一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
1. MySQL字段自增
在使用MySQL数据库的时候,如果需要某一列的整型数字有序递增。就可以使用MySQL的自增列。该列的值可由 MySQL 服务器自动生成,并且是一个按升序增长的正整数序列。自增列能够被用来为表的新行产生唯一的标识。自增列的特点:
- 自增列不能使用全部的数据类型,它只适用于整数或者浮点数类型,包括:
TINYINT
,SMALLINT
,INT
,MEDIUMINT
,BIGINT
,DECIMAL
,FLOAT
,DOUBLE
。字符类型不适用 - 自增必须是主键或者唯一键,并且每一张表只能存在一个自增列。(如果用来做分布式ID生成器主键居多)
- 自增的初始值是1
2. 自增ID如何作为分布式ID生成器
基于MySQL数据的 AUTO_INCREMENT
自增的ID可以充当分布式ID生成器,具体实现如下:
单独建一张表来生成ID,表如下:
CREATE TABLE `distributed_id_generator` (
`id` bigint NOT NULL AUTO_INCREMENT,
`desc` varchar(255) NULL DEFAULT '' COMMENT '说明',
PRIMARY KEY (`id`)
);
复制代码
每次往表中插入一条数据,然后获取到数据返回的ID,这个ID就是全局唯一的ID。
Tips: ID生成并发的保证是由MySQL保证
3. 基于mysql实现
@Service
public class DistributedIdGeneratorService {
@Autowired
private DistributedIdGeneratorDao dao;
public long generatorId() {
DistributedIdGeneratorEntity entity = new DistributedIdGeneratorEntity();
dao.insertDistributedIdGenerator(entity);
return entity.getId();
}
}
public interface DistributedIdGeneratorDao {
Long insertDistributedIdGenerator(@Param("entity") DistributedIdGeneratorEntity entity);
}
复制代码
mybatis的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.github.mxsm.mysql.dao.DistributedIdGeneratorDao">
<insert id="insertDistributedIdGenerator" keyProperty="id" useGeneratedKeys="true" parameterType="com.github.mxsm.mysql.entity.DistributedIdGeneratorEntity">
insert into distributed_id_generator (remark) values (#{entity.remark})
</insert>
</mapper>
复制代码
这样就完成了实现。
Tips:代码地址github.com/mxsm/distri…
4.优缺点
优点:
- 实现简单,主要是由MySQL来实现
- 并发控制无需开发者自己实现,MySQL提供并发控制保证生成的ID唯一性
缺点:
- 并发取决于MySQL数据库,MySQL数据库不能通过集群部署来提高并发。
- 使用一段时间后,作为生成ID的表的数据会上升,表中的数据达到一定量级后会影响性能。作为ID生成器的表无法进行分库分表
- 一旦MySQL数据库不能使用,整个ID生成器就无法进行工作。所以保证数据库的安全运行是使用这个方案生成的关键(主从模式)。
Tips: 对于数据库的表数据过多,可以使用定时任务对数据进行清理
5. 总结
使用MySQL的 AUTO_INCREMENT
来实现分布式ID生成器,性能瓶颈主要在MySQL上面。如果对于并发要求不高可以使用这种方式来实现。只需要保证MySQL数据库能够正常工作(例如主从的模式)。
我是蚂蚁背大象,文章对你有帮助点赞关注我,文章有不正确的地方请您斧正留言评论~谢谢