消除自动增量中的间隙

时间:2012-03-17 22:14:12

标签: mysql

假设我有一个带有自动递增id字段的MySQL表,然后我插入3行。然后,我删除第二行。现在表格的id为1,3。我可以让MySQL纠正它并使其成为1,2而无需编写程序吗?

2 个答案:

答案 0 :(得分:5)

一旦创建了自动索引列,MySQL将不允许您更改索引。我所做的是删除自动索引列,然后添加一个具有相同名称的新列,mysql将索引新生成的列没有间隙。仅在自动索引与其余数据无关但仅用作更新和删除参考的表上执行此操作。

例如,我最近为包含谚语的表做了这一点,其中自动索引列仅在我更新或删除谚语时使用但我需要自动索引是顺序的,因为谚语是通过随机抽出的数字在1和谚语的数量之间,在序列中有间隙可能导致随机数指向不存在的指数。

HTH

答案 1 :(得分:0)

The Access Ten Commandments引用(它可以扩展到其他RDBMS:“如果该字段对您的用户有意义,则不应使用自动编号(或自动增量)”

我能想到的唯一选择(仅使用MySQL)是:

  1. 创建一个触发器,将行号添加到列中(不是主键
  2. 创建一个删除行并更新行号的程序(我无法使用触发器,对不起)
  3. 示例:

    create table tbl_dummy(
        id int unsigned not null auto_increment primary key,
        row_number int unsigned not null default 0,
        some_value varchar(100)
    );
    
    delimiter $$
    
    -- This trigger will add the correct row number for each record inserted 
    -- to the table, regardless of the value of the primary key    
    create trigger add_row_number before insert on tbl_dummy
    for each row
    begin
        declare n int unsigned default 0;
        set n = (select count(*) from tbl_dummy);
        set NEW.row_number = n+1;
    end $$
    
    -- This procedure will update the row numbers for the records stored
    -- after the id of the soon-to-be-deleted record, and then deletes it.
    create procedure delete_row_from_dummy(row_id int unsigned)
    begin
        if (select exists (select * from tbl_dummy where id = row_id)) then
            update tbl_dummy set row_number = row_number - 1 where id > row_id;
            delete from tbl_dummy where id = row_id;
        end if;
    end $$
    
    delimiter ;
    

    请注意,您将被迫逐个删除记录,并且您将被迫获取要删除的记录的正确主键值。

    希望这有帮助