【问题标题】:ALTER TABLE to add a composite primary keyALTER TABLE 添加复合主键
【发布时间】:2012-02-10 04:11:48
【问题描述】:

我有一张名为provider 的表。我有三个名为personplacething 的列。可以有重复的人、重复的地点和重复的事物,但永远不会有重复的人-地点-事物组合。

我将如何 ALTER TABLE 为 MySQL 中的该表添加这三列的复合主键?

【问题讨论】:

    标签: mysql sql primary-key alter-table composite-primary-key


    【解决方案1】:
    ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);
    

    如果主键已经存在,那么你想这样做

    ALTER TABLE provider DROP PRIMARY KEY, ADD PRIMARY KEY(person, place, thing);
    

    【讨论】:

    • @David542 不,它没有 - 你只能有 1 个主键。
    • @David:它是由多个字段组成的单个主键,也就是复合键。
    • @David542 当然可以 - 这是一个由 3 个字段组成的复合主键。 3 个字段的组合必须是唯一的。
    • 感谢发帖——真的让我摆脱了与 ui 的斗争
    • SO 中最宝贵的答案之一 :)
    【解决方案2】:

    @Adrian Cornish 的回答是正确的。但是,删除现有主键还有另一个警告。如果该主键被另一个表用作外键,则在尝试删除它时会出错。在某些版本的 mysql 中,错误消息格式错误(截至 5.5.17,此错误消息仍然

    alter table parent  drop column id;
    ERROR 1025 (HY000): Error on rename of
    './test/#sql-a04_b' to './test/parent' (errno: 150).
    

    如果您想删除被另一个表引用的主键,您必须先删除另一个表中的外键。如果您在重新创建主键后仍需要该外键,则可以重新创建该外键。

    此外,在使用复合键时,顺序也很重要。 这些

    1) ALTER TABLE provider ADD PRIMARY KEY(person,place,thing);
    and
    2) ALTER TABLE provider ADD PRIMARY KEY(person,thing,place);
    

    不是一回事。 它们都在这三个字段的集合上强制唯一性,但是从索引的角度来看是有区别的。字段的索引从左到右。 例如,考虑以下查询:

    A) SELECT person, place, thing FROM provider WHERE person = 'foo' AND thing = 'bar';
    B) SELECT person, place, thing FROM provider WHERE person = 'foo' AND place = 'baz';
    C) SELECT person, place, thing FROM provider WHERE person = 'foo' AND place = 'baz' AND thing = 'bar';
    D) SELECT person, place, thing FROM provider WHERE place = 'baz' AND thing = 'bar';
    

    B可以在ALTER语句1中使用主键索引
    A可以在ALTER语句中使用主键索引2
    C 可以使用任一索引
    D 不能使用任何一个索引

    A 使用索引 2 中的前两个字段作为部分索引。 A 不能使用索引 1,因为它不知道索引的中间位置部分。不过,它可能仍然可以在 just person 上使用部分索引。

    D 不能使用任何一个索引,因为它不认识人。

    有关更多信息,请参阅 mysql 文档here

    【讨论】:

    • @All - 您能否分享相同的 JPA 等效项?
    【解决方案3】:

    您可能只需要一个唯一约束。特别是如果您已经有代理键。 (已经存在的代理键的示例是一个 AUTO_INCREMENT 的单列)

    下面是唯一约束的sql代码

    ALTER TABLE `MyDatabase`.`Provider`
        ADD CONSTRAINT CK_Per_Place_Thing_Unique UNIQUE (person,place,thing)
    ;
    

    【讨论】:

    • 谢谢,约束是我想要的,我不知道在最初的帖子中要求什么。感谢您将此添加到线程中。
    • 我通常使用代理键......然后添加唯一约束。这种方式....如果“唯一性”在未来发生变化,那么调整约束并没有太多戏剧性,而不是弄乱主键。如果您有外键引用此表的子表,则只需对代理键进行 FK,而不是全部 3 列。 ——
    【解决方案4】:
    alter table table_name add primary key (col_name1, col_name2);
    

    【讨论】:

      【解决方案5】:

      使用 COMPOSITE UNIQUE KEY 肯定更好,正如@GranadaCoder 提供的那样,虽然是一个有点棘手的例子:

      ALTER IGNORE TABLE table_name ADD UNIQUES INDEX idx_name(some_id, another_id, one_more_id);

      【讨论】:

        【解决方案6】:

        ALTER TABLE table_name DROP PRIMARY KEY,ADD PRIMARY KEY (col_name1, col_name2);

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-01-25
          • 1970-01-01
          • 2012-04-28
          • 2018-04-27
          • 1970-01-01
          • 2012-07-16
          • 1970-01-01
          • 2013-03-19
          相关资源
          最近更新 更多