主键列的外键约束 - 问题?

时间:2010-06-03 15:34:45

标签: sql sql-server postgresql

从性能/索引/数据管理的角度来看,使用子项上的主键作为外键与子项上的纯代理主键创建表之间的一对一关系有哪些优缺点?第一种方法似乎可以减少冗余,并且可以隐式地一对一地约束,而第二种方法似乎受到DBA的青睐,即使它创建了第二个索引:

create table parent (
     id integer primary key, 
     data varchar(50)
)

create table child (
     id integer primary key references parent(id), 
     data varchar(50)
)

纯代理键:

create table parent (
     id integer primary key, 
     data varchar(50)
)

create table child (
     id integer primary key,
     parent_id integer unique references parent(id), 
     data varchar(50)
)

这里感兴趣的平台是Postgresql,Microsoft SQL Server。

编辑:

所以这是来自实际DBA的基本思想。主要关注的是子表上的索引碎片。假设主键为1-1000000的记录插入到父表中,子表中没有任何内容。稍后,临时操作开始使用与父表中的行相对应的行(但是以随机顺序)填充子表。令人担忧的是,这将导致插入页面拆分,导致索引碎片,并导致删除“瑞士奶酪”效果。我承认这些不是我非常熟悉的术语,当谷歌搜索它们时,点击似乎与Microsoft SQL服务器相关。这些特定于MS的问题(即PG的分析是否可以缓解PG上的问题)?如果是这样,那么这是使用像Postgresql这样的数据库的另一个原因。

2 个答案:

答案 0 :(得分:5)

如果是严格的1-1关系,我认为没有理由不使用第一个选项。

第二个选项提供了一些灵活性,以便稍后使其成为一个多关系,这可能是DBA可能偏爱该选项的原因。

答案 1 :(得分:1)

首先,如果你有一个1:1的关系,那么表的主键也表示另一个表的外键没有问题,事实上我会建议这是首选的方法。

其次,对于任何1:1关系,第一个问题显然应该是是否需要关系,因为通常只需将子表中的列包含在主表中即可。也就是说,有时候1:1的关系显然是有道理的。