大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
SQL server中可以用sequence来实现订单号的自动生成。
创新互联建站是专业的淄博网站建设公司,淄博接单;提供成都网站设计、网站建设,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行淄博网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
例如创建如下序列:
create sequence orderSeq
as bigint --数据类型
start with 100000 --开始值
increment by 1 --增量
minvalue 1 --最小值
maxvalue 1000000--最大值
no cycle --不循环
cache 3 --设置cache大小为3
这样订单号就会从100000开始每次自增1生成。
由于我在工作中遇到这个问题,借此与大家分享一下各大电子商务网站订单号的生成方式。
订单号概念
它是您在购物网站购物后获得的订单号,记录的是购物订单信息。
作用
在您需要与购物网站进行订单查询等操作时,需要给购物网站提供商家订单号。
几种下单途径?
web网站下单
打电话到呼叫中心(CallCenter)下单
手机wap下单
如果采用单数据库来存储的话,随着订单量的增加,单库的写压力增大,造成数据库服务器性能下降。一般会采用分库来缓解数据库服务器的压力。
那么怎么来进行分库呢?
web来源订单,存入web订单库。
CallCenter来源订单,存入CallCenter订单库。
wap来源订单,存入wap订单库。
最终,将这三种类型的数据库同步到订单主库中。
问题来了,怎么把不同的订单同步到订单主库呢?
电商网站一般利用订单号来作为订单表的主键。因此,我们必须保证订单号不重复,才能将订单安全的同步到订单主库中。
订单命名规定唯一性
这个大家都明白,主要保证订单号不重复。
安全性
订单编号不能透露你公司的真实运营信息,比如你的订单就是流水号的话,那么别人就可以从订单号推测出你公司的整体运营概括了。所以订单编码必须是除了你们公司少部分人外,其他人基本看不懂的。可以参考京东和淘宝的编码规则。
不能使用大规模随机码
因为大规模的随机码随机生成,因为本身就没有意义所以无所谓泄密了。但是事实上这种编码规则在实现上会有很大问题的。随机码满足第二点安全性要求,为了满足唯一性,那就得在生成随机码的时候对比历史数据是否有重复,如果你的订单数量到达了十万次,你每次生成订单编码时就得对比十万条历史数据。
随机码就不能在编码中使用了吗?小规模的随机码是可以使用的,比如2~3位,这种随机码一般都是和流水号等结合使用,主要作用是为了隐藏流水号的真实数据而进行使用的。
防止并发
主要针对编码中有时间的设定。
控制位数
订单号的作用就是便于查询。一般正常使用场景应该是订单出异状或者退货的时候,用户将订单号报给客服,由客服进行查询。所以一般在10~15位为好。目前京东11位,淘宝16位。
怎么保证订单号的唯一性订单号命名规则来生成
比如“业务编码 + 时间戳 + 机器编号[前4位] + 随机4位数 + 毫秒数”。
说明:业务编码(OrderType: Web=1 CallCenter=2 Wap=3) 机器编号(用来表示由那台服务器生成的订单)
伪代码如下:
缺点:这种方式在高并发下会频繁更新订单量记录表,很容易产生锁表。但是锁表问题也是可以解决的,加一层缓存。
全局订单号数据池来生成
数据库创建一个订单号数据库表(order_id_generator);利用python脚本生成一批订单号,将这批订单号存入到order_id_generator表中。生成订单时,会首先调用事务GET_ORDER_ID_FOR_REGISTER,获得当前订单号,再生成订单。这样就保证了子库订单号不会重复。
数据库代码如下:
伪代码如下:
总结
订单号的生成方案,需要根据目前的订单量而定;因为各种方案都有各自的使用场景。
首先,订单号有3个性质:1.唯一性 2.不可推测性 3.效率性
唯一性和不可推测性不用说了,效率性是指不能频繁的去数据库查询以避免重复。
况且满足这些条件的同时订单号还要足够的短。
我在java下定制的订单号生成方式如下:
int r1=(int)(Math.random()*(10));//产生2个0-9的随机数
int r2=(int)(Math.random()*(10));
long now = System.currentTimeMillis();//一个13位的时间戳
String paymentID =String.valueOf(r1)+String.valueOf(r2)+String.valueOf(now);// 订单ID
目前规则来看,两个人在同一微秒提交订单重复的概率为1%
订单效果:251393292999921
望采纳!
这个只能程序做的。数据库只提供了数据的插入,修改,删除和查询等操作,没有提供完备的计算功能
Getkey(tableName)就是调用存错过程GetID的方法,@Size是固定的还是应该作为参数传进来?
用存储过程生成流水号是很常用的,这里以生成订单编号的流水号作为示例。(新的一天的流水号从1开始,如:今天的订单编号是CD2013010900014,下一个订单编号将是CD2013010900015;明天的订单编号将从CD2013011000001开始)
生成规则:2位前缀+年月日+5位流水号 或者 2位前缀+年月日时分+5位流水号 或者 2位前缀+年月日时分秒+5位流水号。
测试订单表(test_orders):
[sql] view plain copy
CREATE TABLE `test_orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`orderNo` varchar(25) NOT NULL DEFAULT '',
`orderName` char(10) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=76 DEFAULT CHARSET=utf8
生成订单编号的存储过程(generate_orderNo):
[sql] view plain copy
CREATE DEFINER=PROCEDURE `generate_orderNo`(in orderNamePre char(2), in num int, out newOrderNo varchar(25))
BEGIN
DECLARE currentDate varCHAR (15) ;-- 当前日期,有可能包含时分秒
DECLARE maxNo INT DEFAULT 0 ; -- 离现在最近的满足条件的订单编号的流水号最后5位,如:SH2013011000002的maxNo=2
-- DECLARE l_orderNo varCHAR (25) ;-- 新生成的订单编号
-- DECLARE oldDate DATE ;-- 离现在最近的满足条件的订单编号的日期
DECLARE oldOrderNo VARCHAR (25) DEFAULT '' ;-- 离现在最近的满足条件的订单编号
if num = 8 then -- 根据年月日生成订单编号
SELECT DATE_FORMAT(NOW(), '%Y%m%d') INTO currentDate ;-- 订单编号形式:前缀+年月日+流水号,如:SH2013011000002
elseif num = 14 then -- 根据年月日时分秒生成订单编号
SELECT DATE_FORMAT(NOW(), '%Y%m%d%H%i%s') INTO currentDate ; -- 订单编号形式:前缀+年月日时分秒+流水号,如:SH2013011010050700001,个人不推荐使用这种方法生成流水号
else -- 根据年月日时分生成订单编号
SELECT DATE_FORMAT(NOW(), '%Y%m%d%H%i') INTO currentDate ;-- 订单形式:前缀+年月日时分+流水号,如:SH20130110100900005
end if ;
SELECT IFNULL(orderNo, '') INTO oldOrderNo
FROM test_orders
WHERE SUBSTRING(orderNo, 3, num) = currentDate
AND SUBSTRING(orderNo, 1, 2) = orderNamePre
and length(orderNo) = 7 + num
ORDER BY id DESC LIMIT 1 ; -- 有多条时只显示离现在最近的一条
IF oldOrderNo != '' THEN
SET maxNo = CONVERT(SUBSTRING(oldOrderNo, -5), DECIMAL) ;-- SUBSTRING(oldOrderNo, -5):订单编号如果不为‘‘截取订单的最后5位
END IF ;
SELECT
CONCAT(orderNamePre, currentDate, LPAD((maxNo + 1), 5, '0')) INTO newOrderNo ; -- LPAD((maxNo + 1), 5, '0'):如果不足5位,将用0填充左边
INSERT INTO test_orders (orderNo, orderName) VALUES (newOrderNo, 'testNo') ; -- 向订单表中插入数据
-- set newOrderNo = l_orderNo;
SELECT
newOrderNo ;
END
参数说明:orderNamePre:(输入)订单编号的前缀,这里设定为两个字符
num:(输入)将按什么规则生成流水号(生成规则有:年月日、年月日时分秒、年月日时分三种),可选的num有:8、12、14
newOrderNo:(输出)新生成的订单编号
生成中的一些说明在存储过程中已经写得很明确了,这里不再重复。
调用存储过程向表中插入数据:
[sql] view plain copy
SET @orderNo = '';
CALL `generate_orderNo`('SH', 12, @orderNo);
SELECT @orderNo;