MySQL 如何设计主键


当前第2页 返回上一页

业务 Key 往往比较长,所占空间更大,导致更大的磁盘 IO

在 Key 确定前不能持久化数据,有时我们没有在确定数据 Key 时,就想先添加一条记录,之后再更新业务 Key

设计一个兼具易用和性能的 Key 生成方案比较难

逻辑 Key 的优点

不会因为业务的变动而需要修改 Key 逻辑

操作简单,且易于管理

逻辑 Key 往往更小,性能更优

逻辑 Key 更容易保证唯一性

更易于优化

逻辑 Key 缺点

查询主键列和主键索引需要额外的磁盘空间

在插入数据和更新数据时需要额外的 IO

更多的 join 可能

如果没有唯一性策略限制,容易出现重复的 Key

测试环境和正式环境 Key 不一致,不利于排查问题

Key 的值没有和数据关联,不符合三范式

不能用于搜索关键字

依赖不同数据库系统的具体实现,不利于底层数据库的替换

五、主键生成

一般情况下,我们都使用 Mysql 的自增 ID,来作为表的主键,这样简单,而且从上面讲到的来看,性能也是最好的。但是在分库分表的情况情况下,自增 ID 则不能满足需求。我们可以来看看不同数据库生成 ID 的方式,也看一些分布式 ID 生成方案。利于我们思考甚至实现自己的分布式 ID 生成服务。

数据库的实现

Mysql 自增

Mysql 在内存中维护一个自增计数器,每次访问 auto-increment 计数器的时候, InnoDB 都会加上一个名为AUTO-INC 锁直到该语句结束(注意锁只持有到语句结束,不是事务结束)。AUTO-INC 锁是一个特殊的表级别的锁,用来提升包含 auto_increment 列的并发插入性。

在分布式的情况下,其实可以独立一个服务和数据库来做 id 生成,依旧依赖 Mysql 的表 id 自增能力来为第三方服务统一生成 id。为性能考虑可以不同业务使用不同的表。

Mongodb ObjectId

Mongodb 为防止主键冲突,设计了一个 ObjectId 作为主键 id。它由一个 12 字节的十六进制数字组成,其中包含以下几部分:

Time:时间戳。4 字节。秒级。

Machine:机器标识。3 字节。一般是机器主机名的散列值,这样就确保了不同主机生成不同的机器 hash 值,确保在分布式中不造成冲突,同一台机器的值相同。

PID:进程 ID。2 字节。上面的 Machine 是为了确保在不同机器产生的 objectId 不冲突,而 pid 就是为了在同一台机器不同的 mongodb 进程产生的 objectId 不冲突。

INC:自增计数器。3 字节。前面的九个字节保证了一秒内不同机器不同进程生成的 objectId 不冲突,自增计数器,用来确保在同一秒内产生的 objectId 也不会发现冲突,允许 256 的 3 次方等于 16777216 条记录的唯一性。

Cassandra TimeUUID

Cassandra 使用下面规则生成一个唯一的 id:time + MAC + sequence

方案

Zookeeper 自增:通过 zk 的自增机制实现。

Redis 自增:通过 Redis 的自增机制实现。

UUID:使用 UUID 字符串作为 Key。

snowflake 算法:和 Mongodb 的实现类似,1位符号位 + 41位时间戳(毫秒级)+ 10位数据机器位 + 12位毫秒内的序列。

开源实现

百度 UidGenerator:基于snowflake算法。

美团 Leaf:同时实现了基于 Mysql 自增(优化)和 snowflake 算法的机制。

以上就是MySQL 如何设计主键的详细内容,更多文章请关注木庄网络博客

返回前面的内容

相关阅读 >>

mysql怎么添加约束?

mysql服务如何修改注册表

详解mysql插入数据成功但是报[err] 1055错误如何解决

mysql怎么删除数据表中的全部数据?

分享mysql中实用的几种sql语句

百万数据下mysql条件查询及分页查询的注意事项

mysql安装配置jdbc和基础学习

mysql如何删除表中一行数据?

细说mysql死锁与日志二三事

触发器什么时候执行

更多相关阅读请进入《mysql》频道 >>


数据库系统概念 第6版
书籍

数据库系统概念 第6版

机械工业出版社

本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...