MYSQL,你会想到啥
想到啥,管我啥事,DBA去管。我只写sql,这里告诉你,你的sql执行结果可能跟你想的不一样。一般在没有并发或者不是高并发情况下,是没有问题,这是mysql帮你做好了 。
mysql->数据存储-
数据存到哪
如何保存,
数据格式是怎么样的
如何保证数据不丢失
如何做到数据复制
怎么提供api供各种语言操作
怎么与各种客户端或者说服务器进行通信
怎么处理不同语言的sql
怎么去优化
怎么样查询才能更快
那里需要去加缓存
如何解决并发情况下事务的问题
SQL语句是怎么样被执行的
…(欢迎添加)
让你去设计或者开发一个mysql
我也不会,但是可以去思考。。。
我们目前需要知道的内容
根据索引的知识,避免并发情况下表锁问题
根据各种数据库、硬件知识,以及具体业务场景的使用,优化mysql的各项配置
索引结构为什么选择B+
索引:首先是将数据通过索引检索,如果能直接在建立的索引上拿到我们需要的数据,那应该是是最好的设计(这样就不需要通过索引,再去进行IO),然后考虑数据如何存放在索引中能快速被搜索到。
这里主要涉及几个点:
- 检索速度
- 树高的问题(与你存储的数据内容大小有关,每个节点的大小和磁盘页大小是固定的)->树越高,代表磁盘io次数越多
二叉树:主要问题,可能形成链表结构,检索无法满足要求,其次是树高问题
二叉搜索树:
红黑树:
B-:
B+:
B+树:
每个子节点只存放数据节点的引用
叶子节点只存放数据,而且是顺序性的。也就是说索引关键字key的逻辑顺序对应的数据,在磁盘中也是顺序的。(这里在我们根据索引号去拿具体顺序的数据时,可以顺序的访问磁盘,这时候应该是比较快的)
几种索引:
聚集索引:除了主键索引都是非聚集索引。索引中键值的逻辑顺序决定了表中相应行的物理顺序(索引中的数据物理存放地址和索引的顺序是一致的),可以这么理解:只要是索引是连续的,那么数据在存储介质上的存储位置也是连续的
具体说明请欣赏:https://www.cnblogs.com/duzhentong/p/8639223.html
主键索引:
辅助索引:例如,name索引,先根据name索引获取id(主键索引,然后根据主键索引查询,这是innodb 特性)
覆盖索引:查询的数据列通过索引项就可以查出来,不需要访问叶子节点(数据存储区)
几种锁
为什么有这么多锁,因为我们在并发条件为了满足数据库隔离级别,为了达到这种效果,mysql引入了这么多的锁,目的就是为了实现并发下事务的隔离。
锁的目的是对事务隔离的实现。
共享锁:in share_mode
排他锁:除了查询,update\insert\delete都会加排他锁
意向共享锁(表锁):相当于一个标记,在使用共享锁之前,会加这个锁,也就是加上这个标记。
意向排他锁(表锁):相当于一个标记,在使用排他锁之前,会加这个锁,也就是加上这个标记。
这个标记,干嘛用,快速告诉其他事务,这个表,已经加了表锁,你的事务需要加表锁,需要等待,其他事务不需要再去遍历每一个数据行是否加锁,从而来判断是否表被锁住。
临界锁:
间隙锁:
记录锁:
mvcc:通过数据记录事务的版本号,来控制并发下的数据可见问题
比如:
A 会话:开启事务; select name from user where id=1; --“aaa”
B会话: update name=“ccc” from user where id =1;
A会话: select name from user where id=1; --这时候还是读取的"aaa",因为这里读取的是比A会话事务号小的记录。或者删除版本号要么是null,要么大于当前版本号的记录。
mvcc问题:带来脏读问题,原因是读取了未提交的修改操作。这时候读操作的事务id大于修改操作的。
这时候用快照读来解决。事务未提交前,读操作是读取的快照。
undo_log:目的是保证数据的原子性(即记录事务提交前数据记录,以便于回滚),这里用来快照读
总结一下(我觉得很关键):
innodb如何解决(脏读、不可重复读、幻读)这些问题:
脏读:快照读
不可重复读:MVCC+快照读
幻读:MVCC
并发情况下:我们写update\insert\delelte操作的时候,需要注意我们是不是锁住了数据行,是不是锁住了表。这时候其他事务在操作这个空间的时候,是不是能正常操作,对我们的业务是不是有影响。
redo_log:目的是保证数据的持久性(数据的操作,是写在这里的,写完即表示操作成功)
配置的优化
连接数的配置:
几个参考因素:操作系统句柄数
mysql配置的连接数
内存参数的配置:
缓冲区
。。。