使用复合/复合主键有什么弊端?
使用复合/复合主键有什么弊端?
解决方案
需要更多的特异性。
太过分了,它可能会使插入内容(每个键都必须存在)和文档变得过于复杂,并且如果连接不完整,可能会怀疑我们加入的读物。
有时,它可能表明数据模型有缺陷(复合键真的是由数据描述的吗?)
我不认为这会带来性能上的损失……它真的很容易出错。
在那些对自然复合键具有唯一非空约束的情况下,我建议使用生成的主键。
如果将自然键用作主键,则很可能必须在外键引用中引用这两个值,以确保标识正确的记录。
- 可能导致更多的标准化问题(2NF,"请注意,当1NF表没有复合候选键(候选键由多个属性组成)时,该表将自动位于2NF中")
- 更多不必要的数据重复。如果复合键由3列组成,则需要在每个表中创建相同的3列,并将其用作外键。
- 通常在代理键的帮助下是可以避免的(了解其优缺点)
- 我可以想象一个组合键的好方案-在一个代表N:N关系的表中,例如Student-Classes,中间表中的键将是(StudentID,ClassID)。但是,如果我们需要存储有关每对的更多信息(例如班上学生的所有成绩的历史记录),则可能会引入一个替代键。
- 当我们在图表上查看时,其可读性较差
- 在查询联接上使用它时,可读性较差
- 在foregein密钥上使用它时,必须添加一个关于所有属性的检查约束,该约束必须为null或者不为null(如果仅一个null为空,则不选中该密钥)
- 通常用作外键时需要更多存储空间
- 某些工具无法管理组合键
拥有复合键本身没有什么问题,但是理想情况下,主键应尽可能小(就所需的字节数而言)。如果主键很长,那么这将导致非聚集索引膨胀。
请记住,主键中列的顺序很重要。第一列应尽可能有选择性,即尽可能"独特"。可以搜索第一列上的搜索,但是仅扫描第二列上的搜索将必须进行扫描,除非第二列上也没有非聚集索引。
我认为这是合成键辩论的一种特殊形式(无论使用有意义的键还是任意的合成主键)。由于多种原因,我几乎完全落入了这场辩论的综合重点。这些是一些更相关的:
- 我们必须在最新的外键的末尾保留从属子表。如果更改一个主键字段之一的值(可能会发生-见下文),则我们必须以某种方式更改所有相关表,其中它们的PK值包括这些字段。这有点棘手,因为更改键值将使FK与子表的关系无效,因此我们(取决于平台上可用的约束验证选项)可能不得不采取一些技巧,例如将记录复制到新记录并删除旧记录。
- 在较深的架构上,键可能会变得很宽-我曾经看过8列。
- 主键值的更改在从系统加载的ETL流程中难以识别。我曾经看到的示例是从保险承保系统中提取的MIS应用程序。在某些情况下,客户会重复使用策略条目,从而更改策略标识符。这是表主键的一部分。发生这种情况时,仓库负载不会知道旧值是什么,因此无法将新数据与其匹配。开发人员必须搜索审计日志以识别更改的值。
当记录的PK值更改时,与非合成主键有关的大多数问题都与问题有关。非综合值最有用的应用是打算使用数据库模式的地方,例如M.I.S.报表编写者直接使用表格的应用程序。在这种情况下,为方便起见,可以合理地将具有固定域的短值(例如货币代码或者日期)直接放在表格上。
使用复合主键的主要缺点是,我们会将典型的ORM代码生成器混为一谈。
以具有两个候选键的表为例:一个简单键(单列)和一个复合键(多列)。在这种情况下,问题似乎是:"如果我选择将一个键提升为"主键"并且选择了复合键,那么我会遭受什么不利影响?"
首先,考虑一下我们是否真的需要提升密钥:" SQL中`PRIMARY KEY'的存在似乎是某种历史性的事故。根据作者Chris Date所说,SQL的最早版本没有任何关键约束和" PRIMARY KEY"直到后来才被添加到SQL标准中。该标准的设计者显然是从发明该概念的EFCodd那里获得的,尽管当时Codd的原始概念已经被放弃了(Codd最初提出外键只能将一个键引用为主键,但是这个想法被人们遗忘和忽略,因为它被广泛认为是毫无意义的限制。" [来源:David Portas的Blog:主键失效了吗?
其次,我们将采用什么标准来选择表中的哪个键应为"主键"?
在SQL中,键" PRIMARY KEY"的选择是任意的,且取决于产品。在ACE / Jet(又名MS Access)中,两个主要且经常相互竞争的因素是,我们是否要使用" PRIMARY KEY"来支持磁盘上的群集,还是希望包含该键的列在" Relationships"图片中显示为粗体?在MS Access用户界面中;我认为索引策略胜过漂亮的想法是少数派:)在SQL Server中,我们可以独立于PRIMARY KEY
来指定聚簇索引,并且似乎没有提供特定于产品的优势。唯一剩下的优点似乎是这样的事实:在SQL DDL中创建外键时,我们可以忽略" PRIMARY KEY"的列,这是SQL-92标准的行为,对我来说似乎没什么大不了的(也许他们添加到标准中的另一件事是因为它是SQL产品中已经广泛使用的功能?)因此,这并不是寻找缺点的情况,而是我们应该查看SQL产品有什么优势(如果有)给出PRIMARY KEY
。换句话说,选择错误密钥的唯一缺点是我们可能会错过给定的优势。
第三,我们是否在暗示使用人工/合成/代理键在物理模型中实现逻辑模型中的候选键,因为我们担心如果在外键和表联接中使用自然键会导致性能下降?这是一个完全不同的问题,在很大程度上取决于我们对SQL自然键问题的"宗教态度"。