随着微服务框架的逐步应用,分布式ID生成策略要支持高并发、有序性、易读性。常用方案有UUID、GUID、Redis、MongoDB等,本次只提供数据库生成方式。作为平台框架基于适配原则提供数据库层面的选择,以下为具体的设计。
可适用于ID持续增长,固定编码长度,不足补零。
可适用于每天、每月、每年阶段性的清零自增长。
可指定编码的前缀、后缀。
阶段性的清零操作无需定时任务。
创建表结构
CREATE TABLE `tb_ids` (
`ID` int(11) DEFAULT NULL COMMENT '编码',
`object` varchar(100) DEFAULT NULL COMMENT '对象',
`segment` varchar(100) DEFAULT NULL COMMENT '切分段落',
`prefix` varchar(10) DEFAULT NULL COMMENT '前缀',
`format` varchar(50) DEFAULT NULL COMMENT '段落格式',
`length` int(11) DEFAULT NULL COMMENT '数字长度',
`sequence` int(11) DEFAULT NULL COMMENT '当前序列',
`suffix` varchar(10) DEFAULT NULL COMMENT '后缀',
`type` int(11) DEFAULT NULL COMMENT
@Resource(name = "dashboardTemplate") protected JdbcTemplate systemJDBCTemplate;
//这个是Dao里面的实现方法
public Long insertAndGetKey(final Topic topic) { KeyHolder keyHolder = new Generate...
myBatis对于Integer类型传0问题
最近碰到一个特别奇葩的问题就是在MyBatis使用的时候,修改为Integer类型的字段传0步修改的问题,记录一下,以后别忘记了
原因就是:我们传0的时候默认的给我们解析成 “” (空字符串)了。在我们xml中判断的时候直接条件拦截
<if test="num!=null and ''!=num">
AND s.num= #{num}
解决办法,就是把判断空字符串去掉就可以了
这个写法很巧妙,使用了
mysql
的ON DUPLICATE KEY UPDATE的语法,首次insert,后续每次都是在当前值的基础上update。当然,使用数据库
生成
唯一
ID
的方式是有缺陷的,它只适用于单库,如果分了库,就做不到全系统唯一,只能用雪花算法了。基于数据库
生成
唯一
ID
有很多手段:oracle有funcNextval等
函数
,也可以用自增列。其中,category参数代表一种业务类别,num是该次
生成
唯一
ID
的个数。前者依赖于oracle,后者不通用,一张表只能
生成
一种业务的唯一
ID
。
最近和Sobin在做一个精品课程的项目,因为用到一个固定的
id
作为表间关联,所以在前一个表插入数据后要把插入数据
生成
的自增
id
传递给下一个表。研究了一番决定使用
Mysql
提供了一个LAST_INSERT_
ID
()的
函数
。
代码如下:
LAST_INSERT_
ID
() (with no argument) returns the first automatically generated value that was set for an AUTO_INCREMENT column by the most recently executed INSERT or UPDATE statement
现在大多数的数据库引擎用的是InnoDB,他底层数据结构是B+tree形式,而B+tree的这种数据结构是以主键索引组织我们表的数据,如果没有设置主键
Mysql
会自己为该表
生成
一组隐藏的整型的自增的列作为该表的索引,这样就会造成不必要的效率低下,所以建议以后:
1、设计表时必须设置主键
id
;
2、主键
id
最好是int类型(整型)并且自增;
这样就会大大提高数据库查询速度。
密码:xxxx@PasswOrdD8mi
docker run --name
mysql
-p 3306:3306 -v /light/
mysql
/conf:/etc/
mysql
/conf.d -v /light/
mysql
/data:/var/lib/
mysql
-e
MYSQL
_ROOT_PASSWORD=x
生产系统随着业务增长总会经历一个业务量由小变大的过程,可扩展性是考量数据库系统高可用性的一个重要指标;在单表/数据库数据量过大,更新量不断飙涨时,
MySQL
DBA往往会对业务系统提出sharding的方案。
首先根据长度需求通过java的随机
函数
java.util.Random
生成
随机数,如希望得到5位随机
id
,则可以使用如下语句int r = (new Random()).nextInt()%89999;int
id
= 10000 + Math.abs(r);第二步,检查数据库内是否已经存在该
id
。可以通过查询该
id
是否有结果来判断。如果不存在则直接插入,否则重新
生成
随机数。以下为完整代码:pub...
DROP TABLE IF EXISTS sequence;
-- 建sequence表,指定seq列为无符号大整型,可支持无符号值:0(default)到18446744073709551615(0到2^64–1)。
CREATE TABLE sequence (
name VARCHAR(50) NOT NULL,
生产系统随着业务增长总会经历一个业务量由小变大的过程,可扩展性是考量数据库系统高可用性的一个重要指标;在单表/数据库数据量过大,更新量不断飙涨时,
MySQL
DBA往往会对业务系统提出sharding的方案。既然要sharding,那么不可避免的要讨论到sharding key问题,在有些业务系统中,必须保证sharding key全局唯一,比如存放商品的数据库等,那么如何
生成
全局唯一的
ID
呢,下...
数据库自增
ID
基于
MySQL
,最简单的方法是使用auto_increment 来
生成
全局唯一递增
ID
,但最致命的问题是在高并发情况下,数据库压力大,DB单点存在宕机风险。
数据库多主模式
针对上面方式的缺点,我们可以使用数据库主从模式来做高可用方面的优化,比如双主模式,两个
MySQL
设置不同的初始值及步长:
MySQL
1:
set @@auto_increment_offset = 1; ...
在数据库设计中,我们经常使用代理键使用AUTO_INCREMENT属性为主键列
生成
唯一的整数值。
当您将新行插入到具有AUTO_INCREMENT列的表中时,
MySQL
会自动
生成
一个唯一的整数,并将其作为主键列的值。
有关如何设置列的AUTO_INCREMENT属性的更多信息,请查...
1.主键自增类型问题:int、bigint:
有符号int最大约22亿,远大于一般业务需求了和
MySQL
单表所能支持的性能上限,其实主键达到20多亿时应该去考虑分库分表了,如果要加大预留量,可以把主键改为改为无符号int(int unsigned)上限约为42亿,这个预留量已经是非常的充足了;使用bigint,会占用更大的磁盘和内存空间,内存空间毕竟有限,无效的占用会导致更多的数据换入换出,额外增加了IO的压力,对性能是不利的。但也不是绝对的考虑到 int 自增存在有大量删除测试数据或删除历...