如何在 MySQL 数据库中重新分配唯一的整数 ID?
How to redistribute unique integer ids in a MySQL database?
考虑一下:
- 我有一个包含 10 行的数据库。
- 每一行都有一个唯一的 ID (int) 与一些值配对,例如名称(varchar)。
- 这些 ID 从 1 递增到 10。
- 我删除了 2 条记录 - 2 和 8。
- 我再添加 2 条记录 11 和 12。
问题:
- 有没有一种好方法可以重新分配此数据库中的唯一 ID,使其再次从 1 变为 10?
- 这会被视为不好的做法吗?
我问这个问题,因为在使用了这个数据库之后:添加和删除值,ids 会有很大的不同。
解决这个问题的一种方法是在您实际查询时只生成您想要的行号,如下所示:
SET @rn = 0;
SELECT
(@rn:=@rn + 1) AS rn, name
FROM yourTable;
ORDER BY id;
一般来说,您不必担心 MySQL 分配的自动递增值。 MySQL 将确保这些值在您不干预的情况下是唯一的。
如果您将 ID 列设置为主键和自动递增,"resetting" 并不是真正必要的,因为它会继续分配唯一 ID。
如果困扰您的是现有值中的 "gaps",那么您可以求助于 "sort deletion",通过使用 is_deleted 列具有 bit/boolean 个值。当然,默认值是 0(或 b0)。事实上,如果有一些非常重要的数据以后可能会有用,建议软删除,特别是如果它涉及与支付相关的条目的可能性,用户可以通过疏忽或故意删除其中一个条目。
没有简单的删除方法,您只需删除一个值并重新排列剩余的 ID 以保留序列。解决方法可能是执行以下步骤:
- 先删除条目。即
delete from <table> where ID = _value
- INSERT INTO SELECT(没有 id 列)。请注意 table 需要在列和类型方面相同才能使此查询正常工作,可以这么说......您也可以使用临时的 backup_table。即
insert into <backup_table> select <coluum1, column2, ...> from <table>
- 截断您的 table,即
truncate table <table>
- 将临时 table 中的值复制回现有的 table。您可以再次使用 INSERT INTO SELECT,但请确保在最后
降低温度 table
请注意,我不建议您这样做,主要是因为大多数人在他们的应用程序中使用某种缓存,并且他们还使用特定方法来评估特定对象是否相同。
IE。在 Java 中,POJO 的 equals() 和 hashCode() 方法被覆盖,程序员通常依赖 ID 作为识别特定对象的永久方式。通过使用上述方法,你基本上打破了整个概念,我不建议你为此更改对象的自动增量 ID 值,而不是其他任何事情。
本质上,你想做的只是一个反模式,通常会将经验丰富的程序员采用的常见模式和实践变成容易出现意外问题的解决方案 and/or 失败......尤其是这个应用 if/when 涉及高级功能,例如将这种反模式应用到利用 galera 集群 and/or 应用程序缓存的应用程序中。
考虑一下:
- 我有一个包含 10 行的数据库。
- 每一行都有一个唯一的 ID (int) 与一些值配对,例如名称(varchar)。
- 这些 ID 从 1 递增到 10。
- 我删除了 2 条记录 - 2 和 8。
- 我再添加 2 条记录 11 和 12。
问题:
- 有没有一种好方法可以重新分配此数据库中的唯一 ID,使其再次从 1 变为 10?
- 这会被视为不好的做法吗?
我问这个问题,因为在使用了这个数据库之后:添加和删除值,ids 会有很大的不同。
解决这个问题的一种方法是在您实际查询时只生成您想要的行号,如下所示:
SET @rn = 0;
SELECT
(@rn:=@rn + 1) AS rn, name
FROM yourTable;
ORDER BY id;
一般来说,您不必担心 MySQL 分配的自动递增值。 MySQL 将确保这些值在您不干预的情况下是唯一的。
如果您将 ID 列设置为主键和自动递增,"resetting" 并不是真正必要的,因为它会继续分配唯一 ID。
如果困扰您的是现有值中的 "gaps",那么您可以求助于 "sort deletion",通过使用 is_deleted 列具有 bit/boolean 个值。当然,默认值是 0(或 b0)。事实上,如果有一些非常重要的数据以后可能会有用,建议软删除,特别是如果它涉及与支付相关的条目的可能性,用户可以通过疏忽或故意删除其中一个条目。
没有简单的删除方法,您只需删除一个值并重新排列剩余的 ID 以保留序列。解决方法可能是执行以下步骤:
- 先删除条目。即
delete from <table> where ID = _value
- INSERT INTO SELECT(没有 id 列)。请注意 table 需要在列和类型方面相同才能使此查询正常工作,可以这么说......您也可以使用临时的 backup_table。即
insert into <backup_table> select <coluum1, column2, ...> from <table>
- 截断您的 table,即
truncate table <table>
- 将临时 table 中的值复制回现有的 table。您可以再次使用 INSERT INTO SELECT,但请确保在最后 降低温度 table
请注意,我不建议您这样做,主要是因为大多数人在他们的应用程序中使用某种缓存,并且他们还使用特定方法来评估特定对象是否相同。 IE。在 Java 中,POJO 的 equals() 和 hashCode() 方法被覆盖,程序员通常依赖 ID 作为识别特定对象的永久方式。通过使用上述方法,你基本上打破了整个概念,我不建议你为此更改对象的自动增量 ID 值,而不是其他任何事情。
本质上,你想做的只是一个反模式,通常会将经验丰富的程序员采用的常见模式和实践变成容易出现意外问题的解决方案 and/or 失败......尤其是这个应用 if/when 涉及高级功能,例如将这种反模式应用到利用 galera 集群 and/or 应用程序缓存的应用程序中。