【问题标题】:Out of sync auto increment MYSQL不同步自动增量MYSQL
【发布时间】:2014-12-27 21:37:36
【问题描述】:

我正在使用的其中一个表上有一个奇怪的行为,我不确定是我的 php 代码还是数据库上的某些设置导致自动递增的 id 不同步。

如果我在名称和汽车上没有任何索引的情况下运行以下代码,我会得到:

    $cars = array("Volvo","BMW","Toyota");
    $name = "John Smith";

        foreach($cars as $value)
        {
                try 
                {

                 //insert into database with a prepared statement

                   $query = $db->prepare(
                   'INSERT INTO cars (name,cars) 
                   VALUES (:name,:cars) 
                   ');
                   $query->execute(array(           
                   ':name' => $name,
                   ':cars' => $value
                   ));

                }
                //else catch the exception and show the error.
                catch(PDOException $e) 
                {
                    $error[] = $e->getMessage();
                }   
        }

///Results
id || name       || cars
1  || John Smith || Volvo
2  || John Smith || BMW
3  || John Smith || Toyota

但是,如果我在 name&cars 上放置一个唯一索引,自动增量就会不同步,我不明白为什么,因为我看不到我的 PHP 代码有任何问题?

$cars = array("Volvo","BMW","Toyota");
    $name = "John Smith";

        foreach($cars as $value)
        {
                try 
                {

                 //insert into database with a prepared statement

                   $query = $db->prepare(
                   'INSERT INTO cars (name,cars) 
                   VALUES (:name,:cars) 
                   ');
                   $query->execute(array(           
                   ':name' => $name,
                   ':cars' => $value
                   ));

                }
                //else catch the exception and show the error.
                catch(PDOException $e) 
                {
                    $error[] = $e->getMessage();
                }   
        }

///Results
id || name       || cars
3  || John Smith || Toyota
1  || John Smith || Volvo
2  || John Smith || BMW

【问题讨论】:

  • 除非您的 SELECT 语句有 ORDER BY 子句,否则不保证您的记录将按任何特定顺序返回
  • 为什么要 name / cars 成为唯一索引?
  • 我只想要一个名字和汽车的组合。除此之外,对我来说没有任何用处,因为我只会获得与该人拥有这辆命名汽车相同的信息,其他所有内容都将作为副本存在于数据库中
  • 也谢谢你告诉我,我一直以为记录是按顺序插入的。所以我不应该担心我做错了什么导致订单失败?

标签: php mysql auto-increment sql-insert


【解决方案1】:

为什么你认为它不同步? John 的 Toyota 仍然是 3,而他的 Volvo 是 1

您如何获得结果?你只是SELECT你的cars,对吧?行为很好,因为没有任何ORDER BY 语句,无需按 id 对数据进行排序。

你应该用SELECT id, name, cars FROM cars ORDER BY id ASC查询。

mysql 完全可以返回一个无序列表。 “无序”只是一些内部优化的结果。

【讨论】:

  • 啊,你确定吗?我很担心,因为虽然数字并没有不同步,但这是我第一次看到它以随机顺序插入。通常我习惯于看到 1、2、3、4、5 等,而不是 3、1、5、2、4。你是对的,它只是一个没有任何 ORDER BY 的 SELECT 语句。所以这是正常的吗?而且我不应该担心我做错了什么?
  • 在数据库引擎重新组织表格时顺序发生变化是完全正常的。
【解决方案2】:

两件事。

首先,自动增量通常会以某种方式“不同步”。看看MySQL AUTO_INCREMENT does not ROLLBACK 的一个很好的例子,说明为什么你不能期望自动增量主键 ID 与你的数据“同步”。 id 是唯一的,并且会递增。这就是你能说的关于自动增量的全部内容。

这就引出了第二点。您当然不能说自动增量字段不会有间隙或将按排序顺序返回给您,除非您坚持认为它是(@omeinusch 和 Mark Ba​​ker 都在上面指出,他们都是正确的)。在这里,我想指出的是,您的自动增量的行为完全符合预期。插入另一行。它的 id 为四。开始插入事务,将其回滚,然后插入另一行。它的 id 为 6。这是故意的。插入 100 行,将它们回滚,然后再插入 100 行。这批 100 的自动增量 ID > 100。除非您将 ORDER BY id 添加到查询中,否则它们不会按排序顺序返回给您。这是故意的。确实没有什么“不同步”的。

【讨论】:

  • 感谢您的澄清,我知道当您删除记录时,您最终会出现空白。但是我不明白的是,我认为 foreach 每次迭代都会循环。所以在第一次迭代时它插入第一个 ID,因此首先应该是 1,第二次迭代是第二次插入,所以 2 秒等等。因此,我认为在数据库中我希望按顺序看到 1、2、3。当我看到上面的结果时,我就像是啊!为什么第 3 次迭代首先进行,不理解它们被分配了唯一的 id,但并不意味着它们将是无序的。我期待有序列表
  • 常见的误解。如果有帮助,SQL 是关系型的,这就是数学意义上的关系型(例如en.wikipedia.org/wiki/Relational_algebra)。不要把它想象成一个有序列表。把它想象成一个集合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多