了解 MySQL 在添加自动增量主键时的行为

发布于 2024-12-02 01:55:07 字数 890 浏览 2 评论 0原文

假设我们在 MySQL 数据库中有一个 (InnoDB) 表 associations,其结构如下:

CREATE TABLE `associations` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
  `fk_id_1` int(11) NOT NULL,
  `fk_id_2` int(11) NOT NULL,
  `fk_id_3` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`),
  UNIQUE KEY `some_unique_constraint` (`fk_id_1`,`fk_id_2`),
  KEY `fk_id_2_INDEX` (`fk_id_2`),
  KEY `fk_id_3_INDEX` (`fk_id_3`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin$$

id 列中有跳转(我知道这是一个如何在多个线程尝试获取自动增量值时生成自动增量值的问题)。由于没有其他表使用 id 列作为参考,我计划删除 id 列并重新创建它,希望计数漏洞将会消失。我备份了数据库并进行了测试。结果有点令人困惑。行的顺序似乎发生了变化。如果我没记错的话,顺序是首先是fk_id_1,然后是fk_id_2,然后是fk_id_3

当为行分配新生成的自动增量键时,这是 MySQL 设置表的自然顺序吗?

在此过程中还发生了更多我应该知道的事情吗?

我需要了解这一点的原因是,我需要使 id 列对于我打算完成的另一项任务有用,其中间隙是不可能的。

Let's say we have a (InnoDB) table associations in a MySQL-Database which has the following structure:

CREATE TABLE `associations` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
  `fk_id_1` int(11) NOT NULL,
  `fk_id_2` int(11) NOT NULL,
  `fk_id_3` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`),
  UNIQUE KEY `some_unique_constraint` (`fk_id_1`,`fk_id_2`),
  KEY `fk_id_2_INDEX` (`fk_id_2`),
  KEY `fk_id_3_INDEX` (`fk_id_3`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin$

There are jumps in the column id (I know this is an issue of how the autoincremented value is generated while multiple threads try to get one). Since no other table is using the column id as a reference I plan to drop the column id and to create it again, hopefully the counting holes will be gone. I backed up my database and tested that. The result was a little confusing. The order of the rows seemed to have changed. If I am not mistaken the order is first by fk_id_1 then fk_id_2 then fk_id_3.

Is this the natural order in which MySQL sets the table, when assignung an new generated autoincrement key to the rows?

Is there more I should know, that happened during this process?

The reason, why I need to know about this is that I need to make the column id useful for another task I intend to accomplish where gaps are a no go.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

为你鎻心 2024-12-09 01:55:07

任何主流 RDBS 中的表都没有自然顺序。

只有 SELECT 语句中最外层的 ORDER BY 才能保证结果的顺序。

如果你想要“顺序”:

  • 创建一个新表
  • INSERT..SELECT..ORDER BY fk_id_1, fk_id_2, fk_id_3
  • 删除旧表
  • 重命名新表

或者接受间隙...强迫症对开发人员不利

编辑:

问题说“不依赖”这个值,但事实证明是存在的。

如果不允许间隙,则不要使用自动编号,并使用 fk_id_1、fk_id_2、fk_id_3 作为密钥,并进行 ROW_NUMBER 模拟。或者对下游进行编码以处理差距。

自动编号会有间隙:生活中不可改变的事实。

There is no natural order to a table in any mainstream RDBS.

Only the outermost ORDER BY in a SELECT statement will guarantee the order of results.

If you want "order":

  • create a new table
  • INSERT..SELECT..ORDER BY fk_id_1, fk_id_2, fk_id_3
  • Drop old table
  • Rename new table

Or live with gaps... OCD isn't good for developers

Edit:

Question says "no dependency" on this value but turns out there is.

If gaps are not allowed then don't use autonumber and use fk_id_1, fk_id_2, fk_id_3 as your key, with a ROW_NUMBER emulation. Or code your downstream to deal with gaps.

Autonumbers will have gaps: immutable fact of life.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文