mysql主键什么情况用uuid(Mysql主键UUID和自增主键的区别及优劣分析)
mysql主键什么情况用uuid
Mysql主键UUID和自增主键的区别及优劣分析引言
之前有段时间用postgresql 数据库,在上云之后,从自增主键变为uuid,感觉uuid全球唯一,很方便。
最近用mysql,发现mysql主键都是选择自增主键,仔细比较一下,为什么mysql选择自增主键,有什么不同。
在mysql5.0之前,如果是多个master复制的环境,无法用自增主键,因为可能重复。在5.0以及之后的版本通过配置自增偏移量解决了整个问题。
什么情况下我们希望用uuid
1. 避免重复,便于scale,这就是我们做cloud service的时候选择uuid的主要原因
2. 入库之前可以知道id
3.相对安全,不能简单的从uuid获取信息,但是如果自增,则容易暴露信息,如果一个客户id是123456,很容易猜到有客户id是123456.
UUID有什么问题
1.uuid有16个字节,比int(4 byte)和bigint(8 byte)占用更多存储空间
2.由于size和无序性,可能引起性能问题
Mysql的uuid原理
mysql的innodb存储引擎处理storage的方式是靠聚集索引。
聚集索引是指数据库表行中数据的物理顺序与键值的逻辑(索引)顺序相同。一个表只能有一个聚集索引,因为一个表的物理顺序只有一种情况
1.为什么要使用uuid做主键
(1).其实在innodb存储引擎下,自增长的id做主键性能已经达到了最佳。不论是存储和读取速度都是最快的,而且占的存储空间也是最小。
(2).但是在我们实际到项目中会碰到问题,历史数据表的主键id会与数据表的id重复,两张自增id做主键的表合并时,id一定会有冲突,但如果各自的id还关联了其他表,这就很不好操作。
(3).如果使用UUID,生成的ID不仅是表独立的,而且是库独立的。对以后的数据操作很有好处,可以说一劳永逸。
2.UUID优缺点
缺点: 1. 影响插入速度, 并且造成硬盘使用率低
2. uuid之间比较大小相对数字慢不少, 影响查询速度。
3. uuid占空间大, 如果你建的索引越多, 影响越严重
优点:出现数据拆分、合并存储的时候,能达到全局的唯一性
3.最优方案
(1).InnoDB引擎表是基于B+树的索引组织表。
(2).B+树:B+树是为磁盘或其他直接存取辅助设备而设计的一种平衡查找树,在B+树中,所有记录节点都是按键值的大小顺序存放在同一层的叶节点中,各叶节点指针进行连接。
(3).InnoDB主索引:叶节点包含了完整的数据记录。这种索引叫做聚集索引。InnoDB 的索引能提供一种非常快速的主键查找性能。不过,它的辅助索引也会包含主键列,所以,如果主键定义的比较大,其他索引也将很大。如果想在表上定义 、很多索引,则争取尽量把主键定义得小一些。InnoDB 不会压缩索引
(4).聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。
综合上述可得:
(1).如果InnoDB表的数据写入顺序能和B+树索引的叶子节点顺序一致的话,这时候存取效率是最高的。为了存储和查询性能应该使用自增长id做主键。
(2).对于InnoDB的主索引,数据会按照主键进行排序,由于UUID的无序性,InnoDB会产生巨大的IO压力,此时不适合使用UUID做物理主键,可以把它作为逻辑主键,物理主键依然使用自增ID。为了全局的唯一性,应该用uuid做索引关联其他表或做外键。
4.如果非要使用uuid做主键,下面是小建议:
如果是主从即M-S模式,最好是不使用mysql自带函数uuid来生成唯一主键,因为主表生成的uuid要再关联从表时,需要再去数据库查出这个uuid,需要多进行一次数据库交互,而且在这个时间差里面主表很有可能还有数据生成,这样就很容易导致关联的uuid出错。如果真要使用uuid,可以在Java中生成后,直接存储到DB里,这时主从的uuid就是一样的了!
补充:mysql的uuid()主键重复
1、mysql的uuid()主键重复
mysql使用了navicat客户端,某次执行了如下sql
|
select replace (uuid(), '-' , '' ) as id, u.user_id from t_user u; |
结果发现,生成的uuid重复了,
经过排查,发现是navicat的问题,需要将该sql语句做如下调整:
|
select replace ( convert (uuid() using utf8mb4), '-' , '' ), u.user_id from t_user u; |
结果如下:
2、使用其他方案:
将uuid再进行一次md5:
|
select md5(uuid()) as id, u.user_id from t_user u; |
以上为个人经验,希望能给大家一个参考,也希望大家多多支持开心学习网。如有错误或未考虑完全的地方,望不吝赐教。
原文链接:https://blog.csdn.net/qq_39454048/article/details/82378155
- mysql的存储方法(MySQL中的binary类型使用操作)
- zabbix如何配置监控(zabbix监控mysql的实例方法)
- 软件测试常用mysql语句(MySQL压力测试工具Mysqlslap的使用)
- mysql8.0查询操作(MySQL 8.0 redo log的深入解析)
- mysql的三大组件(详解MySQL8的新特性ROLE)
- Mysql官方性能测试工具mysqlslap的使用简介(Mysql官方性能测试工具mysqlslap的使用简介)
- docker部署tomcat(Docker安装Tomcat、MySQL和Redis的步骤详解)
- mysql给字段加默认值(MySQL 如何处理隐式默认值)
- mysql server安装图解教程(mysql容器之间的replication配置实例详解)
- mysql的limit的分页使用(获取 MySQL innodb B+tree 的高度的方法)
- php7用什么替代mysql(mysqli扩展无法在PHP7下升级问题的解决)
- mysql优化使用方法(详解Mysql函数调用优化)
- python怎样读取mysql数据(使用Python将Mysql的查询数据导出到文件的方法)
- django连接mysql不支持中文插入(Django创建项目+连通mysql的操作方法)
- mysql主从配置教程(MySQL大库搭建主从的一种思路分享)
- 宝塔数据库不小心删了(宝塔面板MySQL数据库经常自动停止的解决方法)
- 《九牛之人降魔传》开机 演员祁高坤化身九牛之人除魔卫道(九牛之人降魔传开机)
- 王铲铲的致富之路无限金币卡法攻略教学(王铲铲的致富之路无限金币卡法攻略教学)
- 文明6金币太少怎么办 文明6无限刷钱教程(文明6金币太少怎么办)
- 开国中将,王牌军63军首任政委,两个连襟一个上将一个少将传为佳话(王牌军63军首任政委)
- 臭名昭著的731部队最高负责人 石井四郎(臭名昭著的731部队最高负责人)
- 王牌部队,你看的剧情我看的时尚(你看的剧情我看的时尚)
热门推荐
- ubuntu中source指令(怎么修改Ubuntu的源列表source list详解)
- sql server建表语句带字段说明(SqlServer给表增加多个字段的语法)
- MVC过滤器的用法
- 云服务器常见的哪几种(新手如何选择合适的云服务器?)
- ASP.NET windows服务调试
- css中width:auto和width:100%的区别
- 织梦列表页调用文章怎么调(详解织梦手机端搜索时候直接调用search_m.htm手机站页面的办法)
- 微信小程序canvas缩放(微信小程序之html5 canvas绘图并保存到系统相册)
- 免费ftp服务器怎么用(几种流行的ftp服务器软件推荐)
- docker入门搭建博客(快速掌握使用Docker搭建开发环境)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9