链接表是否需要无意义的主键字段?

时间:2009-12-03 21:57:20

标签: sql database-design primary-key

我正在研究几个链接表,我开始思考(Danger Will Robinson,Danger)链接表的可能结构是什么,以及他们的专业人士和骗子是什么。

我想出了一些可能的链接表限制:

传统3柱模型

  • id - 自动编号PRIMARY
  • table1fk - 外键
  • table2fk - 外键

在大多数书中,这是经典之作,'努夫说。

索引3列模型

  • id - 自动编号PRIMARY
  • table1fk - 外键INDEX ('table1fk')
  • table2fk - 外键INDEX ('table2fk')

根据我自己的经验,您要查询的字段未在传统模型中编入索引。我发现索引外键字段确实提高了预期的性能。不是一个重大的改变,而是一个很好的优化调整。

复合键2列ADD PRIMARY KEY ('table1fk' , 'table2fk')

  • table1fk - 外键
  • table2fk - 外键

使用这个我使用复合键,以便table1中的记录只能链接到table2上的记录一次。因为密钥是复合的,所以我可以添加记录(1,1),(1,2),(2,2)而不会出现任何重复错误。

复合键2列选项有任何潜在问题吗?这可能会导致索引问题吗?表现受到了打击?有什么东西可以取消这个可能的选择吗?

12 个答案:

答案 0 :(得分:17)

我会使用复合键,而不是额外无意义的键。

我不会使用在我的数据库结构上强制执行此类规则的ORM系统。

答案 1 :(得分:12)

对于真正的链接表,它们通常不作为对象模型中的对象实体存在。因此,从未使用过代理密钥。从集合中移除项目会导致从链接关系中删除项目,其中两个外键都已知(Person.Siblings.Remove(Sibling)Person.RemoveSibling(Sibling),这在数据访问层被适当地翻译为{{1 }})。

正如Mike所提到的,如果它确实成为对象模型中的实际实体,那么它可能值得一个ID。然而,即使添加了诸如关系的有效开始和结束日期等时间因素以及类似的事情,它也并不总是很清楚。例如,集合可能具有在聚合级别关联的生效日期,因此关系本身可能仍然不会成为具有任何公开属性的实体。

我想补充一点,你可能需要在两个外键列上以两种方式索引表。

答案 2 :(得分:6)

如果这是一个真正的多对多连接表,那么转储不必要的id列(除非你的ORM需要一个。在这种情况下,你必须决定你的智力是否会胜过你的实用性)。

但我发现真正的连接表非常罕见。通常不久我就开始想要在该表中放入一些其他数据。因此,我几乎总是从一开始就将这些连接表建模为实体,并在那里粘贴一个id。

答案 3 :(得分:6)

拥有单列pk可以帮助解决灾难恢复问题。因此虽然理论上你是正确的,但你只需要2个外键。实际上,当狗屎击中风扇时,您可能需要单列密钥。我从来没有遇到过被搞砸的情况,因为我有一个列标识符,但是我一直在那些被搞砸的地方,因为我没有。

答案 4 :(得分:3)

复合PK并关闭群集。

答案 5 :(得分:1)

我使用复合键来防止重复输入并让数据库处理异常。使用单个密钥,您可以依赖前端应用程序在添加新记录之前检查数据库是否重复。

答案 6 :(得分:0)

我已经使用了两者,使用第一个模型(使用uid)的唯一好处是你可以将标识符作为数字传输,而在某些情况下,你必须使用复合键进行一些字符串连接。把它运走。

我同意,无论您采用哪种方式,都不会将外键编入索引。

答案 7 :(得分:0)

如果您使用ORM来获取/更改数据,其中一些需要单列主键(感谢Tom H指出这一点)才能正常运行(我相信Subsonic 2.x是这样,不确定3.x)。

在我看来,拥有主键不会影响性能到任何可衡量的程度,所以我通常会使用它。

答案 8 :(得分:0)

我(几乎)总是使用额外的单列主键。这通常使构建用户界面变得更容易,因为当用户选择特定的链接实体时,我可以使用单个整数值进行标识,而不必创建然后解析复合标识符。

答案 9 :(得分:0)

如果你需要在两个方向上遍历连接表,那就是从table1fk 一个table2fk键开始,你可以考虑添加第二个反向的复合索引。

ADD KEY ('table2fk', 'table1fk')

答案 10 :(得分:0)

正确答案是:

  • 主键为('table1fk' , 'table2fk')
  • ('table2fk' , 'table1fk')
  • 上的另一个索引

由于:

  • 您不需要table1fk或table2fk上的索引:优化器将使用PK
  • 您最有可能以“两种”方式使用表格
  • 只需要因为脑卒中ORM而需要添加代理键

答案 11 :(得分:0)

有一种称为识别和非识别关系的东西。通过识别关系,FK是多对多表中PK的一部分。例如,假设我们有表PersonCompany和多对多表Employment。在识别关系中,fk PersonIDCompanyID都是pk的一部分,因此我们无法重复PersonID, CompanyID组合。

TABLE Employment(PersonID int (PK,FK), CompanyID int (PK,FK))

现在,假设我们想要获取就业历史,那么一个人可以离开公司,在其他地方工作,然后再回到同一家公司。这里的关系是非标识的,PersonID, CompanyID的组合现在可以重复,所以表格看起来像:

TABLE Employment(EmploymentID int (PK), PersonID int (FK), CompanyID int (FK), 
                     FromDate datetime, ToDate datetime)