数据库面试题1

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/strivenoend/article/details/84727965

1.数据库自增主键可能的问题

1、当数据库导出之后重新导入(备份再恢复),主键会重新生成,如果有其他的表以这个主键作为外键,那么会导致这个关联关系不存在。 
2、数据量特别大时,会导致查询数据库操作变慢。此时需要进行数据库的水平拆分,划分到不同的数据库中,那么当添加数据时,每个表都会自增长,导致主键冲突。

在MySQL中经常会配置自增长属性的字段作为主键,特别是使用InnoDB存储引擎,

因为InnoDB的聚集索引的特性,使用自增长属性的字段当主键性能更好,但是使用自增主键也可能会带来一些问题。

举个例子,使用自增主键对数据库做分库分表,可能出现一些诸如主键重复等的问题,或者在数据库导入的时候,可能会因为主键出现一些问题。

主要业务表的主键应该配置一个合理的策略,尽量避免自增AUTO_INCREMENT。

针对主键自增可能产生的问题,下面这两篇文章有相关的讨论:

INNODB自增主键的一些问题

mysql自增列导致主键重复问题分析

针对主键增长方式的解决方案

来自知乎问题-高并发网站如何解决数据库主键自增的时候出现重复?

2.数据库自增主键可能的问题,如何解决

1)依赖数据库自增机制达到全局ID唯一并消除单点

在2的基础上,部署两个(多个)数据库实例,

设置自增步长为2(多个则为实例数),即auto-increment-increment = 2

设置auto-increment-offset分别为1,2.....

这样第一台数据库服务器的自增id为 1 3 5 7 9

第二台为2 4 6 8 10

2)使用uuid

解决的办法有两个方向,一个是在应用层做处理,一个是数据库上去做处理

3)给每个数据库设置不同的开始id

数据库1 从  10000.. 开始
数据库2 从  20000.. 开始
这种办法不依赖于其他服务实现id唯一性,即时其他数据库挂了依然能生成id

4)使用一个库专门生成id

id列不设自增,由应用设置id

建立单独的id生成数据库,库中建立多个id生成表,每个表如下

+-------------------+------+
| id | stub |
+-------------------+------+
| 72157623227190423 | a |
+-------------------+------+


每次插入数据时先从该库的对应id生成表中更新id

REPLACE INTO Tickets64 (stub) VALUES ('a');
SELECT LAST_INSERT_ID();


执行后表内数据id增加1,并返回新id

然后使用该id插入到表中,这种方法的好处是能够统计每个表的数据量

5)使用Redis分批次生成id

redis中存储一个id的 当前批次值 ,应用每次获取该值的时候增加1,每个批次的数量是固定的
比如批次10,开始id为  10 x 1000  结束id为  (10 + 1) x 1000 - 1 
id使用完成后再去获取一个批次id

猜你喜欢

转载自blog.csdn.net/strivenoend/article/details/84727965