[DB][MySql]关于取得自增字段的值、及@@IDENTITY 与并发性问题
对于刚从Oracle转向MySql的人都会为,MySql中没有Oracle里的Sequence而感到困惑。MySql中没有了Sequence,那么MySql的主键用什么方式来实现最好呢?
主要有下面几种方式:
1、自增字段作为主键。
【推荐方案】
MySql尽管比Oracle少了Sequence,可是多了字段的自增长特性。
插入完了以后能够通过运行【SELECT @@IDENTITY】获取上一条插入语句中生成的自增长字段的值。
这个语句非常特别,没有关联到特定的SQL语句,会 让人感觉迷糊,他究竟是怎么获取值的。在并发情况下会不会获取其它线程运行后的值。
答案是有可能的,可是不用怕、是可控的。仅仅有不当的编码才会导致取到其它线程的值。先来说一下原理:
SUMMARY
The Jet OLE DB version 4.0 provider supports the SELECT @@Identity query that allows you to retrieve the value of the auto-increment field generated on your connection. Auto-increment values used on other connections to your database do not affect the results of this specialized query. This feature works with Jet 4.0 databases but not with older formats.
大致意思是【SELECT @@IDENTITY】获取的是当前数据库连接的前一次运行的值。其它连接运行的值不会影响当前线程。时下流行的框架(如Spring-jdbc、mybatis、hibernate)的数据库连接都是存在ThreadLocal中的、是线程隔离的,所以不会获取到其它线程中的【SELECT @@IDENTITY】值。
当多线程编程时、强制把数据库连接传给各个线程同一时候运行时才会取到其它线程的【SELECT @@IDENTITY】。
2、在MySql中模拟Sequence
第一步:创建--Sequence 管理表
DROP TABLE IF EXISTS sequence;
CREATE TABLE WFO_SEQ(
name VARCHAR(50) NOT NULL,
current_value INT NOT NULL,
increment INT NOT NULL DEFAULT 1,
PRIMARY KEY (name)
) ENGINE=InnoDB;
第二步:创建--取当前值的函数
DROP FUNCTION IF EXISTS currval;
DELIMITER $
CREATE FUNCTION currval (seq_name VARCHAR(50))
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE value INTEGER;
SET value = 0;
SELECT current_value INTO value
FROM WFO_SEQ
WHERE name = seq_name;
RETURN value;
END
$
DELIMITER ;
第三步:创建--取下一个值的函数
DROP FUNCTION IF EXISTS nextval;
DELIMITER $
CREATE FUNCTION nextval (seq_name VARCHAR(50))
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE C_V INTEGER; UPDATE WFO_SEQ SET CURRENT_VALUE = CURRENT_VALUE + INCREMENT WHERE NAME = SEQ_NAME; SET C_V = CURRVAL(SEQ_NAME);
IF C_V = -1 THEN
INSERT INTO WFO_SEQ(NAME, CURRENT_VALUE, INCREMENT)
VALUES(SEQ_NAME, 1, 1);
RETURN 1;
END IF;
RETURN C_V;
END
$
DELIMITER ;
第四步:创建--更新当前值的函数
DROP FUNCTION IF EXISTS setval;
DELIMITER $
CREATE FUNCTION setval (seq_name VARCHAR(50), value INTEGER)
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
UPDATE WFO_SEQ
SET current_value = value
WHERE name = seq_name;
RETURN currval(seq_name);
END
$
DELIMITER ;
第五步:測试函数功能
SELECT SETVAL('TestSeq',
10);---设置指定sequence的初始值
SELECT CURRVAL('TestSeq');--查询指定sequence的当前值
SELECT NEXTVAL('TestSeq');--查询指定sequence的下一个值
[DB][MySql]关于取得自增字段的值、及@@IDENTITY 与并发性问题的更多相关文章
- MySQL 自增字段取值
1 前言 本文来自回答思否网友的一个问题,这个网友新建了一张表,auto_increment_increment设为10,AUTO_INCREMENT主键起始值设为9, 当他插入数据的时候,发现主键值 ...
- 使用pymysql循环删除重复数据,并修改自增字段偏移值
创建表: CREATE TABLE `info` ( `id` tinyint NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, PRIMAR ...
- mysql 约束条件 auto_increment 自动增长 修改自增字段起始值
创建一张表 t20 mysql) ); Query OK, rows affected (0.01 sec) mysql> desc t20; +-------+----------+----- ...
- PowerDesigner Mysql 主键自增、初始值、字符集
自增 在你所要设为自增型的键上(比如你的id)双击,弹出一个Column Properties对话框,右下角有一个Identify的选择框,选中它OK,就可以了. 再去查看Preview,就能看到AU ...
- MySQL数据库中,将一个字段的值分割成多条数据显示
本文主要记录如何在MySQL数据库中,将一个字符串分割成多条数据显示. 外键有时是以字符串的形式存储,例如 12,13,14 这种,如果以这种形式存储,则不能直接与其他表关联查询,此时就需要将该字段的 ...
- postgresql自增字段初始值的设定
在实际开发中会有这样的需求,想要自己设置表中自增字段的初始值. 比如:有一个your_table表中有一个自增字段id,我们知道,插入数据后,默认是从1开始自增的. 但是假如现在有一个需求,是要求id ...
- MySQL 插入与自增主键值相等的字段 与 高并发下保证数据准确的实验
场景描述: 表t2 中 有 自增主键 id 和 字段v 当插入记录的时候 要求 v与id 的值相等(按理来说这样的字段是需要拆表的,但是业务场景是 只有某些行相等 ) 在网上搜的一种办法是 先获取 ...
- MyBatis insert后返回自增字段的值
如下情况适用支持自增的DB,如MySQL.其他情况参见:MyBatis魔法堂:Insert操作详解(返回主键.批量插入) 1.model public class UserInfo { private ...
- mysql中如何更新一个字段的值为它本身的值连接上一个字符串
CONCAT(str1,str2,...) 返回结果为连接参数产生的字符串. 如有任何一个参数为NULL ,则返回值为 NULL. 或许有一个或多个参数. 如果所有参数均为非二进制字符串,则结 ...
随机推荐
- Fiddler——抓包工具的使用
fiddler安装 pc端安装fiddler,自行从百度下载即可 Fiddler是强大且好用的Web调试工具之一,它能记录客户端和服务器的http和https请求,允许你监视,设置断点,甚至修改输入输 ...
- DeepMind:所谓SACX学习范式
机器人是否能应用于服务最终还是那两条腿值多少钱,而与人交互,能真正地做"服务"工作,还是看那两条胳膊怎么工作.大脑的智能化还是非常遥远的,还是先把感受器和效应器做好才是王道. 关于 ...
- (转)版本管理工具介绍——SVN篇(一)
http://blog.csdn.net/yerenyuan_pku/article/details/72620101 SVN是何物 SVN是Subversion的简称,是一款集中式的开源版本控制系统 ...
- [Tensorflow] 使用 model.save_weights() 保存 Keras Subclassed Model
import numpy as np import matplotlib.pyplot as plt import os import time import tensorflow as tf tf. ...
- C++ Error C2662 cannot convert 'this' pointer from 'const *'
---恢复内容开始--- 这个错误在于一点:常量对象只能调用常量成员(函数\变量),不能调用非常量成员.另一方面,非常量对象,既可以调用常量成员,又可以调用非常量成员. class A { publi ...
- 深入分析同步工具类之AbstractQueuedSynchronizer
概览: AQS(简称)依赖内部维护的一个FIFO(先进先出)队列,可以很好的实现阻塞.同步:volatile修饰的属性state,哪个线程先改变这个状态值,那么这个线程就获得了优先权,可以做任何事 ...
- Scrapy用Cookie实现模拟登录
模拟登录是爬取某些站点内容的一个关键,有些网站(特别是论坛类),不登录的话,一个数据也拿不到. 模拟登录有这样几个关键: 弄清楚登录的url一些网站打开出现登录的页面,地址栏大多数不是登录提交表单的u ...
- linux tload-显示系统负载状况
推荐:更多linux 性能监测与优化 关注:linux命令大全 tload命令以图形化的方式输出当前系统的平均负载到指定的终端.假设不给予终端机编号,则会在执行tload指令的终端机显示负载情形. 语 ...
- swoft| 源码解读系列二: 启动阶段, swoft 都干了些啥?
date: 2018-8-01 14:22:17title: swoft| 源码解读系列二: 启动阶段, swoft 都干了些啥?description: 阅读 sowft 框架源码, 了解 sowf ...
- 【Codeforces 159B】Matchmaker
[链接] 我是链接,点我呀:) [题意] 笔和笔盖 笔有颜色和直径 笔盖也有颜色和直径 笔盖和笔如果直径相等 那么称为good 如果笔盖和笔直径相等.颜色也相等,那么称为very good 问你怎样安 ...