首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >不带auto_increment的唯一id

不带auto_increment的唯一id
EN

Stack Overflow用户
提问于 2014-09-18 09:04:06
回答 4查看 7.1K关注 0票数 3

我有一个具有非自动递增主键的现有模式。该键在其他十几个表中用作外键。

我继承了一个有重大性能问题的程序。目前,当向该表添加新行时,创建新的唯一id的方式如下:

代码语言:javascript
运行
复制
1) a query for all existing primary key values is retrieved
2) a random number is generated
3) if the number does not exist in the retrieved values, use it, otherwise goto (2)

该应用程序是多线程和多服务器的,所以简单地在启动时获取一次现有的ids不是一个选择。我没有从发起请求中获取并转换为伪唯一值(如成员id)的唯一信息。

我知道在理论上可以在内部执行操作,以将自动递增添加到现有的主键。我知道系统地删除指向这个表的所有外键也是可能的,然后创建-重命名-插入一个新版本的表,然后添加回来的外键,但是这个表格式是由第三方应用程序决定的,如果我搞砸了,那么糟糕的事情就会发生。

有没有一种方法可以利用sql/mysql获得唯一的行值?

我想出的最接近的方法是从一个很大的空间中随机选择一个数字,并希望它在数据库中是唯一的,然后在发生奇怪的冲突时重试。

想法?

EN

回答 4

Stack Overflow用户

发布于 2014-09-18 09:12:12

如果表的主键未用于外键引用,则删除该主键。其目标是使您的列成为自动递增的主键。

因此,查找最大值,然后执行以下操作:

代码语言:javascript
运行
复制
alter table t modify id int not null auto_increment primary key;
alter table t auto_increment = <maximum value> + 1;

我不认为有必要显式地设置auto_increment值,但我喜欢确定。

票数 2
EN

Stack Overflow用户

发布于 2014-09-18 09:16:47

我认为你可以选择MAX(‘strange id-column’)+1,这个值是唯一的,你可以把sql代码和插入代码放在一个事务中,以防止出错。

票数 0
EN

Stack Overflow用户

发布于 2014-09-18 09:33:09

拉回所有主键值的列表(对于大型集合),然后生成伪随机值并通过检查列表来验证它的唯一性,这似乎真的很昂贵。

我看到这种方法的一个大问题是,当序列以相同的种子值启动时,伪随机数生成器将生成相同的值序列。

如果发生了这种情况,那么将会有一次又一次的冲突,直到序列达到一个尚未使用的值。下一次发生这种情况时,你会再次遍历整个列表,以添加另一个值。

我不明白为什么这个值必须是随机的。

如果不需要伪随机性,并且升序值也可以,那么如果我不想对现有表进行任何更改,我会这样做:

我将创建另一个具有auto_increment列的“id生成器”表。我对该表执行插入操作以生成id值。

我不会运行查询从现有表中拉回所有现有的生成器值,而是执行一个插入到“id- id”表中,然后执行一个SELECT LAST_INSERT_ID()来检索我刚插入的行的id,它将使用该值作为“生成的”id值。

基本上,模拟Oracle SEQUENCE对象。没有必要将所有行都保存在"id-generator“表中。因此,我可以删除所有id值小于最大id值的行。

如果需要伪随机性(抖动),我可能只会尝试插入,以此来确定键是否存在。如果由于键重复而导致插入失败,我将使用不同的id值重试。

伪随机生成器的重复序列吓到我了。如果我连续发生几次碰撞。这些是来自以前使用的序列,还是来自不同序列的值。我没有任何办法知道。放弃序列并重新开始一个新的种子,如果该种子以前已经被使用过,我将继续追逐之前生成的另一系列值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25902626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档