Mysql主键UUID和自增主键的区别及优劣分析

 更新时间:2021年02月02日 16:25:38   作者:银月 rey  
这篇文章主要介绍了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;

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

相关文章

  • Mysql事项,视图,函数,触发器命令(详解)

    Mysql事项,视图,函数,触发器命令(详解)

    下面小编就为大家带来一篇Mysql事项,视图,函数,触发器命令(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • mysql 的load data infile

    mysql 的load data infile

    前些日子在开发一个舆情监测系统,需要在一个操作过程中往数据表里插入大量的数据,为了改变以往生硬地逐条数据插入的笨办法,也为了提高执行效率,决定用load data infile来执行数据插入。
    2009-05-05
  • CentOS6.9下mysql 5.7.17安装配置方法图文教程

    CentOS6.9下mysql 5.7.17安装配置方法图文教程

    这篇文章主要为大家详细介绍了CentOS6.9下mysql 5.7.17安装配置方法图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • 使用sql语句insert之前判断是否已存在记录

    使用sql语句insert之前判断是否已存在记录

    这篇文章主要介绍了使用sql语句insert之前判断是否已存在记录,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Mysql离线安装8.0.26的图文教程

    Mysql离线安装8.0.26的图文教程

    这篇文章主要介绍了Mysql离线安装8.0.26的图文教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • MySQL数据库优化之索引实现原理与用法分析

    MySQL数据库优化之索引实现原理与用法分析

    这篇文章主要介绍了MySQL数据库优化之索引实现原理与用法,结合实例形式分析了mysql数据库优化操作的索引原理、具体实现与相关操作注意事项,需要的朋友可以参考下
    2020-01-01
  • mysql如何显示longblob解决方案

    mysql如何显示longblob解决方案

    这篇文章主要为大家介绍了mysql如何显示longblob解决方案,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • 详解MySQL子查询(嵌套查询)、联结表、组合查询

    详解MySQL子查询(嵌套查询)、联结表、组合查询

    这篇文章主要介绍了MySQL子查询(嵌套查询)、联结表、组合查询,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • mysql 8.0.28 安装配置方法图文教程

    mysql 8.0.28 安装配置方法图文教程

    这篇文章主要为大家详细介绍了mysql 8.0.28 安装配置方法图文教程,文中安装步骤介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • xampp中修改mysql默认空密码(root密码)的方法分享

    xampp中修改mysql默认空密码(root密码)的方法分享

    以前开发我一直都是用的phpnow做php开发环境,phpnow的特点就是一键安装,安装的时候会要求用户输入mysql的root密码。今天由于客户机器使用的xampp作为开发环境,所以碰到了修改mysql默认空密码的问题
    2014-04-04

最新评论