非关系型数据库和关系型数据的区别
关系型数据库:
采用关系模型来组织数据
可以保证数据的一致性
更新的开销小
支持复杂的查询
非关系型数据库
无需sql层的解析,读写效率高
基于键值对的方式存储数据,
支持多种数据类型的存储,图片文档等
应该很快执行的sql突然变慢了,为什么?如何解决?
原因
MySQL数据库本身被堵住了,比如系统网络资源的限制
sql语句被一些加在数据库上的锁堵住了,导致存储引擎不执行,
索引使用不当导致没有走索引
数据库表的特点导致回表的次数过多。
解决:
采用force index强行选择一个索引
尝试修改sql语句
考虑采用新的索引,对索引进行优化
drop、truncate、delete的区别
delete是从表中删除一行,同时记录日志方便回滚。
truncate是从表中删除所有的数据,不记录日志,无法恢复。
drop是删除整个一张表,表都没了。
一般来说执行速度是drop>truncate>delete
mysql的可重复读解决了幻读的问题吗?
参考链接
在可重复读的隔离级别下普通查询是看不到幻读问题的,因为普通查询是快照读。
如果是当前读就可能会存在幻读问题,但是这个问题也已经被解决了所以不存在幻读问题,具体是怎么解决的呢?
Innodb 引擎为了解决「可重复读」隔离级别使用「当前读」而造成的幻读问题,就引出了 next-key 锁,就是记录锁和间隙锁的组合。也是说如果是当前读就会导致间隙锁的发生,此时其他事务是无法插入符合这个事务当前读读取到的数据的条件的,就会导致阻塞,所以我们项目中一定要注意这个问题,不然很难排查并且严重影响项目的性能。
MySQL的自增主键用完了怎么办?
由于int型的范围大概是20亿左右,而数据达到千万级别的时候就应该考虑分库分表了,因为单个MySQL存不下这么多的数据,所以不需要考虑这个问题。
mysq为什么推荐使用自增主键?
- 使用自增主键的话每次添加数据直接添加到当前索引节点的后续位置,当一页写满就会自动开辟一个新的页。
- 如果使用如果使用非自增主键(如uuid),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到索引页的随机某个位置,此时MySQL为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成索引碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。
- 不过,也不是所有的场景下都得使用自增主键,可能场景下,主键必须自己生成,不在乎那些性能的开销。那也没有问题。
货币类型用什么存储?
使用Decimal类型,因为float和double都是二进制存储,大数据量的情况下会有误差。
如果是时间字段使用什么类型比较好?
可以选择使用timestamp、datetime、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个字节,自己维护一个时间戳,查询效率高,不过数据写入,显示都需要做转换。
为什么不直接存储图片、音频、视频等大容量内容?
我们在实际应用中,都是文件形式存储的。mysql中,只存文件的存放路径。虽然mysql中blob类型可以用来存放大容量文件,但是,我们在生产中,基本不用!
主要有如下几个原因:
1. Mysql内存临时表不支持TEXT、BLOB这样的大数据类型,如果查询中包含这样的数据,查询效率会非常慢。
2. 数据库特别大,内存占用高,维护也比较麻烦。
3. binlog太大,如果是主从同步的架构,会导致主从同步效率问题!
因此,不推荐使用blob等类型!
MySQL数据库cpu飙升到100%的话他怎么处理?
- 列出所有进程 show processlist 观察所有进程 多秒没有状态变化的(干掉)
- 查看慢查询,找出执行时间长的sql;explain分析sql是否走索引,sql优化;
- 检查其他子系统是否正常,是否缓存失效引起,需要查看buffer命中率;
select for update使用的是行级锁还是表级锁?锁的是什么?
首先需要看数据库使用的索引是什么,如果是InnoDB的话,还需要看查询条件where子句中是否存在索引列的判断条件,存在的话才会使用行级锁,不存在就是用表级锁。
执行insert的时候,插入的字段含有主键就会触发行级锁不然就是表级锁。
当然,如果对于MySIAM存储引擎的话是只支持表级锁的。
对于行级锁,锁的是索引。
MySQL为什么使用B+树索引结构而不是哈希、红黑树、B-树?
- Hash哈希,只适合等值查询,不适合范围查询。
- 红黑树,是一种特化的平衡二叉树,MySQL 数据量很大的时候,索引的体积也会很大,内存放不下的而从磁盘读取,树的层次太高的话,读取磁盘的次数就多了。
- B-Tree,叶子节点和非叶子节点都保存数据,相同的数据量,B+树更矮壮,也是就说,相同的数据量,B+树数据结构,查询磁盘的次数会更少。