简体   繁体   English

为什么不允许表中有两个主键?

[英]Why two primary keys in a table is not allowed?

I want to understand the reasoning behind why two primary keys are not allowed in same table by grammar of MySql. 我想了解MySql语法为什么不允许在同一表中使用两个主键的原因。 I understand composite key and this is not related to that. 我了解复合键,与此无关。

I could not understand why two separate primary key in same table is not allowed. 我不明白为什么不允许在同一表中使用两个单独的主键。 But we can have one column as primary key and other column as unique and not null. 但是我们可以将一列作为主键,将另一列作为唯一键而不是null。 Which practically acts as having two different primary keys as we can distinctly identify a row using any of these keys. 实际上,它具有两个不同的主键,因为我们可以使用这些键中的任何一个来清楚地标识行。 Why the first one is not allowed but the later is? 为什么第一个不允许,但第二个不允许?

I was trying to figure out the logic but stumbled upon Rule 2 of Codd's 12 rules which says 我试图弄清楚逻辑,但偶然发现了科德12条规则中的规则2,

Each and every datum (atomic value) in a relational data base is guaranteed to be logically accessible by resorting to a combination of table name, primary key value and column name. 通过使用表名,主键值和列名的组合,可以确保逻辑上可以访问关系数据库中的每个数据(原子值)。

Does combination of table name, primary key value and column should be unique for a single datum value or can we have multiple combinations which guarantees access? 表名称,主键值和列的组合对于单个基准值是否应该是唯一的,或者我们可以有多种组合来保证访问? Why or why not? 为什么或者为什么不?

Edit: Since the question was identified as possible duplicate, I will explain below how it is different Other similar question was 编辑:由于该问题被确定为可能的重复,我将在下面解释它的不同之处其他类似的问题是

Can I have multiple primary keys in a single table? 我可以在一个表中有多个主键吗?

The ans is NO . 答案是

My question is why ? 我的问题是为什么 What is the reasoning? 这是什么原因?

What is that Codd intends to say by rule no 2? 根据第2条规则,科德打算说什么?

What problems would have occurred if multiple separate primary keys were allowed? 如果允许多个单独的主键会发生什么问题?

You can have as many UNIQUE KEY constraints as your database system allows, and many relational purists now see it as a mistake to elevate one of these keys and anoint it as PRIMARY. 你可以有许多独特KEY约束作为数据库系统允许,和许多关系较真现在看到它作为一个错误来提升这些关键之一 ,并膏抹为PRIMARY。

Logically, both unique key constraints and primary keys fulfil the same purposes - defining a subset of columns by which rows may be uniquely identified. 从逻辑上讲,唯一键约束和主键都实现相同的目的-定义列的子集,通过该列子可以唯一地标识行。 They also should be eligible as targets for foreign key constraints. 它们还应该有资格作为外键约束的目标。

Certain defaults (such as nullability) are automatically applied by primary key constraints but there's no reason you cannot apply the same constraints manually to columns included in unique key constraints. 某些默认设置(例如可空性)由主键约束自动应用,但是没有理由不能将相同的约束手动应用于唯一键约束中包含的列。

'Primary key' can be traced back to Ted Codd , inventor of the relational model on which SQL is loosely based. “主键”可以追溯到关系模型的发明者Ted Codd ,后者是基于SQL的松散基础。 Codd clearly realised that when a relation is stored in a DBMS as a variable (relvar, r-table, table, whatever) it could have multiple candidate keys that should be enforced. Codd清楚地意识到,当关系作为变量(relvar,r-table,table等)存储在DBMS中时,它可能具有多个应强制使用的候选键。 He originally thought that nominating one or more of the keys as 'primary' might be beneficial. 他最初认为提名一个或多个键为“主键”可能是有益的。 Since then (late 1960s!) RM thinking has moved on and the idea of a 'primary' key is no longer considered potentially beneficial. 从那时起(1960年代末!),RM的思维不断发展,“主键”的想法不再被认为具有潜在的益处。 A similar thing can be said of nulls: Codd went on to propose two types of null ie four valued logic. 关于空值,可以说类似的话:Codd继续提出两种类型的空值,即四值逻辑。 What can I say? 我能说什么 The man was a genius but not infallible! 这个人是个天才,但并非万无一失!

Sadly, many of the early RM thinking made it into the early SQL implementations and later enshrined in the SQL standards. 令人遗憾的是,许多早期的RM思想使它融入了早期的SQL实现中,并随后被纳入SQL标准中。 And because of the "shackles of compatibility", they will never be removed from the SQL standards. 并且由于“兼容性问题”,它们将永远不会从SQL标准中删除。 But these things were not properly implemented in SQL. 但是这些事情没有在SQL中正确实现。 For example, Codd didn't specify a relvar should be restricted to one primary key but on implementation in SQL one per table is now the rule. 例如,Codd没有指定relvar应该限制为一个主键,但是在SQL中实现时,现在每个表一个规则。 Why? 为什么? Misunderstanding of Codd's original paper by early SQL implementers? 早期的SQL实现者对Codd的原始论文有误解吗? Canny explicit design by relational theorists? 关系理论家的巧妙设计吗? I assume cock-up over conspiracy! 我认为是阴谋大忌!

The differences between a PK and an equivalent NOT NULL UNIQUE constraint are minor and not terribly useful. PK和等效的NOT NULL UNIQUE约束之间的差异很小,并且不是非常有用。 For example, when specifying a PK in SQL, you must specify the referenced table but you can omit the referencing columns. 例如,在SQL中指定PK时,必须指定被引用的表,但是可以省略引用列。 When specifying columns, they must be "equal to the set of column names in the unique columns of a unique constraint of the referenced table" (ie either the PK or any NOT NULL UNIQUE constraint). 指定列时,它们必须“等于引用表的唯一约束的唯一列中的列名集”(即PK或任何NOT NULL UNIQUE约束)。 When omitting columns from the definition, then the referenced table's PK is assumed. 当从定义中删除列时,则假定引用表的PK。 If a table were allowed to have more than one PK then this functionality really wouldn't work. 如果一个表被允许具有多个PK,那么此功能实际上将不起作用。 As I say, not a big deal but maybe important to some users. 正如我所说,这并不重要,但对于某些用户而言可能很重要。

A primary key has three properties: 主键具有三个属性:

  • The combination of values is unique. 值的组合是唯一的。
  • Each value in the key is NOT NULL . 键中的每个值NOT NULLNOT NULL
  • There is only one primary key per table. 每个表只有一个主键。

A table can have as may key or key combinations that meeting the first two conditions. 一个表可以具有满足前两个条件的键或键组合。 You are asking why the third definitions is needed. 您在问为什么需要第三个定义。

It is a matter of convenience for defining relational logic that each table has a "named" method of accessing a particular row. 为了方便定义关系逻辑,每个表都具有访问特定行的“命名”方法。 For instance, this gives guidance on how best to define foreign key relationships (use the primary key). 例如,这为如何最好地定义外键关系(使用主键)提供了指导。 It is simply the definition. 这只是定义。

Some databases uses the primary key for clustering the data -- that is, sorting the rows on the data pages. 某些数据库使用主键对数据进行聚类,即对数据页上的行进行排序。 Given that the data can only be sorted one way, this offers a practical reason why. 鉴于只能以一种方式对数据进行排序,因此提供了一个实际的理由。

From a normalization perspective 从规范化的角度

There's a lot of computer science behind database algorithms, and like any science has to make assumptions, and one of them is that data are stored in a form that is normalized . 数据库算法背后有很多计算机科学,就像任何科学都必须做出假设一样,其中之一是数据以规范化的形式存储。 Everything in the row must depend on the key (1st normal form), the whole key (2nd normal form), and nothing but the key (3rd normal form). 该行中的所有内容都必须取决于键(第一标准格式), 整个键(第二标准格式),并且取决于键(第三标准格式)。 When you stray away from this, you will get less predictable and usually poor performance. 当您偏离这一点时,您将获得较少的可预测性,并且通常性能较差。

A row can have any number of candidate keys , each of which could satisfy the criteria for being a primary key. 行可以具有任意数量的候选键 ,每个候选键都可以满足成为主键的条件。 And I suppose you could call the others "secondary" or "tertiary keys." 我想您可以将其他人称为“第二把钥匙”或“第三把钥匙”。 Nobody does that, really. 真的没有人这样做。 If another value is needed, eg a natural key , it is typically set up as an attribute, not a key. 如果需要另一个值,例如自然键 ,通常将其设置为属性,而不是键。

That being said, you could take any two columns and call them a compound key , and also declare that key the primary key. 话虽如此,您可以将任意两列称为复合键 ,也可以将该键声明为主键。 That way, there are indeed two columns participating in the primary key relationship. 这样,确实有两列参与主键关系。 But that leads to problems in performance. 但这会导致性能问题。

From a performance perspective 从性能角度看

One key is necessary and sufficient to achieve a normalized schema. 一个密钥对于实现规范化架构是必要且足够的。 More than one key could be set up, but they would contain redundant data-- if you know one, you know the other, if you know who to ask-- and be in violation of 2nd normal form. 可以设置多个密​​钥,但是它们将包含冗余数据(如果您知道一个,就知道另一个,如果您知道向谁询问),并且违反了第二种标准格式。 It also means each row would take up more space that it really needs to. 这也意味着每一行将占用它真正需要的更多空间。 A bigger row means fewer rows per page meaning poorer performance, especially considering that the primary key is used as a clustering key and is contained in the leaf pages of all in indexes throughout the database. 较大的行意味着每页较少的行,这意味着性能较差,特别是考虑到主键用作集群键,并且包含在整个数据库中所有索引的叶页中。 Why spend the bytes on something you already know? 为什么将字节花在您已经知道的事情上?

Typical practice 典型做法

Store any additional "keys" as attributes in the row where the entity is defined. 将任何其他“键”作为属性存储在定义实体的行中。 For example, you could store social security number as an attribute of the Employee table where EmployeeID is the primary (and possibly surrogate) key. 例如,您可以将社会保险号存储为Employee表的属性,其中EmployeeID是主键(并且可能是代理键)。 Whenever you need it, join to the Employee table. 无论何时需要,都可以连接到Employee表。 (And by the way you might want to tighten the column level permissions of the SSN.) Don't store it in multiple places; (顺便说一句,您可能想加强SSN的列级权限。)不要将其存储在多个位置; there's no need to. 没必要。

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

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