【问题标题】:MySQL InnoDB: autoincrement non-primary keyMySQL InnoDB:自动增量非主键
【发布时间】:2012-12-14 17:04:20
【问题描述】:

是否可以自动增加一个非主键

表“book_cmets”

book_id     medium_int
timestamp   medium_int
user_id     medium_int
vote_up     small_int
vote_down   small_int
comment     text
comment_id  medium_int

Primary key -> (book_id, timestamp, user_id)

此表上不会有其他索引。但是,我想使 comment_id 列自动增量,以便我可以轻松地创建另一个表:

表“book_cmets_votes”

comment_id  (medium_int)
user_id     (medium_int)

Primary key -> (comment_id, user_id)

对于每本书的评论,用户只能投票一次。此表通过主键强制执行此规则。

问题:

是否可以自动增加一个非主键 - 如自动增加表“book_cmets”中的comment_id 列?


替代方案,讨论。

如上所述,为了简单起见,我想这样做。替代品没有希望。

  • 制作 commnet_id PK 并通过 book_id, timestamp, user_id 上的唯一索引强制执行完整性。在这种情况下,我会创建一个额外的索引。
  • 保留 PK 并将 book_comments_votes 中的 comment_id 替换为整个 PK。这将使表格的大小增加三倍以上。

建议?想法?

【问题讨论】:

  • 为什么不能简单地将comment_id 设为主键?我不明白你为什么需要额外的唯一索引。我可能只是没有完全理解你的问题。
  • comment_id 因为 PK 不足以强制执行数据完整性 - 特别是没有其他重复用户对特定书籍的投票。这就是为什么复合键需要唯一索引的原因。
  • 所以用户每本书只能投票一次,而不是您在问题中所说的每本书评论一次?

标签: mysql primary-key innodb


【解决方案1】:

您已有表。如果您已经为comment_id 提供了主键,并且唯一的目的是设置 auto_increment。您可以将主键拖放到该列。 MySQL 允许具有任何 key 属性的列可以访问 auto_increment。所以最好尝试索引或unique keycomment_id,如下所示。

1.删除主键

ALTER TABLE `book_comments` MODIFY `comment_id` INT(5) NOT NULL;

ALTER TABLE `book_comments` DROP PRIMARY KEY ;
  1. 使用UNIQUE_KEY 属性添加AUTO_INCREMENT

ALTER TABLE 'brand_keywords' CHANGE COLUMN 'comment_id' 'comment_id' INT(5) NOT NULL AUTO_INCREMENT UNIQUE;

【讨论】:

    【解决方案2】:

    从 MySQL 5.5 开始,似乎可以在没有 索引或主键的情况下为 INT 字段提供自动增量。

    【讨论】:

    • 你可以吗?请发布您的代码。我在 5.5.23 和 5.6.12 中尝试过: > create table test (user varchar(20) not null, id int auto_increment, primary key(user)); ERROR 1075 (42000):表定义不正确;只能有一个自动列,并且必须定义为一个键
    • 对不起,你必须添加一个索引,我的错。创建表测试(用户varchar(20)不为空,id int auto_increment,索引(id),主键(用户))
    • 你能提到参考吗?
    【解决方案3】:

    是的,你可以。您只需将该列设为索引即可。

    CREATE TABLE `test` (
      `testID` int(11) NOT NULL,
      `string` varchar(45) DEFAULT NULL,
      `testInc` int(11) NOT NULL AUTO_INCREMENT,
      PRIMARY KEY (`testID`),
      KEY `testInc` (`testInc`)
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
    
    
    insert into test(
      testID,
     string
    )
    values (
    1,
        'Hello'
    );
    
    
    insert into test( 
    testID,
     string
    )
    values (
    2,
        'world'
    );
    

    将为“testInc”插入具有自动递增值的行。然而,这是一件非常愚蠢的事情。

    你已经说过正确的方法了:

    “通过 book_id、timestamp、user_id 上的唯一索引对 comment_id 进行 PK 并强制执行完整性。”

    这正是你应该这样做的方式。它不仅为您提供将来查询所需的表的正确主键键,还满足the principle of least astonishment

    【讨论】:

    • “这是一件非常愚蠢的事情”。这很强大。每个怪癖都有其用例。我有大的基于文本的键,我不想在我的设计中传播它们。代理键符合要求。
    • 我建议他们使用代理键,而不是他们最初的愚蠢想法。
    • 非常感谢你帮了大忙 :))
    • 这不仅是强大的,而且是错误的评论。虽然他说得对,但拥有一把合适的钥匙是件好事。这并不意味着由各种列组成的复杂键是最好的解决方案。主整数 id 非常便携,不一定是复杂的键。
    • 即使它确实允许对任何索引进行 auto_increment,我至少会使其成为唯一索引。自动递增的非唯一索引似乎是灾难的秘诀
    猜你喜欢
    • 2012-08-11
    • 1970-01-01
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 2012-06-21
    • 2011-03-18
    相关资源
    最近更新 更多