我正在尝试学习如何使用密钥并打破必须为所有表中的所有行设置SERIAL
类型ID的习惯。与此同时,我也在做多对多关系,因此要求协调关系的表中任一列的唯一值会妨碍这种关系。
如何在表上定义主键,以便任何给定的值都可以在任何列中重复,只要所有列中的值组合永远不会完全重复?
答案 0 :(得分:46)
引自CREATE TABLE Syntax页面:
PRIMARY KEY可以是多列 指数。但是,你无法创建一个 多列索引使用 列中的PRIMARY KEY键属性 规格。这样做只会标记 那个单列是主要的。您 必须使用单独的PRIMARY KEY(index_col_name,...)子句。
这样的东西可以用于多列主键:
CREATE TABLE
product (
category INT NOT NULL,
id INT NOT NULL,
price DECIMAL,
PRIMARY KEY(category, id)
);
答案 1 :(得分:18)
主键是一个域概念,它在相似实体中唯一地(必然且充分地)标识您的实体。只有当密钥的一部分引用另一个域实体的特定实例时,复合(多列)主键才有意义。
假设您拥有个人藏书。只要你一个人,就可以计算它们并为每个数字分配一个数字。该数字是图书馆域名的主键。
现在您想要将您的图书馆与您的图书馆合并,但仍然可以区分图书所属的图书馆。域现在更宽,主键现在是(owner,book_id)。
因此,制作每个主键复合不应该是您的策略,而是应该在需要时使用它。
现在有关MySQL的一些事实。如果你定义一个复合主键并希望RDBSM为你自动增加id,你应该知道MyISAM和InnoDB行为之间的区别。
假设我们想要一个包含两个字段的表:parent_id,child_id。我们希望child_id能够自动增加。
MyISAM将在具有相同parent_id的记录中唯一自动增量,InnoDB将在整个表中自动增量。
在MyISAM中,您应该将主键定义为(parent_id,child_id),并将InnoDB定义为(child_id,parent_id),因为自动增量字段应该是InnoDB中主键中最左侧的组成部分。
答案 2 :(得分:0)
主键是行的唯一值。包含价格是一种可能改变的价值是没有意义的。想象一下,如果你必须改变大范围的价格,那么所有这些主键值都会改变。真是个烂摊子!