【发布时间】:2009-08-06 02:36:17
【问题描述】:
在一般的一对多(父对子)关系中,(a) 将 parent_id 放入子表和 (b) 使用只有 parent_id、child_id 的数据透视表之间是否存在显着的效率差异?
注意:如有必要,假设 Oracle,否则使用通用 RDBMS 回答。
【问题讨论】:
在一般的一对多(父对子)关系中,(a) 将 parent_id 放入子表和 (b) 使用只有 parent_id、child_id 的数据透视表之间是否存在显着的效率差异?
注意:如有必要,假设 Oracle,否则使用通用 RDBMS 回答。
【问题讨论】:
如果PIVOT 表是指many-to-many 链接表,那么不,它只会影响性能。
您应该在子表中保留parent_id。
many-to-many 链接表需要额外的JOIN,因此效率较低。
比较以下查询:
SELECT *
FROM child_table c
JOIN child_to_parent cp
ON cp.child = c.id
JOIN parent p
ON p.id = cp.parent
WHERE c.property = 'some_property'
还有这个:
SELECT *
FROM child_table c
JOIN parent p
ON p.id = c.parent
WHERE c.property = 'some_property'
后一种是JOIN更短更高效。
该规则唯一可能的例外是您经常运行这些查询:
SELECT *
FROM child_table c
JOIN parent_table p
ON p.id = c.parent
WHERE c.id IN (id1, id2, ...)
,我。 e.您事先知道子行的id。
如果您对 child_table 使用自然键,这可能会很有用。
在这种情况下是的,child_to_parent 链接表会更有效,因为您可以将其替换为以下查询:
SELECT *
FROM child_to_parent cp
JOIN parent_table p
ON p.id = cp.parent
WHERE cp.child IN (id1, id2, ...)
而child_to_parent 的大小将始终小于或等于child_table,因此效率更高。
但是,在Oracle 中,您可以在child_table (id, parent_id) 上创建复合索引,从而获得相同的结果。
由于Oracle 不索引NULL,此索引将与您的child_to_parent 表一样,但没有表本身和隐含的维护开销。
在其他系统(索引NULL's)中,索引的效率可能低于专用表,尤其是当您有很多NULL 父表时。
【讨论】: