我正在学习如何使用键,并打破必须在所有表中的所有行都具有SERIAL
类型ID的习惯。同时,我也在进行多对多关系,因此要求协调关系的表的任一列上的唯一值会妨碍它。
如何定义一个主键,使得任何给定值可以在任何列中重复出现,只要跨所有列的值的组合从来没有完全重复?
我正在学习如何使用键,并打破必须在所有表中的所有行都具有SERIAL
类型ID的习惯。同时,我也在进行多对多关系,因此要求协调关系的表的任一列上的唯一值会妨碍它。
如何定义一个主键,使得任何给定值可以在任何列中重复出现,只要跨所有列的值的组合从来没有完全重复?
以下内容引用自CREATE TABLE Syntax页面:
主键可以是多列索引。但是,您不能在列规范中使用PRIMARY KEY关键字属性创建多列索引。这样做只会将该单个列标记为主键。您需要使用单独的PRIMARY KEY(index_col_name,...)子句。
对于多列主键,可以使用类似以下的语法:
CREATE TABLE
product (
category INT NOT NULL,
id INT NOT NULL,
price DECIMAL,
PRIMARY KEY(category, 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中,自动递增的字段应该是主键中最左边的组成部分。