mysql数据库引擎为 “InnoDB” 时,为何不能使用uuid(或订单号)来作为主键

论坛 期权论坛 脚本     
匿名技术用户   2021-1-3 20:32   123   0

目录

问题提出

主键为varhcar类型演示

随机生成三个uuid

创建表并插入数据

数据分析

原因分析

导致问题

思考:如果不使用主键会怎么样?


问题提出

建表时一般是 id 作为主键,并且 id 字段的数据类型为 long类型,如果是varchar类型(uuid),是否可以呢?

主键为varhcar类型演示

随机生成三个uuid

    public static void main(String[] args) {
        try {
            for (int i = 0; i <3 ; i++) {
                String aa = UUID.randomUUID().toString();
                System.out.println(aa);
                System.out.println(aa.hashCode());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

输出结果如下

7fe7db3d-fe29-45c2-8612-91821978fb5e

9ae9c364-c9cd-4520-ba0a-38ef84762207

3fd22fc1-723c-404b-a038-5409c5d6e29d

创建表并插入数据

CREATE TABLE `tb_test` (
  `id` varchar(100) NOT NULL COMMENT '主键',
  `content` varchar(255) DEFAULT NULL COMMENT '内容',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入数据,顺序执行如下DDL语句,执行间隔几秒

INSERT INTO `tb_test` VALUES ('7fe7db3d-fe29-45c2-8612-91821978fb5e','第1条测试数据',NOW());
INSERT INTO `tb_test` VALUES ('9ae9c364-c9cd-4520-ba0a-38ef84762207','第2条测试数据',NOW());
INSERT INTO `tb_test` VALUES ('3fd22fc1-723c-404b-a038-5409c5d6e29d','第3条测试数据',NOW());

表数据如下:

数据分析

从上图中可以看到,数据的排序是有问题的.出现问题的原因是表数据排序的顺序是uuid正序排序

原因分析

1 索引的本质是数据结构,主键本身就是索引,InnoDB使用B+Tree作为索引结构,索引中的值,是主键的值,而不是数据的内存地址。B-Tree通常意味着所有的值都是按顺序存储的.

导致问题

表数据的存储是按照主键的值来排序的,这就导致一个问题,就是每次插入都要进行重新排序操作.引起不必要的内存开销

思考:如果不使用主键会怎么样?

1 清除上述表数据

2 删除主键

3 按照顺序执行并依次间隔几秒插入数据

4 得到如下数据顺序(明面上看是按照插入时间排序)

原因解释:

如果表数据引擎是innoDB,表数据文件本身就是按B+Tree组织的一个索引结构,如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP