对于1-多个关系,数据透视表与Parent_ID

时间:2009-08-05 18:07:17

标签: database database-design

在一般的一对多(父对子)关系中,(a)将parent_id放在子表中和(b)使用只有parent_id,child_id的数据透视表之间是否存在显着的效率差异?

注意:如有必要,请假设Oracle,否则使用常规RDBMS进行回答。

1 个答案:

答案 0 :(得分:2)

如果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, ...)

,我。即你事先知道子行的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)中,索引的效率可能低于专用表,特别是如果您有很多NULL个父级。