【问题标题】:MySQL Auto Increment Values After DELETE without WHERE在没有 WHERE 的情况下删除后 MySQL 自动递增值
【发布时间】:2009-09-13 13:24:50
【问题描述】:

跑步后发现,

DELETE FROM tablename

我的 ID(自动递增)值变得很奇怪

7, 8, 9, 0, 1, 12, 3, 4, 15 

按照这个顺序,当我做一个时,

SELECT * FROM tablename

我知道认证指南说,当使用 DELETE without WHERE 清空表时,ID 可能会或可能不会被重置,但是是什么导致 ID 序列如此奇怪?我很确定这是插入行的顺序。最初在删除之前,我的表中有 6 行,所以 7、8、9 似乎可以理解。

【问题讨论】:

    标签: mysql auto-increment sql-delete


    【解决方案1】:

    如果没有order by 子句,数据库中绝对没有任何相似性或顺序保证。这与记录的存储方式有关——它们不是按任何顺序存储的。数据库通常会根据聚簇索引优化其存储数据的方式,但每个数据库存储数据的方式略有不同。

    你永远不应该认为你会有一个可重复的订单除非你使用order by子句。

    因此,您的 ID 似乎已被回收。这个顺序绝对没有什么奇怪的——你首先选择了一个伪随机顺序。

    【讨论】:

    • 我理解“如果没有 order by 子句,数据库中的顺序绝对没有相似或保证”,但我希望重用 ID 的顺序是升序的?我认为该订单仅在检索时才会是随机的(因为它存储了“randomly”)?即使重复使用 ID 也是随机的?并且通常 ID 不使用 0?
    • 我不知道删除发生的时间或删除的内容,所以这对我来说一点也不奇怪。如果表设置为AUTO_INCREMENT=0,那么0就会起作用。
    【解决方案2】:

    参考您的屏幕截图:http://img19.imageshack.us/img19/7336/82051321.pnghttp://img27.imageshack.us/img27/2935/24285862.png

    问题在于您的“应用程序代码”。您正在将 LOAD DATA INFILE 与具有 windows 样式 (\r\n) 行结尾的文件一起使用,除非您另外指定,否则 mysql 中的默认值是 unix 样式 (\n)。

    要明白我的意思,试试这个:

    mysql> load data infile 'data.txt' into table testDel (val);
    Query OK, 6 rows affected (0.01 sec)
    Records: 6  Deleted: 0  Skipped: 0  Warnings: 0
    
    mysql> select * from testDel;
    +----+----------------+
    | id | val            |
    +----+----------------+
     | 7 | hello world 1
     | 8 | hello world 2
     | 9 | hello world 3
     | 0 | hello world 4
     | 1 | hello world 5
    | 12 | hello world 6  |
    +----+----------------+
    6 rows in set (0.00 sec)
    
    mysql> select id, hex(val) from testDel;
    +----+------------------------------+
    | id | hex(val)                     |
    +----+------------------------------+
    |  7 | 68656C6C6F20776F726C6420310D |
    |  8 | 68656C6C6F20776F726C6420320D |
    |  9 | 68656C6C6F20776F726C6420330D |
    | 10 | 68656C6C6F20776F726C6420340D |
    | 11 | 68656C6C6F20776F726C6420350D |
    | 12 | 68656C6C6F20776F726C642036   |
    +----+------------------------------+
    6 rows in set (0.01 sec)
    

    正在发生的事情是 \r 正在破坏您的值的显示。你有没有注意到你的桌子“墙”没有排成一行?这应该是显示出现问题的提示,正如在“墙壁”确实排列的带有 hex(val) 的查询中所证明的那样。

    要修复导入,您必须在文件中指定行尾:

    mysql> load data infile 'data.txt' into table testDel lines terminated by '\r\n' (val);
    Query OK, 6 rows affected (0.00 sec)
    Records: 6  Deleted: 0  Skipped: 0  Warnings: 0
    
    mysql> select * from testDel;
    +----+---------------+
    | id | val           |
    +----+---------------+
    | 13 | hello world 1 |
    | 14 | hello world 2 |
    | 15 | hello world 3 |
    | 16 | hello world 4 |
    | 17 | hello world 5 |
    | 18 | hello world 6 |
    +----+---------------+
    6 rows in set (0.00 sec)
    

    【讨论】:

    • 哦,谢谢。但我会理解为什么 \r 可能会影响显示但 ids ...?
    • 我的例子的重点是告诉你数据没有错。 \r 只是简单地搞砸了格式。事实上,如果你一直使用不同的工具,例如 phpmyadmin,你甚至不会注意到这个问题。
    【解决方案3】:

    你应该尝试而不是 DELETE FROM

    TRUNCATE tablename
    

    我相信这也会重置 ID 的序列。

    【讨论】:

    • 那是truncate table tablename,亲爱的上帝,伙计,这是核选项。它不是事务性的,如果你有一个“哦,等等!”,你就不能回滚它。片刻。使用该按钮时要非常非常小心。
    • "truncate table tablename" 和 "truncate tablename" 都有效。在这种情况下,您不关心交易。我只是提供了一种重置表 ID 序列的方法。我同意你不应该在生产代码中使用它。
    • 我明白 truncate 的作用。我只是想知道为什么当我 test 使用删除命令变得如此奇怪。我也明白,如果我不使用顺序,则不能保证,但至少我希望 ID 的顺序与插入时一样。
    【解决方案4】:

    除了 DELETE、10 个简单的 INSERT 和一个简单的 SELECT 之外,这里还发生了一些事情。您的 ID 列表中有一个 0,这意味着某处正在为您的 auto_increment 列指定值。

    我会检查您的应用程序代码。

    如果不是这样,您需要提出一组特定的步骤(包括 CREATE TABLE)来说明如何重现此问题。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 2011-01-13
    • 2021-08-04
    • 2012-04-12
    相关资源
    最近更新 更多