解决mysql的int型主键自增问题
作者:编程小龙 发布时间:2024-01-28 11:54:45
引入
我们在使用mysql数据库时,习惯使用int型作为主键,并设置为自增,这既能够保证唯一,使用起来又很方便,但int型的长度是有限的,如果超过长度怎么办呢?
暴露问题
我们先创建一个测试表,创建语句如下:
CREATE TABLE test1 (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
)
然后我们插入两条数据:
INSERT INTO test1 VALUES(NULL,'小牛');
INSERT INTO test1 VALUES(NULL,'大牛');
查询表显示正常:
int型的有符号的范围为231 -1 = 2147483647,我们直接插入一条数据id为2147483647,如下:
INSERT INTO test1 VALUES(2147483647 ,'小华')
结果显示正常:
此时自增ID已达到了int型的上限,如果我再插入数据,就会报错:
INSERT INTO test1 VALUES(NULL,'母牛');
此时主键已无法自增,插入的id仍然是2147483647,就违反了主键唯一的条件,所以报错。
解决问题
(1)使用更大的数据类型bigint
bigint的范围是263-1,所谓指数 * ,此时的大小达到了9,223,372,036,854,775,807的可怕量级,简单来说就是用bigint 一天100w条数据也得存200亿年才能自增 * ,所以在当前场景,几乎不用担心bigint会自增满
我们修改数据类型为bigint,如图
再执行插入语句:
INSERT INTO test1 VALUES(NULL,'母牛');
又能够正常插入了:
(2)使用UUID作为主键
我们都知道,UUID会根据当前系统性能,时间戳等一系列参数经过运算得到一个全世界唯一的字符串,并且mysql提供了生成UUID的方法,用它作为主键能够保证数据的唯一性。
利用如下代码可以生成32位的UUID:
-- 生成32位UUID
SELECT REPLACE(UUID(),'-','') AS UUID;
然后咱们再创建一个测试表:
CREATE TABLE test2(
id VARCHAR(50) PRIMARY KEY,
NAME VARCHAR(20) NOT NULL
)
插入一条数据:
-- 插入UUID
INSERT INTO test2 VALUES(REPLACE(UUID(),'-',''),'老王');
但这样写插入语句每次都要手写UUID函数,貌似有点太麻烦了,咱们可以写一个触发器,让触发器自动为我们设置ID:
-- 创建触发器
DELIMITER $$
CREATE
TRIGGER auto_id -- 名称
BEFORE INSERT -- 触发时机
ON test2 FOR EACH ROW -- 作用于test2表,对每行数据生效
BEGIN
IF new.id = '' THEN -- 当id为空字符串时设置UUID
SET new.id = REPLACE(UUID(),'-','');
END IF;
END$$
插入一条数据:
-- 插入一条数据
INSERT INTO test2 VALUES('','小王');
结果能正常添加
总结
(1) 用int型和bigInt型增删改查速度较UUID更快,并且更节省空间。
(2) 用UUID更方便。
为何要使用自增int作为主键
相信大家都知道要使用无符号自增int作为主键的数据类型,可你知道为何要使自用增int而不是使用varchar、text、varchar等类型吗?
大家也能说出一些优点:对上层业务透明,插入数据时无需显示指定;数据类型简单,更便于存储维护表结构
其实,使用自增int作为主键好处多多,今天我们就来一起学习一下,并强烈建议大家在实际开发中使用自增int作为主键。
优点:
1、int 相比varchar、char、text使用更少的存储空间,而且数据类型简单,可以节约CPU的开销,更便于表结构的维护
2、默认都会在主键上建立主键索引,使用整形作为主键可以将更多的索引载入内存,提高查询性能
3、对于InnoDB存储引擎而言,每个二级索引都会使用主键作为索引值的后缀,使用自增主键可以减少索引的长度(大小),方便更多的索引数据载入内存
4、可以使索引数据更加紧凑,在数据插入、删除、更新时可以做到索引数据尽可能少的移动、分裂页,减少碎片的产生(可以通过optimize table 来重建表),减少维护开销
5、在数据插入时,可以保证逻辑相邻的元素物理也相邻,便于范围查找
当然,使用自增int作为主键也不是百利无一害,在高并发的情况下也可能会造成锁的争用问题。
来源:https://blog.csdn.net/qq_42365534/article/details/108088835
猜你喜欢
- 一个小的解决方法分享:正常安装的情况下,你所需要的包都能在python文件夹下找到,找到你所需要的包 ,把它复制到Python35\Lib\
- str='python String function'生成字符串变量str='python String func
- 前言博主参与过大大小小十次数学建模比赛,也获得了不少建模奖项。对于一些小批量样本数据去做预测或者是评估其规律性的话,比较适合的模型一般都是选
- Python程序中,在进程和进程之间是不共享全局变量的数据的。我们来看一个例子:from multiprocessing import Pr
- 例如我们有如下结构的文件:pkg/ __init__.py libs/ some_lib.py __init__.py components
- 问题背景在项目开发过程中,我遇到一个需求:对于某条记录,一个用户对它进行操作时会持续比较久,希望在一个用户的操作期间,不允许有另一个用户操作
- 提到分发请求,相信大多数人首先会想到Nginx,Nginx作为一种多功能服务器,不仅提供了反向代理隐藏主机ip的能力,还拥有简单的缓存加速功
- 本文实例讲述了Python 静态方法和类方法。分享给大家供大家参考,具体如下:1. 类属性、实例属性它们在定义和使用中有所区别,而最本质的区
- 实验室老师让给数据画一张线性拟合图。不会matlab,就琢磨着用python。参照了网上的一些文章,查看了帮助文档,成功的写了出来这里用到了
- 这篇文章主要介绍了基于python实现文件加密功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可
- 对python3下的requests使用并不是很熟练,今天稍微用了下,请求几次下来后发现出现连接超时的异常,上网查了下,找到了一个还算中肯的
- Web应用中大多会提供静态文件服务以便给用户更好的访问体验。静态文件主要包含CSS样式文件,js脚本,图片和字体等。Flask也支持静态文件
- 点云生成 3D 网格的最快方法已经用 Python 编写了几个实现来从点云中获取网格。它们中的大多数
- 说明相应的学习视频见链接,本文只对重点进行总结。多进程重点(只要看下面代码的main函数即可)1.创建2.如何开守护进程3.多进程,开销大,
- 写在前面题目所说的并不是目的,主要是为了更详细的了解网站的反爬机制,如果真的想要提高博客的阅读量,优质的内容必不可少。了解网站的反爬机制一般
- 1、字典中的键存在时,可以通过字典名+下标的方式访问字典中改键对应的值,若键不存在则会抛出异常。如果想直接向字典中添加元素可以直接用字典名+
- iterator循环器(iterator)是对象的容器,包含有多个对象。通过调用循环器的next()方法 (next()方法,在Python
- python 统计代码行数简单实例送测的时候,发现需要统计代码行数于是写了个小程序统计自己的代码的行数。#calclate_co
- Series对象和DataFrame的列数据提供了cat、dt、str三种属性接口(accessors),分别对应分类数据、日期时间数据和字
- Flask file upload代码import osfrom flask import Flask, request, re