我意识到这里的答案可能是某种形式的“它取决于”;但我仍然想知道一般的经验法则是什么(如果有的话)。
如果我想启用某个类型的“软删除”记录,我可能会添加deleted
列,这样我就可以做这样的事情(提供一个Rails示例,但我不是故意的问题是Rails特定的):
class SomeModel < ActiveRecord::Base
default_scope { where(:deleted => false) }
end
在这种情况下,我认为将deleted
列编入索引会相对便宜,因为只有两个可能的值:true
或false
。
当然,删除记录时可能会有用。所以我可以选择deleted_at
:
class SomeModel < ActiveRecord::Base
default_scope { where(:deleted_at => nil) }
end
我肯定在野外看到过这种事情。我的问题是在这种情况下索引是否实际上要贵得多,因为基本上每条记录都会有deleted_at
*的不同值。我对数据库内部几乎一无所知(有些事情我想在某一天阅读);所以我认识到这可能是一个天真的问题。
我知道这可能也取决于数据库;如果重要的话,我最关心的是PostgreSQL。但我想其他人也想了解MySQL,Oracle等等。
所以?帮助不大?
*当我输入那句话时,我认为我意识到了答案,因为很明显每条记录对id
都有不同的价值,但你不会三思而后行索引那个。那么日期/时间值可能以相同的方式工作?无论如何,我更喜欢那些对这个主题有真正了解的人的回答而不是我的预感:)
答案 0 :(得分:2)
How database index works could be seen here的高视图。
一般在设计索引时,
deleted
字段,或gender
的经典样本,包含两个不同的值:男性或女性。 位图索引的一个优点是可以对其中的一些进行AND运算和OR运算,以便非常有效地回答查询。
Working of indexes in postgresql和some guidance on index strategies可能派上用场。
答案 1 :(得分:1)
指数的大小主要受两件事的影响:
除此之外,还有一些开销通常无法影响(例如,B树本身,对主表存储的引用)。
回答你的问题:是的,二进制索引可能更小更快,但不是因为不同值的数量,而是因为一个二进制字段需要的空间少于日期。
如果您想了解SQL索引,请查看我的网站http://use-the-index-luke.com/
答案 2 :(得分:1)
索引deleted_at值仅在您经常需要识别在特定时间范围内删除的记录时才有用。如果您不需要这种能力 - 例如,如果您只想知道何时删除了通过其他方式识别的记录,那么就不值得索引。
当然,一旦记录被删除,您可能希望它永远不会被再次修改,因此您可以在实践中使用updated_at作为删除时间戳。
如果您想快速识别未删除的记录,那么如果您的RDBMS支持它,则部分索引是合适的。语法因系统而异,但简而言之,您希望仅在索引中包含deleted_at不为null(或is_deleted =&gt; false)的行。