MySQL实现序列(Sequence)效果以及在Mybatis中如何使用这种策略

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介:

前言:

在oracle中一般使用序列(Sequence)来处理主键字段,在MySQL中是没有序列的,但是MySQL有提供了自增长(increment)来实现类似的目的,但也只是自增,而不能设置步长、开始索引、是否循环等。最重要的是一张表只能设置一个字段使用自增,但有的时候我们需要两个或两个以上的字段实现自增(单表多字段自增),MySQL本身是实现不了的,但我们可以用创建一个序列表,使用函数来获取序列的值

一 MySQL中序列的实现

(1)新建一个测试表:

1
2
3
4
5
6
7
8
9
10
11
12
DROP  TABLE  IF EXISTS `article`;
CREATE  TABLE  `article` (
   `id`  int (11)  NOT  NULL ,
   ` name varchar (100)  DEFAULT  NULL ,
   `author`  varchar (50)  DEFAULT  NULL ,
   PRIMARY  KEY  (`id`)
) ENGINE=InnoDB  DEFAULT  CHARSET=utf8;
 
-- ----------------------------
-- Records of article
-- ----------------------------
INSERT  INTO  `article`  VALUES  ( '1' '程序猿的自我修养' 'zifangsky' );

注意,这里并没有设置主键自增

(2)添加序列表并添加测试数据:

1
2
3
4
5
6
7
8
9
10
11
12
DROP  TABLE  IF EXISTS ` sequence `;
CREATE  TABLE  ` sequence ` (
   `seq_name`  varchar (50)  NOT  NULL ,
   `current_val`  int (11)  NOT  NULL ,
   `increment_val`  int (11)  NOT  NULL  DEFAULT  '1' ,
   PRIMARY  KEY  (`seq_name`)
) ENGINE=InnoDB  DEFAULT  CHARSET=utf8;
 
-- ----------------------------
-- Records of board_event_success
-- ----------------------------
INSERT  INTO  ` sequence VALUES  ( 'seq_article' '0' '1' );
  • “seq_name”字段表示一个表的的序列,起名最好跟表的名字相关,并且每个表一条数据

  • “current_val”字段表示“seq_name”字段所对应的表的当前最大ID(主键ID)

  • “increment_val”字段表示“seq_name”字段所对应的表的主键ID增长的步长(也就是每次自增+1、+2等)

(3)创建一个用于获取一个表当前最大ID的函数:

1
2
3
4
5
6
7
8
9
10
11
DROP  FUNCTION  IF EXISTS `currval`;
DELIMITER ;;
CREATE  FUNCTION  `currval`(v_seq_name  VARCHAR (50))  RETURNS  int (11)
begin     
     declare  value  integer ;       
     set  value = 0;       
     select  current_val  into  value  from  sequence  where  seq_name = v_seq_name; 
    return  value; 
end
;;
DELIMITER ;

从代码可以看出,这个函数的逻辑很简单,就是根据“seq_name”查询“sequence”这个表的“current_val”这个字段的值

测试:

1
mysql>  select  currval( 'seq_article' );

很显然,现在输出为0

(4)创建一个用于获取一个表下一个ID的函数:

1
2
3
4
5
6
7
8
9
DROP  FUNCTION  IF EXISTS `nextval`;
DELIMITER ;;
CREATE  FUNCTION  `nextval`(v_seq_name  VARCHAR (50))  RETURNS  int (11)
begin
     update  sequence  set  current_val = current_val + increment_val  where  seq_name = v_seq_name;
     return  currval(v_seq_name);
end
;;
DELIMITER ;

这个函数的逻辑也很简单,先是更新“sequence”这个表中的某一个表的序列值,然后再次查询该序列值作为插入数据时的主键ID

测试:

1
mysql>  select  nextval( 'seq_article' );

很显然,执行这个函数的结果是1,同时“sequence”这个表中的对应的记录也增加了1

二 Mybatis中的序列使用

使用插件生成一个表对应的Mapper.xml文件时需要修改其生成策略,具体来说就是修改generatorConfig.xml文件,修改一个表的基本数据的生成策略:

1
2
3
4
< table  tableName = "article"  domainObjectName = "Article"  enableCountByExample = "false"  enableDeleteByExample = "false"  enableSelectByExample = "false"  enableUpdateByExample = "false" >
     < property  name = "ignoreQualifiersAtRuntime"  value = "false" />
     < generatedKey  column = "id"  sqlStatement = "select nextval('seq_article');" />
</ table >

然后运行插件,最后我们可以看到生成的insert方法是这样的:

1
2
3
4
5
6
7
8
9
   < insert  id = "insert"  parameterType = "cn.zifangsky.model.Article"  >
     < selectKey  resultType = "java.lang.Integer"  keyProperty = "id"  order = "BEFORE"  >
       select nextval('seq_article');
     </ selectKey >
     insert into article (id, name, author
       )
     values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{author,jdbcType=VARCHAR}
       )
   </ insert >

也就是说使用Mybatis插入数据时,它先是通过 nextval 函数查出待插入数据的主键ID之后,再进行数据的插入




本文转自 pangfc 51CTO博客,原文链接:http://blog.51cto.com/983836259/1889590,如需转载请自行联系原作者

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
2月前
|
缓存 关系型数据库 MySQL
降低MySQL高CPU使用率的优化策略。
通过上述方法不断地迭代改进,在实际操作中需要根据具体场景做出相对合理判断。每一步改进都需谨慎评估其变动可能导致其他方面问题,在做任何变动前建议先在测试环境验证其效果后再部署到生产环境中去。
121 6
|
3月前
|
缓存 关系型数据库 MySQL
在MySQL中处理高并发和负载峰值的关键技术与策略
采用上述策略和技术时,每个环节都要进行细致的规划和测试,确保数据库系统既能满足高并发的要求,又要保持足够的灵活性来应对各种突发的流量峰值。实施时,合理评估和测试改动对系统性能的影响,避免单一措施可能引起的连锁反应。持续的系统监控和分析将对维护系统稳定性和进行未来规划提供重要信息。
189 15
|
11月前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
581 66
|
2月前
|
缓存 关系型数据库 MySQL
MySQL数据库性能调优:实用技术与策略
通过秉持以上的策略实施具体的优化措施,可以确保MySQL数据库的高效稳定运行。务必结合具体情况,动态调整优化策略,才能充分发挥数据库的性能潜力。
137 0
|
4月前
|
SQL Java 数据库
解决Java Spring Boot应用中MyBatis-Plus查询问题的策略。
保持技能更新是侦探的重要素质。定期回顾最佳实践和新技术。比如,定期查看MyBatis-Plus的更新和社区的最佳做法,这样才能不断提升查询效率和性能。
179 1
|
11月前
|
缓存 关系型数据库 MySQL
MySQL执行计划选择策略:揭秘查询优化的艺术
【10月更文挑战第15天】 在数据库性能优化中,选择最优的执行计划是提升查询效率的关键。MySQL作为一个强大的关系型数据库管理系统,提供了复杂的查询优化器来生成执行计划。本文将深入探讨如何选择合适的执行计划,以及为什么某些计划更优。
359 2
|
6月前
|
关系型数据库 MySQL 大数据
大数据新视界--大数据大厂之MySQL 数据库课程设计:MySQL 数据库 SQL 语句调优的进阶策略与实际案例(2-2)
本文延续前篇,深入探讨 MySQL 数据库 SQL 语句调优进阶策略。包括优化索引使用,介绍多种索引类型及避免索引失效等;调整数据库参数,如缓冲池、连接数和日志参数;还有分区表、垂直拆分等其他优化方法。通过实际案例分析展示调优效果。回顾与数据库课程设计相关文章,强调全面认识 MySQL 数据库重要性。为读者提供综合调优指导,确保数据库高效运行。
|
9月前
|
监控 关系型数据库 MySQL
Aurora MySQL负载突增应对策略与优化方案
通过以上策略,企业可以有效应对 Aurora MySQL 的负载突增,确保数据库在高负载情况下依然保持高性能和稳定性。这些优化方案涵盖了从架构设计到具体配置和监控的各个方面,能够全面提升数据库的响应速度和处理能力。在实际应用中,应根据具体的业务需求和负载特征,灵活调整和应用这些优化策略。
167 22
|
9月前
|
关系型数据库 MySQL 中间件
MySQL 中如何实现分库分表?常见的分库分表策略有哪些?
在MySQL中,分库分表(Sharding)通过将数据分散到多个数据库或表中,以应对大量数据带来的性能和扩展性问题。常见策略包括:哈希分片(分布均匀,查询效率高)、范围分片(适合范围查询)、列表分片(适用于特定值查询)、复合分片(灵活性高)和动态分片(灵活应对负载变化)。每种策略各有优劣,需根据业务需求选择。常用工具如MyCAT、ShardingSphere和TDDL可简化实现过程。
|
10月前
|
缓存 NoSQL 关系型数据库
MySQL战记:Count( *)实现之谜与计数策略的选择
本文深入探讨了MySQL中`count(*)`的不同实现方式,特别是MyISAM和InnoDB引擎的区别,以及各种计数方法的性能比较。同时,文章分析了使用缓存系统(如Redis)与数据库保存计数的优劣,并强调了在高并发场景下保持数据一致性的挑战。
265 0
MySQL战记:Count( *)实现之谜与计数策略的选择

推荐镜像

更多