简易发号SQL,可用于生成指定前缀自增序列,如订单号,生成优惠券码等

需求1:订单号要求唯一、长度不太长、自增、但不能通过早上订单号和晚上订单号相减推算出平台大概一天的单量

需求2:要求生成10w张优惠券,要求券码唯一、不能太长,不能轻易猜测出其他券码

根据这些需求提供一个简单的数据库发号的sql来满足上面的需求,介绍如下

Increments表设计两个字段,Prefix和MaxNum,不需要设计主键和聚集索引,在Prefix上建立唯一索引,可Include[MaxNum]字段,这样查询时可以保证索引覆盖

将前缀和数据拼接的服务由应用来提供,数据库自负责拿到增加后的数字,建议封装成存储过程,切记此脚本本身已包含事务,不要在应用程序中再使用事务嵌套(另外本人非dba,技术水平有限,不能保证下面sql不会出现死锁)

DECLARE @Prefix nvarchar(32)=‘C‘ --输入前缀
DECLARE @Qty int=1 --输入增长步长
SET TRANSACTION ISOLATION LEVEL READ COMMITTED --设置隔离级别
BEGIN TRAN --开启事务
    DECLARE @maxNum bigint=0 --声明目前指定前缀的当前最大数字
    reTry: --goto的label
    SELECT
    @maxNum = MaxNum + @Qty
    FROM Increments WITH (UPDLOCK)
    WHERE Prefix = @Prefix --使用更新锁查询指定前缀的目前种子数+步长,并发时,如果存在记录,只有一个连接可以查询到此记录,其他连接会被阻塞至事务提交后
    IF (@maxNum = 0) --如果未查到此前缀
    BEGIN
        BEGIN TRY
            SET @maxNum = @maxNum + @Qty
            INSERT Increments
              VALUES (@Prefix, @maxNum) --插入前缀记录,设置目前种子数等于步长,并发情况下同样的前缀可能会同时会执行插入操作,通过在Prefix设置唯一索引使只有一个插入成功,其他重新reTry
        END TRY
        BEGIN CATCH
            GOTO reTry --插入失败时reTry
        END CATCH
    END
    ELSE
    BEGIN
        UPDATE Increments
        SET MaxNum = MaxNum + @Qty
        WHERE Prefix = @Prefix --查到种子数的情况下,更新记录
    END
    SELECT
      @maxNum --返回目前种子数+步长的结果
COMMIT

订单号:短日期作为前缀+随机(1-9)步长+随机数字,如

20180108 00016 037 --示例,正常情况中间没有空格
20180108 00019 233

券码:批量生成10w张,单字母作为前缀(如T),步长设置为100W,获取数字(如2000000),生成1000000-2000000的数组,通过洗牌算法获取10w个元素,将每个元素转换为36进制

TSM9H   --对应T1335221
TSMC9   --对应T1335321

然后类似身份证校验码,自己设计一个算法增加1-2位校验码在开始或者结束,如所有数字*自身相加取最后一位放在最后,例

--T转换为数字为29

TSM9H8  --对应TSM9H 2*2+9*9+1*1+3*3+3*3+5*5+2*2+2*2+1*1=138
TSMC93  --对应TSMC9 2*2+9*9+1*1+3*3+3*3+5*5+3*3+2*2+1*1=143

原文地址:https://www.cnblogs.com/wpycs/p/8432393.html

时间: 2024-08-30 07:35:34

简易发号SQL,可用于生成指定前缀自增序列,如订单号,生成优惠券码等的相关文章

pidof---查找指定名称的进程的进程号id号。

pidof命令用于查找指定名称的进程的进程号id号. 语法 pidof(选项)(参数) 选项 -s:仅返回一个进程号: -c:仅显示具有相同"root"目录的进程: -x:显示由脚本开启的进程: -o:指定不显示的进程ID. 参数 进程名称:指定要查找的进程名称. 实例 pidof nginx 13312 5371 pidof crond 1509 pidof init 1 原文地址:https://www.cnblogs.com/jianlibao/p/9995857.html

订单号生成规则

前阵子,公司有个电子商务项目,需要生成订单号.当时的考虑很简单,取系统时间加上随机数,或者使用 uniqid() 方法.我们都知道,订单号最基本的要求就是唯一,这个条件必须满足.仔细考虑下上述方法,在顾客购买量少的情况下,订单重复的可能性为零,但是在购买高蜂期生成的订单号重复是很有可能发生的.所以上述方法不可靠,有待强化.在网上找了一番,发现这位同学的想法挺不错的,redtamo,具体的请稳步过去看看,我作简要概述,该方法用上了英文字母.年月日.Unix 时间戳和微秒数.随机数,重复的可能性大大

生成指定长度的字符串

#region 生成指定长度的字符串 2 /// <summary> 3 /// 生成指定长度的字符串,即生成strLong个str字符串 4 /// </summary> 5 /// <param name="strLong">生成的长度</param> 6 /// <param name="str">以str生成字符串</param> 7 /// <returns></re

订单号的生成

订单号有3个属性:1.唯一性 2.不可推测性 3.效率性 唯一性是当中最重要的一个,重复了这个订单号就没有意义.其次就是效率性,反复查找数据库会生成的很慢! 不规则订单号生成思路:System.currentTimeMillis()+几位随机数,就OK了.System.currentTimeMillis()这个数一般是不会出现同一个的. 在一些公司的内部系统中可能会要求我们给出一个规则的顺序订单号,比如:年月日+(当前订单数+1),特殊字符串+(当前订单数+1).因为两个人同时操作时会是同一个订

生成26位唯一的订单号

/** * Note : 生成26位数字的唯一订单号 * Author : LMZ * Time : 2019/9/2 10:50 * @return string */ function create_order_sn(){ //date("Ymdhis") . sprintf("%08d", $user_id) . mt_rand(1000, 9999);//郝英晨的生成方法 $sn = date('Ymdhis') . substr(implode(null,

SQL Server生成指定范围内的随机数

在开发中很多时候,我们都会遇到这种需要生成一个指定范围随机数的情况.而且在很多语言中比如Java.C#.SQl等,都会有一个函数生成一个类似于0.234273983423789的随机小数,而所有的随机数都是通过这个最基本的随机数(0.234273983423789)变化过来的. 下面我说一下生成指定范围随机数的思路,比如我要生成一个100-999范围内的随机数,我就要保证我写的生成随机数的表达式所生成的值,最大是999,最小是100.还有就是要明白一个数学里的小道理,0.99去乘一个数字所得的结

shell 生成指定范围随机数与随机字符串 .

shell 生成指定范围随机数与随机字符串 分类:             shell              2014-04-22 22:17     20902人阅读     评论(5)     收藏     举报 shellrandomurandomuuidlinux shell 生成指定范围随机数与随机字符串 1.使用系统的 $RANDOM 变量 [plain] view plaincopyprint? [email protected]:~$ echo $RANDOM 17617 [

用SQL profiler工具抓指定表名的动态

note: 网上很少有人提到,我也记下. 用SQL profiler工具抓指定表名(单个表)的动态 1,选择textdata字段 2,筛选databasename. 3,筛选表名,注意前后%%号. 原文出处:http://blog.51cto.com/aizzw/803462 原文地址:https://www.cnblogs.com/HaiHong/p/9625514.html

Thinkphp 生成订单号小案例

Thinkphp 生成订单号小案例小伙伴们在日常的商城项目开发中,都会遇到订单号生成的问题,今天呢思梦PHP就带领大家去解读一下生成订单号的问题!首先,订单号我们要明确它有有3个性质:1.唯一性 2.不可推测性 3.效率性,唯一性和不可推测性不用说了,效率性是指不能频繁的去数据库查询以避免重复.况且满足这些条件的同时订单号还要足够的短.不知道小伙伴们在日常的项目中是否也和我一样去思考过生成订单的一些小问题,可能你也会说,这些东西不用想的那么复杂,其实呢,小编也是同意大家的看法,但是殊不知我们做程