【问题标题】:How to reorder a primary key?如何重新排序主键?
【发布时间】:2011-11-14 17:05:11
【问题描述】:

我有一个包含 5700 条记录的表。主键是一个整数。现在我注意到缺少一些值。像这样:

100 data
101 data 
102 data
104 data

103 丢失。如何在一个 SQL 命令中更新所有行以使顺序正确(在我的示例中,104 变为 103)?

【问题讨论】:

  • 为什么需要这样做? PK中的“洞”是正常情况,有的加了,有的删了,没什么好担心的。
  • [这里][1] 你可以找到答案。 [1]:stackoverflow.com/questions/1841104/…

标签: mysql


【解决方案1】:

试试这个:

SET @var:=0;
UPDATE `table` SET `id`=(@var:=@var+1);
ALTER TABLE `table` AUTO_INCREMENT=1; 

【讨论】:

  • 这很好用。使用 innoDB 级联,关系是安全的,哦,使用 ALTER TABLE table auto_increment = 1;修复自动增量重置。
  • 感谢您的提及。编辑答案以包含此查询。
  • 这实际上就像魅力一样。对我来说,这是这个问题的公认答案
【解决方案2】:

这样做没有意义。

已删除记录中的 ID 不会被有意重复使用 - 例如,以确保从其他表对先前已删除记录的引用不会突然指向 错误 记录。尝试改变这一点不是一个好主意。

如果您想要一个没有漏洞的编号列表,请创建第二个 int 列,以便在必要时(即删除记录时)在客户端程序中重新排序。

【讨论】:

  • 如果您想要一个没有漏洞的编号列表,请创建第二个 int 列,以便在必要时(即删除记录时)在客户端程序中重新排序。伟大的!如何在 PHP 中做到这一点?
  • 如果有人需要这样做,他可以有理由这样做,即使你认为没有意义。
  • @sanmai 提供编号列表不是主键的工作。如果需要,请维护第二列。为此滥用PK简直是愚蠢的。
  • 没关系,因为你的回答没有回答问题。
  • @sanmai 您正在宣传盲目回答问题,即使这会导致不良做法。我认为这是一个糟糕的想法,并且可能有害。提问 question 应该是回答之前要做的第一件事。见What is the XY problem?
【解决方案3】:

不确定一个命令,但你可以用四个命令来完成:

CREATE TABLE `temp` SELECT * FROM `orig_tbl`;
TRUNCATE `orig_tbl`;
-- counter doesn't reset in some old versions
ALTER TABLE `orig_tbl` AUTO_INCREMENT = 1; 
-- now we omit primary key column to let it seal the holes
INSERT INTO `orig_tbl` (`col1`, `col2`) SELECT `col1`, `col2` FROM `temp`;

除非您这样做是为了更轻松地随机选择记录,否则您真的应该重新考虑您的方法。

【讨论】:

  • 如果你使用外键,这会搞砸你
  • @frostymarvelous 如果您使用外键,为什么首先要重新排序主键?
  • 我打算在新项目中重用旧数据集。我只需要清理它。
【解决方案4】:

除非您真的别无选择,否则我建议您不要弄乱您的 PK,否则当其他表引用该 id 列时,它可能会导致整个地方的损坏。如果PK真容不得半点缝隙,或许PK的选择并不理想……

如果你真的认为你应该这样做(并且确定不会在其他表中破坏):

  • 创建一个与原始表结构相同的表,但使用类型 serial 作为 id
  • 将不带 id 的数据复制到该复制表中 - 现在您将拥有一份原始副本,这要归功于串行一个不错的无缝 id 字段
  • 清空原始表(或更快,创建相同的副本并删除原始表)
  • 将复制表中的数据复制到包含id的原始表中

【讨论】:

    【解决方案5】:

    另一种方式,不截断整个表:

    -- Make Backup of original table's content
    CREATE TABLE `orig_tbl_backup` SELECT * FROM `orig_tbl`;
    -- Drop needed column. 
    ALTER TABLE `orig_tbl` DROP `id`;
    -- Re-create it
    ALTER TABLE `orig_tbl` AUTO_INCREMENT = 1;
    ALTER TABLE `orig_tbl` ADD `id` int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-18
      相关资源
      最近更新 更多