假设我有一个要根据布尔属性(例如,“标记”属性)过滤的数据库表。只是向表中添加“标记”属性,还是创建一个具有基表外键的新表更好?优缺点都有什么?
4 回答
如果这就是您所需要的1,那么只需添加简单字段。
但是,你必须小心你如何索引它。除非值严重倾斜2,否则您最终会得到一个具有可怕的选择性和聚集因子3的索引,并且实际上最好进行全表扫描4。
如果您将标志与其他字段一起过滤,请创建一个复合索引,这样就有更好的机会获得体面的选择性。
1即您不需要以某种方式“描述”或“增强”两个可能的布尔值中的每一个的附加数据。
2一个值是极少数(包含的行数false
远小于包含 的行数true
,反之亦然),而您恰好只过滤该值。
3该链接适用于 Oracle,但一般原则适用于所有 DBMS。
4即使存在索引,一个像样的 DBMS 也会自动为您做这件事。一个假设的“愚蠢”的 DBMS 只会盲目地使用索引并且执行得比全表扫描还要差。
如果这个标志本身有属性或者它是可重用的,最好将它创建为另一个表。但是,如果它只是将一行标记为真/假,只需创建一个布尔列(并节省时间和工作量)
只需向表中添加列,它会更好更简单.. 然后创建一个位图索引,如果您在 WHERE 中使用此列,这将加快您的查询速度
这取决于。当值与表/关系并不真正相关时,我自己更喜欢添加一个新表。
一个很好的例子是当您有一个代表订单的表格并且您想要跟踪已打印的订单时。我会在订单中添加一个名为printed_orders 的新表,其中包含一个外键。
create table printed_orders (
order_id int primary key references order(order_id)
);
它是否被打印并不是订单的一部分,而是系统/业务规则的一部分。