繁体   English   中英

我可以在一个表的复合主键中包含太多列吗

[英]Can I have too many columns in my composite primary key on one table

我有一个使用2个外键字段和一个日期字段的表。 表格使用3个或更多字段作为主键是否很常见? 这样做有什么缺点吗?

-

我的3个表是雇员,培训和emp_training。 员工表保存员工数据。 培训桌举行不同的培训课程。 我将emp_training表设计为字段EmployeeID(FK),TrainingID(FK),OnDate。

员工可以执行多个培训课程,并且可以多次执行同一培训课程。 但是他们不能在同一天多次参加同一培训课程。 哪个更好地实现:

选项A-将所有3个字段设为主键

选项B-添加一个自动编号PK字段,并使用查询查找任何可能的重复项。

在使用2个字段作为主键之前,我已经创建了很多表,但是从来没有使用3个,因此我很好奇继续执行选项A是否有任何不利之处

是的,如果可以通过二级索引采用更好的策略来实现唯一性,那么为复合主键(PK)选择太多列的策略就很糟糕。

请记住,PK是特殊的。 您的数据只有1种物理/群集排序。 通过插入和更新对数据进行的更改(以及现有的改组)具有开销,如果在二级索引中进行维护则不会存在开销。

因此,以下内容可能没有那么微不足道的差异:

  1. 具有5个复合列的主键

  1. 具有1或2列的主键以及
    • 如果仔细考虑,二级索引将保持唯一性

前者要求在数据页之间移动数据以维护聚簇索引(PK)。 这可能表明为什么人们经常看到:

(
id int auto_increment primary key,
...
)

在表设计中。

具有索引宽度的性能:

上面1.中的PK宽度很窄。 2.的宽度可以很宽。 传播到子关系的更宽的密钥将降低性能和并发性。

FK组合物的情况:

不使用单列索引(最好是PK)就无法实现外键组合的特殊情况,这在我最近的《 答案》中可以看到。

值得一提的是,在SQL Server中,默认情况下PK是唯一的集群密钥 ,但是您也可以创建非集群PK。

您可以定义一个新的聚集索引,而不是PK “主键”实际上只是一个名称...

最重要的问题是:哪些列参与了集群键,并且(这是最重要的问题 ):它们是否具有隐式排序? 并且(同样非常重要 ):是否有许多更新操作会更改参与列的内容?

您必须知道,集群键定义了硬盘上的物理顺序。 换句话说: 集群键是表本身 您可以想到包含所有列的索引。 如果您的前导列( 最坏的情况 )是GUID,则表中的每个插入都不会按顺序进行 这导致99.99%的碎片。

如果聚集索引绑定到插入时间或运行编号( 最好的情况 ),它将永远不会碎片化!

更糟糕的是:如果有一个集群键(无论是否称为PK),它将用作其他索引的查找键。

因此:在许多情况下,最好使用一个运行编号作为聚簇键和一个非聚簇的多列索引,该索引的重建速度要比聚簇的索引快得多。

所有索引都将从中获利!

我给你的建议:

  • 选项C:以PK开头的运行编号,并另外具有唯一的多列密钥以确保数据完整性。 无需在这里使用自己的逻辑...

我认为用组合的PK创建表没有任何问题,此类表在较大的db中是必需的。用2FK创建其OnDate字段构成PK的表并不是真正的问题。 两种方法均可用。 祝好运!

如果您在多个列上分配主键,它将是复合主键。 例如,

CREATE TABLE employee(
  training VARCHAR(10),
  emp_training VARCHAR (20),
  OnDate INTEGER,
  PRIMARY KEY (training, emp_training, OnDate)
)

在training,emp_training,OnDate中将有唯一的记录,并且不能在一起为null。

如前所述,您可以有一个包含多个列的单个主键。

如果问题是如何使列的主键分开,那是不可能的。 但是,您可以创建1个主键并添加两个唯一键

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM