【问题标题】:Multi-Column Primary Key in MySQL 5MySQL 5 中的多列主键
【发布时间】:2011-02-08 05:22:56
【问题描述】:

我正在尝试学习如何使用键,并打破我所有表中的所有行都必须使用SERIAL 类型 ID 的习惯。同时,我也在处理多对多关系,因此在协调关系的表的任一列上要求唯一值会阻碍这一点。

如何在表上定义一个主键,以便任何给定值可以在任何列中重复,只要所有列中的值组合从不完全重复?

【问题讨论】:

标签: mysql key primary-key


【解决方案1】:

引自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)
    );

来自13.1.20.6 FOREIGN KEY Constraints

【讨论】:

  • 你不应该在你的例子的PK(类别,id,价格)中包含价格吗?他要求“任何列”和“跨所有列”? ...然后添加一个严厉的评论,说这是次优的、缓慢的并且在现实生活中从来不需要? (是的!我在这里吹毛求疵:-)
  • 我同意。所有列都应该在那里
  • 在我的情况下根本不起作用。例如,如果我使用不同的类别,但相同的 id,仍然显示重复的键。
  • @bagusflyer 我遇到的一个案例是 MySQL 的类型转换导致两个原本不同的数据成为相同的插入值,导致重复键,例如通过将字符串转换为数字或限制字符数。错误信息应显示转换后的确切键值,可用于检查是否发生转换。
【解决方案2】:

主键是一个域概念,可在相似实体中唯一(必要且充分地)标识您的实体。只有当键的一部分引用另一个域实体的特定实例时,复合(多列)主键才有意义。

假设您有个人收藏的书籍。只要你一个人,你就可以数数并给每个人分配一个数字。该数字是您图书馆域的主键。

现在您想将您的图书馆与您邻居的图书馆合并,但仍然能够区分一本书属于谁。域现在更宽了,主键现在是 (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 主键中最左边的组成部分。

【讨论】:

  • 这是一个出色的答案。
【解决方案3】:

主键是行的唯一值。包含价格是没有意义的,价格可能会发生变化。想象一下,如果您必须更改大范围的价格,那么所有这些主键值都会更改。那将是多么混乱!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 2011-08-12
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多