Mysql 十问
发布日期:2021-10-06 02:38:23 浏览次数:5 分类:技术文章

本文共 2805 字,大约阅读时间需要 9 分钟。

1:为什么要一定要设置主键?

其实这个不是一定的,有些场景下,小系统或者没什么用的表,不设置主键也没关系,mysql最好是用自增主键,主要是以下两个原因:果定义了主键,那么InnoDB会选择主键作为聚集索引、如果没有显式定义主键,则innodb 会选择第一个不包含有NULL值的唯一索引作为主键索引、如果也没有这样的唯一索引,则innodb 会选择内置6字节长的ROWID作为隐含的聚集索引。所以,反正都要生成一个主键,那你还不如自己指定一个主键,提高查询效率!

 

2:主键是用自增还是UUID?

最好是用自增主键,主要是以下两个原因:

  1. 如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。

  2. 如果使用非自增主键(如uuid),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到索引页的随机某个位置,此时MySQL为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成索引碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

不过,也不是所有的场景下都得使用自增主键,可能场景下,主键必须自己生成,不在乎那些性能的开销。那也没有问题。

 

3:自增主机用完了怎么办?

在mysql中,Int整型的范围(-2147483648~2147483648),约20亿!因此不用考虑自增ID达到最大值这个问题。而且数据达到千万级的时候就应该考虑分库分表了。

 

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

最好是主键是无意义的自增ID,然后另外创建一个业务主键ID,

因为任何有业务含义的列都有改变的可能性,主键一旦带上了业务含义,那么主键就有可能发生变更。主键一旦发生变更,该数据在磁盘上的存储位置就会发生变更,有可能会引发页分裂,产生空间碎片。

还有就是,带有业务含义的主键,不一定是顺序自增的。那么就会导致数据的插入顺序,并不能保证后面插入数据的主键一定比前面的数据大。如果出现了,后面插入数据的主键比前面的小,就有可能引发页分裂,产生空间碎片。

 

5:货币字段用什么类型?

货币字段一般都用 Decimal类型,
float和double是以二进制存储的,数据大或者运算之后的时候,可能存在精度值误差。

 

6:时间字段用什么类型?

这个看具体情况和实际场景,timestamp ,datatime ,bigint 都行!

 

timestamp,该类型是四个字节的整数,它能表示的时间范围为1970-01-01 08:00:01到2038-01-19 11:14:07。2038年以后的时间,是无法用timestamp类型存储的。

但是它有一个优势,timestamp类型是带有时区信息的。一旦你系统中的时区发生改变,例如你修改了时区,该字段的值会自动变更。这个特性用来做一些国际化大项目,跨时区的应用时,特别注意!

datetime,占用8个字节,它存储的时间范围为1000-01-01 00:00:00 ~ 9999-12-31 23:59:59。显然,存储时间范围更大。但是它坑的地方在于,它存储的是时间绝对值,不带有时区信息。如果你改变数据库的时区,该项的值不会自己发生变更!

bigint,也是8个字节,自己维护一个时间戳,查询效率高,不过数据写入,显示都需要做转换。这种存储方式的具有 Timestamp 类型的所具有一些优点,并且使用它的进行日期排序以及对比等操作的效率会更高,跨系统也很方便,毕竟只是存放的数值。缺点也很明显,就是数据的可读性太差了,你无法直观的看到具体时间。

 

7:mysql为什么不用大数据类型直接存储内容?

在mysql中,只存文件的存放路径。虽然mysql中blob类型可以用来存放大容量文件,但是,我们在生产中,基本不用!

主要有如下几个原因:

  1. Mysql内存临时表不支持TEXT、BLOB这样的大数据类型,如果查询中包含这样的数据,查询效率会非常慢。

  2. 数据库特别大,内存占用高,维护也比较麻烦。

  3. binlog太大,如果是主从同步的架构,会导致主从同步效率问题!

因此,不推荐使用blob等类型!

 

8:字段为什么要定义为NOT NULL?

一般情况,都会设置一个默认值,不会出现字段里面有null,又有空的情况。主要有以下几个原因:

1. 索引性能不好,Mysql难以优化引用可空列查询,它会使索引、索引统计和值更加复杂。可空列需要更多的存储空间,还需要mysql内部进行特殊处理。可空列被索引后,每条记录都需要一个额外的字节,还能导致MYisam 中固定大小的索引变成可变大小的索引。

2. 如果某列存在null的情况,可能导致count() 等函数执行不对的情况。

3. sql 语句写着也麻烦,既要判断是否为空,又要判断是否为null等。

 

9:MySQL数据库cpu飙升到100%的话他怎么处理?

1. 列出所有进程 show processlist 观察所有进程 多秒没有状态变化的(干掉)

2. 查看慢查询,找出执行时间长的sql;explain分析sql是否走索引,sql优化;

3. 检查其他子系统是否正常,是否缓存失效引起,需要查看buffer命中率;

 

10:mysql主键索引和普通索引之间的区别是什么?

 

普通索引

普通索引是最基本的索引类型,而且它没有唯一性之类的限制。普通索引可以通过以下几种方式创建:

创建索引,例如CREATEINDEX<索引的名字>ONtablename (列的列表);

修改表,例如ALTERTABLEtablenameADDINDEX[索引的名字] (列的列表);

创建表的时候指定索引,例如CREATETABLEtablename ( [...],INDEX[索引的名字] (列的列表) );

主键索引

主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。

主键一般在创建表的时候指定,例如CREATETABLEtablename ( [...],PRIMARYKEY(列的列表) );

但是,我们也可以通过修改表的方式加入主键,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每个表只能有一个主键。

区别

普通索引是最基本的索引类型,没有任何限制,值可以为空,仅加速查询。普通索引是可以重复的,一个表中可以有多个普通索引。

主键索引是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值;索引列的所有值都只能出现一次,即必须唯一。简单来说:主键索引是加速查询 + 列值唯一(不可以有null)+ 表中只有一个。

转载地址:https://blog.csdn.net/luxuiary/article/details/105702618 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:mysql 和 redis 数据不致性怎么办?
下一篇:Java 和 Python 的区别

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年03月24日 04时44分18秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章