主键是否已过时?

时间:2012-02-29 18:48:09

标签: sql-server database-design primary-key

主键提供哪些独特功能?

虽然我把舌头牢牢地贴在脸颊上,但我的问题很严重。在任何火焰开始之前,我不是说在没有约束或参照完整性的情况下构建数据库。但是,据我所知,SQL Server可以取消primary key关键字。

  • 独特的索引涵盖,以及唯一性
  • 基于列的非可空性涵盖PK的非可空性要求
  • PK不必聚集,所以不是它
  • 外键可以并且通常使用唯一索引而不是PK
  • 来实现
  • 甚至MSDN声明创建了一个唯一索引来强制执行PK的唯一性

我同意逻辑上主键关于数据模型的一些意图,但是它呢? [讽刺]哦,我们确实得到了SSMS在设计桌子时显示的那个小钥匙图标! [/讽刺]


修改

从评论中可以看出,我没有像我想的那样清楚地问这个问题。我同意主键从逻辑角度来看很重要

问:

  • 我应该为我的PK选择int还是varchar
  • 必须对PK进行群集,或者如何识别应该群集的内容
  • 如何唯一标识行

我的目的是问“PK提供的哪些功能不能合理使用其他功能?”我不是建议在这里发疯 - 比如使用触发器来强制执行唯一性而不是唯一约束/索引。合理是一个关键词 - 使用唯一索引/约束似乎非常类似于定义PK。

6 个答案:

答案 0 :(得分:10)

完全不同的观点:

SQL是一种由ISO标准定义的语言。该标准具有“强制”功能和“可选的一致性”功能。

如果您使用某种数据操作语言构建DBMS,那么只有在以下情况下您才有权调用您的语言“SQL”:

(a)您已实施标准规定的所有语法(“强制”功能),以及 (b)您已实施的所有语言功能(所有必需的功能,以及您选择使用的“可选”功能),完全暴露标准中定义/描述的行为。

“PRIMARY KEY”语法是一个非常古老的特性,它不一定是那些“强制性”的特征之一。抛弃你的语言意味着你不能再合法地调用你的语言SQL。大型商业供应商很可能不会很快做出这样的举动。

答案 1 :(得分:10)

将每个表的一个密钥指定为“主要”密钥的想法基本上是多余的,过时的,并且在很多方面都非常无益。

这是多余的,因为从逻辑上讲,所有键都可以并且确实提供相同的功能。暂且不考虑任何特定DBMS的限制,从逻辑上讲,“主”键享有与同一表中任何其他键完全相同的特性和功能。因此,将一个密钥指定为“主要”仅与数据库设计者或用户希望的一样重要。区别是任意(这是E.F.Codd使用的词)和纯心理(C.J.Date)。

这个概念已经过时,因为在现代实践中,表格通常具有多个密钥,并且不同的用户和数据使用者对同一条数据具有不同的“首选”或“最重要”标识符。例如:最终用户可以识别并使用表中的一个密钥(通常称为“业务”或“自然”密钥);中间层程序员可能对同一个表中的不同密钥更感兴趣(例如“代理”密钥);另一方面,DBA可能将“聚集”键视为最重要的,或者他可能同样关注具有索引的所有键。因此,首选或最重要的关键取决于观点和预期用途 - 它根本不是一个严格的结构特征。

至少有两个原因,“主键”概念无益。首先,数据库开发工具,DBMS和建模工具的软件供应商遗憾地将各种软件功能附加到指定为“主键”的密钥上。这实际上违背了原始概念。我们不再需要为每个表选择一个对设计者或用户具有一定逻辑意义的键。我们鼓励甚至被迫选择“主要”键来支持X,Y或Z软件中的这个或那个功能,而不考虑其他因素。这是非常令人遗憾的,因为它代表了软件的限制和缺乏灵活性。我们应该可以自由地为每个目的选择一个合适的密钥,而不是仅限于每个表的一个密钥每个目的。

主键无益的最终原因是它们是数据库设计中更重要问题的不必要分心。在教育,数据库设计教科书和日常数据管理实践中,主要关键概念往往具有极大的夸大意义。这通常会损害或实际排除更基本的问题,即所有密钥和所有其他完整性约束对于成功的数据库设计和实现同样重要。

我经常争辩说,“主键”一词应该从数据管理词汇表和数据管理软件中弃用和删除。

答案 2 :(得分:7)

主键是一个逻辑概念。它是定义实体标识的关键:在Widgets表中,每个单独的Widget都由其主键值区分。 PK不是聚集索引(即物理存储属性),也不是唯一约束(即不同的逻辑属性)。虽然主键和聚簇键经常重叠,但这只是一个巧合(PK是一个方便的聚簇键),甚至只是一个疏忽(PK被用作聚簇键,即使给定工作负载存在更好的候选者)。

更改群集密钥是可以在任何时间,在现场,通过操作完成的更改,以更好地满足此存储要求或性能工作负载要求。该应用程序不应该注意到这种变化(在一个理想的世界......)。更改PK是设计更改,需要在对象标识符更改时修改应用程序的数据模型,并且通常会通过数据模式/应用程序代码进行渗透。

顺便说一下,这个话题已经被问到并且已经在这里回答:

详细说明PK和UNIQUE约束之间的区别:即使有几个属性具有唯一约束,因此可以作为PK,只有一个是正确的选择,它们不相等。哪一个完全取决于数据模型,哪一个取决于实体以及每个属性代表什么。 PK对于DBMS并不重要,DBMS真正关心的是集群密钥和唯一性,而不仅仅是PK。 PK适用于您,开发人员和工具集。您不希望每个开发人员使用它的ORM工具指向数据库,以选择不同的唯一键作为实体标识,然后每个开发人员编写一个代码来存储不同的属性 < / em>身份。您希望所有人都选择相同的主键,因为除了唯一之外,它还有其他属性。一个主要的例子是稳定性,PK值在实体的整个生命周期内是稳定的(如果不是,则没有正确选择PK)。

  

PK提供的功能无法合理实施   使用其他功能?

小SSMS图标。说真的,这最终归结为:PK传达了额外的信息,哪些可能的密钥实际上是识别表中实体的密钥。 Path Dependence确实在今天的PK位置中发挥了重要作用,但是如果不是这样的话,那么其他一些构造将会起到完全履行这个传达逻辑模型意图的作用。

答案 3 :(得分:4)

理论上,所有键都是等价的,但出于心理和实际原因,我们选择其中一个作为“主键”。一些注意事项:

  • PK字段自动为NOT NULL。只有当你指定它们时,UNIQUE字段才是非空的(BTW,UNIQUE约束中的NULL通常由不同的DBMS处理不同)。
  • FOREIGN KEY语法默认到父PK。如果要使用父级的UNIQUE约束,则需要明确指定它。
  • Clustering通常基于PK。
  • PK工具通常以视觉上不同的方式显示PK。这可以证明(心理上)我们认为一个关键词比其他关键词“更重要”。

很多这都是传统 - 我们可以轻松拥有使所有关键不仅在理论上而且在实践中等同的惯例和工具,但历史可以成为一股强大的力量,即使在相对年轻的行业比如我们的。

答案 4 :(得分:3)

你指出

  

逻辑上,主键有一点意图

和Aaron Betrand在评论中指出

  

您可以拥有多个唯一约束或唯一索引,但只有一个 应该是您通常期望识别行的方式

我猜Aaron使用像这样的词应该 ,因为他知道即使是外键约束只需要一个独特的约束

From MSDN docs on SQL FOREIGN KEY Constraints

  

FOREIGN KEY约束不必仅链接到另一个表中的PRIMARY KEY约束;它也可以定义为引用另一个表中的UNIQUE约束的列

此外C.J. Date also notes in An introduction to database systems

  

如果候选键组确实包含多个   成员,然后选择哪个是主要的本质上   任意 *

这使我得出结论,除了约定,主键确实没有提供太多。但它是如此重要地集成到我们使用的工具和大多数人的心理模型中,它是不容忽视的。

* C.J。选择主键的日期does explain here并非完全是任意的。例如,易失性主键是个坏主意。

答案 5 :(得分:0)

主键在所有数据库系统中自动编入索引。 (至少在目前为止我所知道的那些。)