面试题首页 > MySQL面试题

MySQL表设计面试题

001如何设置自增的主键?

很简单,只需要在主键后面添加AUTO_INCREMENT关键字就行了

CREATE TABLE `user`(
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(10),
    `password` VARCHAR(20)
);

002插入数据时指定主键了怎么办?

刚才,我们在user表中已经把主键id设置为自增的了,但是又在表中插入了一条设置了id值的数据
insert into `user` values(1, "张三", "zs666")
那么MySQL会直接忽略掉我们自己设置的id,继续通过自增来设置插入数据的id

003主键不连续是什么情况?

例如id从5直接跳到了8,这是因为我们之前在尝试进行插入操作时,虽然事务没有提交,但是id已经自增了

004主键是用自增还是随机(UUID)?

主键建议是自增的好。因为InnoDB中的主键是聚簇索引,如果主键是自增的话,每次插入新的记录就会顺序添加到当前索引节点的后续位置,当一页写满就会自动开辟新的页。如果不是自增主键,可能就会在中间插入,引发页的分裂导致产生很多表空间的碎片。可以理解为当主键是UUID的时候,插入表记录的时间会更长,占用空间也会更大。

005主键为什么不推荐有业务含义?

1.任何有业务含义的列都有改变的可能性,主键一旦带上了业务含义,那么主键就有可能发生变更。而主键一旦发生变更,该记录数据在磁盘上的存储位置就会发生改变,甚至有可能会引发页分裂导致产生空间碎片。
2.带有业务含义的主键就不一定是顺序自增的了,这样就会导致数据的插入顺序不到有序的,也不能保证后面插入数据的主键一定比前面的数据大。如果出现了后面插入数据的主键比前面的小的情况,就有可能引发页分裂导致产生空间碎片。

006表示枚举的字段为什么不用enum类型?

表示枚举的字段一般选用tinyint类型。不选用enum类型主要有两个原因:
1.enum类型的order by的操作效率低,需要额外的操作。
2.如果枚举值是数值类型的,会很容易出现语法陷阱,枚举的下标和数值很容易会被弄混淆。

007货币字段用什么类型?

如果货币单位是分,可以是int类型;如果坚持用元,则要用decimal类型。
但是是不能用float和double类型的,因为这两个类型是以二进制存储的,会有一定的误差。比如float类型如果你insert一个1234567.23,查询出来的结果可能是1234567.25。

008时间字段用什么类型?

时间字段的话需要结合项目背景,varchar、timestamp、datetime或bigint类型都可以。
1.varchar类型。如果用varchar类型来存时间,优点在于显示直观,存取都方便。但是缺点也是挺多的,比如插入的数据没有校验,某一天你可能会发现数据库中存了一个2019-06-31的数据。其次,做时间比较运算时需要用str_to_date()等函数将其转化为时间类型,除非建立基于函数的索引,否则这么写是无法命中索引的,数据量一大,查询效率就会很低。
2.timestamp类型。这个类型是四个字节的整数,它能表示的时间范围为1970-01-01 08:00:01到2038-01-19 11:14:07,而2038年以后的时间,是无法用timestamp类型存储的。但是它有一个优势是它带有时区信息的,一旦系统中的时区发生改变,项目中的该字段的值也会自己发生改变。
3.datetime类型。datetime类型的储存占用8个字节,存储的时间范围为1000-01-01 00:00:00 ~ 9999-12-31 23:59:59。显然,存储时间范围更大,但是它存储的是时间绝对值,不带有时区信息。如果改变了数据库的时区,该项的值不会自己发生变更。
4.bigint类型。这个类型也是8个字节,自己维护一个时间戳,表示范围比timestamp类型大多了。缺点就是要自己维护,不大方便。

009为什么不直接存储图片、音频和视频等大容量内容?

在实际应用中,一般都是用HDFS来存储文件的,在MySQL中只会存文件的存放路径。但是实际上MySQL是有提供两个字段类型被涉及用来存放大容量文件的,一个是text类型,一个是blob类型。然而在生产中基本不会使用这两个类型,主要原因如下:
1.MySQL内存临时表不支持text和blob这样的大数据类型。如果查询中包含这样的数据,那么在排序等操作的时候就不能够使用内存临时表,只能使用磁盘临时表,会导致查询效率低下。
2.这两种类型会造成binlog的内容太多。因为数据的内容比较大,也就会造成binlog的内容比较多。我们知道,主从同步是通过binlog来进行的,如果binlog过大,就会导致主从同步的效率问题。

010为什么字段要被定义为NOT NULL?

1.索引的性能不好。MySQL难以优化引用可空列查询,它会使得索引、索引统计和值更加复杂。可空列需要更多的存储空间,还需要MySQL内部进行特殊处理。可空列被索引后,每条记录都需要一个额外的字节。
2.查询可能会出现一些不可预料的结果。比如说使用count()聚合函数去统计一个可为空的字段,那么最后统计出来的记录数可能会和实际的记录数不同。

011varchar(50)中50的含义?

1)字段最多存放 50 个字符
2)如 varchar(50) 和 varchar(200) 存储 "jay" 字符串所占空间是一样的,后者在排序时会消耗更多内存

目录

返回顶部