当前位置:  开发笔记 > 数据库 > 正文

我可以在一个表中拥有多个主键吗?

如何解决《我可以在一个表中拥有多个主键吗?》经验,为你挑选了7个好方法。

我可以在一个表中拥有多个主键吗?



1> Adam Pierce..:

表可以有一个复合主键,它是由两列或更多列组成的主键.例如:

CREATE TABLE userdata (
  userid INT,
  userdataid INT,
  info char(200),
  primary key (userid, userdataid)
);

更新: 这是一个链接,其中包含复合主键的更详细说明.


Adam,链接+1.绝对帮了我很多.谢谢.

2> RB...:

您只能拥有一个主键,但主键中可以有多个列.

您还可以在表上使用唯一索引,这将有点像主键,因为它们将强制执行唯一值,并将加快查询这些值.



3> Walter Mitty..:

一个表可以有多个候选键.每个候选键都是一列或一组列,这些列是UNIQUE,一起使用,也是NOT NULL.因此,为任何候选键的所有列指定值足以确定有一行符合条件,或者根本没有行.

候选键是关系数据模型中的基本概念.

如果一个表中存在多个密钥,则通常的做法是将一个候选密钥指定为主密钥.通常的做法是使表的任何外键引用主键,而不是任何其他候选键.

我推荐这些实践,但关系模型中没有任何内容需要在候选键中选择主键.


同意.逻辑模型中的所有键都相等(没有'主').物理实现中的哪个键获得PRIMARY KEY指定的选择是仲裁和供应商/产品相关.
我会说它依赖于数据库设计师.
克里斯,我说关系模型不需要主键.我没有说一些工具是否需要它们.但我明白你的观点.

4> Eye..:

这是主要问题和@ Kalmi问题的答案

拥有多个自动生成列有什么意义?

下面的代码具有复合主键.其中一列是自动递增的.这只适用于MyISAM.InnoDB将生成错误" ERROR 1075(42000):表定义不正确;只能有一个自动列,必须将其定义为键 ".

DROP TABLE IF EXISTS `test`.`animals`;
CREATE TABLE  `test`.`animals` (
  `grp` char(30) NOT NULL,
  `id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `name` char(30) NOT NULL,
  PRIMARY KEY (`grp`,`id`)
) ENGINE=MyISAM;

INSERT INTO animals (grp,name) VALUES
    ('mammal','dog'),('mammal','cat'),
    ('bird','penguin'),('fish','lax'),('mammal','whale'),
    ('bird','ostrich');

SELECT * FROM animals ORDER BY grp,id;

Which returns:

+--------+----+---------+
| grp    | id | name    |
+--------+----+---------+
| fish   |  1 | lax     |
| mammal |  1 | dog     |
| mammal |  2 | cat     |
| mammal |  3 | whale   |
| bird   |  1 | penguin |
| bird   |  2 | ostrich |
+--------+----+---------+



5> Yet Another ..:

如其他人所指出的,可以具有多列主键.但是应该注意的是,如果你有一些不是由密钥引入的功能依赖,你应该考虑规范你的关系.

例:

Person(id, name, email, street, zip_code, area)

可能存在功能依赖性id -> name,email, street, zip_code and area 但通常a zip_code与a相关联,area因此之间存在内部功能依赖性zip_code -> area.

因此,可以考虑将其拆分为另一个表:

Person(id, name, email, street, zip_code)
Area(zip_code, name)

这样它与第三种正常形式一致.



6> Pieter Geerk..:

主键是非常不幸的符号,因为"初级"的内涵和与逻辑模型有关的潜意识联想.因此我避免使用它.相反,我指的是物理模型的代理键和逻辑模型的自然键.

重要的是,每个实体的逻辑模型至少具有一组"业务属性",其包括实体的密钥.Boyce,Codd,Date等在关系模型中将这些称为候选键.然后,当我们为这些实体构建表时,它们的候选键在这些表中成为自然键.只有通过那些自然键,用户才能唯一地识别表中的行; 因为代理键应始终对用户隐藏.这是因为代理键没有商业意义.

然而,在没有代理键的情况下,我们的表的物理模型在许多情况下效率低下.回想一下,非聚集索引的非覆盖列只能通过密钥查找(通常)找到聚簇索引(忽略作为堆积实现的表).当我们的可用自然密钥很宽时,这(1)扩大了我们的非聚簇叶节点的宽度,增加了存储要求,并且对非聚集索引的搜索和扫描进行了读取访问; (2)减少聚集索引的扇出,增加索引高度和索引大小,再次增加聚簇索引的读取和存储要求; (3)增加了我们的聚簇索引的缓存要求.从缓存中追逐其他索引和数据.

这是一个小的代理键,被指定为RDBMS作为"主键"证明是有益的.当设置为聚类键时,为了用于从非聚集索引和相关表中的外键查找中查找聚簇索引的键,所有这些缺点都消失了.我们的聚簇索引扇出再次增加以减少聚簇索引的高度和大小,减少聚簇索引的缓存负载,减少通过任何机制访问数据时的读取(无论是索引扫描,索引搜索,非聚簇键查找还是外键查找)并降低表的聚簇索引和非聚簇索引的存储要求.

请注意,仅当代理键很小且聚类键时才会发生这些好处.如果GUID用作聚类键,则情况通常比使用最小可用自然键时更糟.如果表被组织为堆,则8字节(堆)RowID将用于键查找,这比16字节GUID更好但性能低于4字节整数.

如果由于业务限制必须使用GUID,那么搜索更好的群集密钥是值得的.例如,如果一个小的站点标识符和4字节的"站点序列号"是可行的,那么该设计可能比作为代理键的GUID具有更好的性能.

如果堆的结果(可能是散列连接)使得该首选存储成为更广泛的集群密钥的成本,则需要将其平衡到权衡分析中.

考虑这个例子::

ALTER TABLE Persons
ADD CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)

其中元组" (P_Id,LastName) "需要唯一性约束,并且可能是冗长的Unicode LastName加上4字节整数,因此需要(1)声明性地将此约束强制实施为" ADD CONSTRAINT pk_PersonID UNIQUE NONCLUSTERED(P_Id) ,LastName) "和(2)分别声明一个小的代理键作为聚簇索引的" 主键 ".值得注意的是,Anita可能只希望将LastName添加到此约束中以使其成为覆盖字段,这在聚簇索引中是不必要的,因为所有字段都被它覆盖.

SQL Server将主键指定为非聚簇的能力是一个不幸的历史情况,因为"首选自然或候选键"(来自逻辑模型)与"物理存储中的查找键"的含义相混淆模型.我的理解是,最初SYBASE SQL Server总是使用4字节的RowID,无论是作为堆还是聚簇索引,作为物理模型中的"存储中的查找键".


你能把它翻译成英文吗?

7> Manohar Redd..:

(已经研究了很多)

只能有1个主键。
但是您可以有多个备用键。

简单来说就是这种情况:

可能有多个候选键(最少列,唯一标识行)在表中。

专门选择了一个候选密钥,称为主密钥

所有其他候选键称为备用键

主键和备用键都可以是复合键(2列或更多列)

来源:
https : //en.wikipedia.org/wiki/Superkey
https://en.wikipedia.org/wiki/Candidate_key
https://en.wikipedia.org/wiki/Primary_key
https://en.wikipedia.org / wiki / Compound_key

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有