欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数据库主键设计

程序员文章站 2022-06-02 15:39:47
...

先来一个测,看看主键长度对查询和插入性能的影响。
两个表
t_book 主键是string 长度 36 字节
t_student 主键是bigint 8字节

CREATE TABLE `t_book` (
  `book_id` varchar(36) NOT NULL,
  `book_desc` varchar(255) DEFAULT NULL,
  `book_name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`book_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `t_student` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `create_time` datetime DEFAULT NULL,
  `sname` varchar(255) DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8mb4;

通过程序每个表插入 100w 条数据
t_book 花费的时间是 t_student 的十倍以上
(已经有100W 再通过程序每次插入1,连续100次。 t_book 花费 35分钟,t_student 花费4分钟)

再看看 查询 count(*) 的性能

SELECT count() from t_book
query time 3.187s
SELECT count(
) from t_student
query time 0.274s

差距在10倍以上

数据是200W时候

SELECT count() from t_book
query time 7.056s
SELECT count(
) from t_student
query time 0.556s

差距依然在10倍以上

插入速度慢原因

因为插入时候主键的生成策略用的是 uuid
因为是无序的,所以每次索引生成时候需要重排序,浪费时间。

查询速度慢原因

查询connt(*)时候,需要将索引读入到内存中。
如果索引长度越长,同样多的索引需要存储的磁盘空间越大。磁盘IO 也是系统中最大的瓶颈。导致整个性能下降。

所以考虑到性能,主键最好是 递增的并且占用存储空间小。

单表情况

可以是 long 型, 自增主键。

分表情况

需要一个id 生成器。
timestemp + *** + 机器号 组成的 数字
需要保证时间不能回滚,否则会出现重复的id