【发布时间】:2011-02-08 05:22:56
【问题描述】:
我正在尝试学习如何使用键,并打破我所有表中的所有行都必须使用SERIAL 类型 ID 的习惯。同时,我也在处理多对多关系,因此在协调关系的表的任一列上要求唯一值会阻碍这一点。
如何在表上定义一个主键,以便任何给定值可以在任何列中重复,只要所有列中的值组合从不完全重复?
【问题讨论】:
-
不能与 3 年后发布的内容重复。
标签: mysql key primary-key
我正在尝试学习如何使用键,并打破我所有表中的所有行都必须使用SERIAL 类型 ID 的习惯。同时,我也在处理多对多关系,因此在协调关系的表的任一列上要求唯一值会阻碍这一点。
如何在表上定义一个主键,以便任何给定值可以在任何列中重复,只要所有列中的值组合从不完全重复?
【问题讨论】:
标签: mysql key primary-key
引自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)
);
【讨论】:
主键是一个域概念,可在相似实体中唯一(必要且充分地)标识您的实体。只有当键的一部分引用另一个域实体的特定实例时,复合(多列)主键才有意义。
假设您有个人收藏的书籍。只要你一个人,你就可以数数并给每个人分配一个数字。该数字是您图书馆域的主键。
现在您想将您的图书馆与您邻居的图书馆合并,但仍然能够区分一本书属于谁。域现在更宽了,主键现在是 (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 主键中最左边的组成部分。
【讨论】:
主键是行的唯一值。包含价格是没有意义的,价格可能会发生变化。想象一下,如果您必须更改大范围的价格,那么所有这些主键值都会更改。那将是多么混乱!
【讨论】: