数据库主键一定要自增吗?有哪些场景不建议自增?

文章讨论了数据库主键是否必须自增,解释了自增主键的优势,如优化B+树索引效率,减少了页分裂。同时,提到了在分库分表、分布式系统中,主键不自增的场景,如雪花算法和UUID。对于MySQL的TiDB,推荐使用随机UUID避免写热点。此外,出于业务考虑,用户ID不建议使用自增ID,以防泄露用户增长等敏感信息。
摘要由CSDN通过智能技术生成

我们平时建表的时候,一般会像下面这样。

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` char(10) NOT NULL DEFAULT '' COMMENT '名字',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4;

出于习惯,我们一般会加一列id作为主键,而这个主键一般边上都有个AUTO_INCREMENT, 意思是这个主键是自增的。自增就是i++,也就是每次都加1。

但问题来了。

主键id不自增行不行?

为什么要用自增id做主键?

离谱点,没有主键可以吗?

什么情况下不应该自增?

被这么一波追问,念头都不通达了?

这篇文章,我会尝试回答这几个问题。

主键不自增行不行

当然是可以的。比如我们可以把建表sql里的AUTO_INCREMENT去掉。

CREATE TABLE `user` (
  `id` int NOT NULL COMMENT '主键',
  `name` char(10) NOT NULL DEFAULT '' COMMENT '名字',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

然后执行

INSERT INTO `user` (`name`)  VALUES    ('debug');

这时候会报错Field 'id' doesn't have a default value。也就是说如果你不让主键自增的话,那你在写数据的时候需要自己指定id的值是多少,想要主键id是多少就写多少进去,不写就报错。

改成下面这样就好了

INSERT INTO `user` (`id`,`name`)  VALUES    (10, 'debug');

为什么要用自增主键

我们在数据库里保存的数据就跟excel表一样,一行行似的。

user表

而在底层,这一行行数据,就是保存在一个个16k大小的页里。

每次都去遍历所有的行性能会不好,于是为了加速搜索,我们可以根据主键id,从小到大排列这些行数据,将这些数据页用双向链表的形式组织起来,再将这些页里的部分信息提取出来放到一个新的16kb的数据页里,再加入层级的概念。于是,一个个数据页就被组织起来了,成为了一棵B+树索引

B+树结构

而当我们在建表sql里声明了PRIMARY KEY (id)时,mysql的innodb引擎,就会为主键id生成一个主键索引,里面就是通过B+树的形式来维护这套索引。

到这里,我们有两个点是需要关注的:

回答: 是的,数据库主键可以不自增。在MySQL中,我们可以通过去掉建表语句中的AUTO_INCREMENT来实现主键自增的设置。例如,可以创建一个没有自增属性的主键列,如下所示: CREATE TABLE `user` ( `id` int NOT NULL COMMENT '主键', `name` char(10) NOT NULL DEFAULT '' COMMENT '名字', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 尽管在表的定义中没有明确指定自增属性,但是MySQL的InnoDB引擎会在内部生成一个名为ROW_ID的隐藏列,它实际上是一个自增列。这个隐藏列用于确保数据表有一个主键主键索引。\[1\]\[2\] 需要注意的是,并不是所有的数据库建议使用自增id作为主键。例如,TiDB数据库推荐使用随机id作为主键,以避免写热点问题。此外,对于一些敏感数据,如用户id、订单id等,如果使用自增id作为主键,外部通过抓包等方式很容易获取到新进用户量、成单量等信息,因此需要谨慎考虑是否继续使用自增主键。\[3\] #### 引用[.reference_title] - *1* *2* *3* [数据库主键一定自增吗?有哪些场景建议自增?](https://blog.csdn.net/CRMEB/article/details/125393423)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值