mysql - MySQL 中的 Oracle 序列等效项

标签 mysql sql database sequences

我有类似于 Oracle user_sequences 的下表。

我有序列前缀/后缀的逻辑,但为了简单起见,我在这里跳过。

create table my_seq(
min_value integer,
Max_value integer,
last_value integer,
increment_by tinyint,
customer_id integer);

假设当前表中有两条记录。

insert into my_seq(min_value,max_value,last_value,increment_by,customer_id) 
  values(1,99999999,1,1,'foo#',1),(1,999999999,100,1,'foo#',2);

我的 foo 表结构是这样的,

创建表foo(id Auto_increment,foo_number varchar(20),customer_id integer);

受限: 我无法使用 MySQL AUTO_INCRMENT 列,因为 foo 包含不同的客户数据,并且每个客户都可以选择 foo_number 自动生成或手动输入,如果客户选择 auto_genesis,则应该存在间隙。所以 customer=1 选择了它,foo# 应该是 1,2,3,4 等,不允许有间隙。

到目前为止一切顺利,如果我的应用程序在单线程中运行,我们已经实现了自动增量逻辑。我们生成 foo_number 并与其他数据点一起填充到 foo 表中。

我只需执行一个查询即可获取下一个 auto#。

select last_number from my_seq where customer_id=?;

读取 # 并更新记录。

update my_seq set last_number=last_number+increment_by where customer_id=?;

问题: 当多个并发 session 尝试运行 select last_number from my_seq... 时,它会多次返回相同的 foo_number 。另外,由于应用程序端的限制和性能瓶颈,我无法在应用程序中强制执行单线程,因此需要在数据库端解决它。

请建议我如何避免重复的数字?请帮忙,提前致谢。

我google了一下,很多stackoverflow链接都建议使用get_last_id(),如你所见,我无法使用它。

最佳答案

通过结合 @Akina 和 @RickJames 的建议,我能够解决这个问题,谢谢你们的支持。

create table my_seq(
min_value integer,
Max_value integer,
last_value integer,
increment_by tinyint,
customer_id integer)ENGINE = InnoDB;

这里ENGINE=InnoDB非常重要。 为了确保读取时存在表级锁定,我已将应用程序代码修改为:

自动提交=FALSE

那么,

//very import to begin the transaction
begin;
select last_number from my_seq where customer_id=? FOR UPDATE;

Read the result in App.

update my_seq set last_number=last_number+1 where customer_id=?;
commit;

即使在多个并发 session 的情况下,这也会生成唯一的序列号

我遇到了另一个问题,这个解决方案减慢了我生成序列#的其他地方的速度。我已经通过索引 customer_id 解决了启用行级锁而不是表级锁的问题。

更改表 TABLE_NAME 添加索引 (customer_id);

希望这对其他人有帮助。

关于mysql - MySQL 中的 Oracle 序列等效项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50831922/

相关文章:

mysql - 在 key 更新时选择最大合并?

MySQL - 返回 10 天内注册的用户

php - 评估数学表达式

显示左表的 SQL 连接,即使右表与 where 不匹配

mysql - 如何在 MYSQL 中执行此查询?

mysql - 插入查询不适用于具有外键的行

php - 仅使用 PHP/HTML/Javascript 将 'value' 从多个单选类型选择添加到 mySQL 中的特定行/列

Mysql语法错误

sql - 在 Oracle INSERT ALL 语句中选择 Select Columns

mysql - 最佳使用数据库存储大型科学数据集