9

mysql数据库做流水号

 4 years ago
source link: https://www.wencst.com/archives/2046
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

需求

需要生成一个按某个种子生成流水号,这个种子目前是时间维度,比如2020年7月1日生成流水号从0开始一直向后递增1,无论2020年7月1日最终流水号生成多少,2020年7月2日生成流水号依然从0开始重新计数。

方案

1.考虑redis自增数据

虽然这是常用方案,不过我们为了简化架构,redis组件增加后只用作获取自增序列这一个功能,有点大材小用了,所以暂不考虑这个方案。

2.考虑数据库sequence序列

mysql没有sequence功能,这个确实有点坑。

3.使用数据库的auto_increment自增

drop table test;
CREATE TABLE test (
  id varchar(64) not null primary key,
  my_id INT AUTO_INCREMENT NOT NULL unique,
  name VARCHAR(10) NOT NULL
);
insert into test(id,my_id,`name`) values (UUID(),null,'abc')

这个方案确实可以,不过有个弊端,就是不支持种子,也就是当我切换name的时候,计数器并不会重新计数。

4.使用数据库last_insert_id方法

这个方法是基于方案3给出的方法,方案3是每次插入业务数据时,这条数据上新增一列作为自增列,插入后,我们可以使用last_insert_id获取到my_id这一列的值。

那么我们是否可以使用单独一张表来计数,这样是否可以使用种子了呢?答案是否定的。

例如方案3中给出的test表是独立的表,name只是作为种子存在,插入数据时拿到last_insert_id,就是上一次插入的my_id了,不过last_insert_id只能获取到insert数据,对于update的数据是拿不到的,所以如果单独一张表来记录计数,依然要用insert方法,又回到方案3的问题了,没有种子。

5.使用结合方式

使用单独计数表+function来实现,网上大部分给出的方案也是这个方法,不过写的比较乱,我在这里总结一下:

CREATE TABLE tb_sequence ( NAME VARCHAR ( 50 ) NOT NULL, current_value INT NOT NULL, _increment INT NOT NULL DEFAULT 1, PRIMARY KEY ( NAME ) );

DELIMITER //
CREATE FUNCTION _nextval ( n VARCHAR ( 50 ) ) RETURNS INTEGER BEGIN
DECLARE
		_cur INT;
	SET _cur = ( SELECT current_value FROM tb_sequence WHERE NAME = n );
	IF
		_cur IS NULL THEN
			INSERT INTO tb_sequence
		VALUES
			( n, 1, 1 );
		SET _cur = 1;
	END IF;
	UPDATE tb_sequence 
	SET current_value = _cur + _increment 
	WHERE
		NAME = n;
	RETURN _cur;
	END;
// 
SELECT _nextval ( 'test' );

在select _nextval(‘seed’)是,把seed作为种子,如果不存在,就在计数表里插入一条数据,如果存在,则直接+1返回,所以以后每次取值时,可以用一个function就搞定了。

结论

网上有很多文章讲述方案5的,我只是个搬运工,并稍微改动了一下,也避免以后找不到了,供大家参考。

针对这个例子还有很多可扩展的方法,可以修改得更通用,更容易扩展,我就不做赘述了,有更好方案的小伙伴请在下方留言。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK