我有一个mysql表,其中每一行在“序列”列中都有自己的序列号。但是,当一行被删除时,会留下一个空白。所以...
1
2
3
4
......变成......
1
2
4
是否有一种“重置”排序的简洁方法,因此它在一个SQL查询中再次连续?
顺便说一下,我确信这个过程有一个技术术语。任何人吗?
更新:“序列”列不是主键。它仅用于确定记录在应用程序中的显示顺序。
答案 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时,它将保持表锁。