如何重置序列号才能连续?

时间:2011-08-14 13:55:30

标签: mysql sql database-design sequencing

我有一个mysql表,其中每一行在“序列”列中都有自己的序列号。但是,当一行被删除时,会留下一个空白。所以...

1
2
3
4

......变成......

1
2
4

是否有一种“重置”排序的简洁方法,因此它在一个SQL查询中再次连续?

顺便说一下,我确信这个过程有一个技术术语。任何人吗?

更新:“序列”列不是主键。它仅用于确定记录在应用程序中的显示顺序。

5 个答案:

答案 0 :(得分:7)

如果该字段是您的主键...

...然后,正如本问题其他地方所述,您不应该更改ID。这些ID已经是唯一的,您既不需要也不想重复使用它们。

现在,那说......


否则...

对于某些应用程序定义的排序,您很可能有不同的字段(也就是PK)。只要这个排序不是某些其他领域固有的(例如,如果它是用户定义的),那么这没有任何问题。

您可以使用(临时)auto_increment字段重新创建表格,然后删除auto_increment

我会按升序诱惑UPDATE并应用递增变量。

SET @i = 0;
UPDATE `table`
   SET `myOrderCol` = @i:=@i+1
 ORDER BY `myOrderCol` ASC;

(查询未经测试。)

每次删除项目时,这样做似乎相当浪费,但遗憾的是,如果您想要保持完整性,那么通过这种手动订购方法,您可以做很多事情。列。

您可以减少负载,这样在删除myOrderCol等于5后的条目后:

SET @i = 5;
UPDATE `table`
   SET `myOrderCol` = @i:=@i+1
 WHERE `myOrderCol` > 5
 ORDER BY `myOrderCol` ASC;

(查询未经测试。)

这会将所有以下值“混乱”一下。

答案 1 :(得分:1)

我会说不要打扰。重新分配顺序值是一项相对昂贵的操作,如果列值仅用于订购目的,则没有充分理由这样做。您可能唯一担心的是,例如,您的列是UNSIGNED INT,并且您怀疑在应用程序的生命周期中,您可能有超过4,294,967,296行(包括已删除的行)并超出范围,即使您关心的是可以在10年后发生重新分配作为一次性任务。

答案 2 :(得分:0)

这是我经常在这里和其他论坛上阅读的一个问题。正如zerkms所写,这是一个错误的问题。此外,如果你的桌子与其他桌子有关,你就会失去关系。

仅出于学习目的,一种简单的方法是将数据存储在临时表中,截断原始数据(此重置auto_increment),然后重新填充它。

愚蠢的例子:

create table seq (
id int not null auto_increment primary key,
col char(1)
) engine = myisam;

insert into seq (col) values ('a'),('b'),('c'),('d');

delete from seq where id = 3;

create temporary table tmp select col from seq order by id;

truncate seq;

insert into seq (col) select * from tmp;

但它完全没用。 ;)

答案 3 :(得分:0)

如果这是你的PK那么你就不应该改变它。 PKs(大多数)应该是不变的列。如果您要更改它们,那么您不仅需要在该表中更改它,还需要在存在的任何外键中更改它。

如果您确实需要连续序列,那么问问自己为什么。在表中没有固有的或保证的顺序(即使在PK中,尽管由于大多数RDBMS存储和检索数据的方式可能会这样)。这就是为什么我们在SQL中有ORDER BY子句。如果您希望能够根据其他内容(添加到数据库中的时间等)生成序列号,那么请考虑在查询中或在前端生成序列号。

答案 4 :(得分:0)

假设这是一个ID字段,您可以在插入时执行此操作:

INSERT INTO yourTable (ID)
SELECT MIN(ID)
FROM yourTable
WHERE ID > 1

正如其他人所说,我不建议这样做。在评估下一个ID时,它将保持表锁。