赞
踩
事务是逻辑上的一组操作,要么都执行,要么都不执行。
MySQL InnoDB 引擎使用 redo log(重做日志) 保证事务的持久性;
使用 undo log(回滚日志) 来保证事务的原子性。
MySQL InnoDB 引擎通过 锁机制、MVCC 等手段来保证事务的隔离性( 默认支持的隔离级别是 REPEATABLE-READ )。
保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。
幻读强调读取的数据增多或者减少了,不可重复读强调多次读取的数据不一致。
索引是一种用于快速查询和检索数据的数据结构。常见的索引结构有: B 树, B+树和 Hash。
优点 :
- 使用索引可以大大加快 数据的检索速度(大大减少检索的数据量), 这也是创建索引的最主要的原因。
- 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
缺点 :
- 创建索引和维护索引需要耗费许多时间。当对表中的数据进行增删改的时候,如果数据有索引,那么索引也需要动态的修改,会降低 SQL 执行效率。
- 索引需要使用物理文件存储,也会耗费一定空间。
哈希表是键值对的集合,通过键(key)即可快速取出对应的值(value),因此哈希表可以快速检索数据(接近 O(1))。
哈希算法有个 Hash 冲突 问题,也就是说多个不同的 key 最后得到的值相同。通常情况下,我们常用的解决办法是 链地址法。链地址法就是将哈希冲突数据存放在链表中。就比如 JDK1.8 之前 HashMap 就是通过链地址法来解决哈希冲突的。不过,JDK1.8 以后HashMap为了减少链表过长的时候搜索时间过长引入了红黑树。
- 为什么MySQL 没有使用其作为索引的数据结构呢?
Hash 冲突问题 :我们上面也提到过Hash 冲突了,不过对于数据库来说这还不算最大的缺点。Hash 索引不支持顺序和范围查询(Hash 索引不支持顺序和范围查询是它最大的缺点: 假如我们要对表中的数据进行排序或者进行范围查询,那 Hash 索引可就不行了。
B 树也称 B-树,全称为 多路平衡查找树 ,B+ 树是 B 树的一种变体。(查找:左小右大 平衡:左右子树高度差不大于1)
1. B 树的所有节点既存放键(key) 也存放 数据(data),而 B+树只有叶子节点存放 key 和 data,其他内节点只存放 key。
2. B 树的叶子节点都是独立的;B+树的叶子节点有一条引用链指向与它相邻的叶子节点。
3. B 树的检索的过程相当于对范围内的每个节点的关键字做二分查找,可能还没有到达叶子节点,检索就结束了。而 B+树的检索效率就很稳定了,任何查找都是从根节 点到叶子节点的过程,叶子节点的顺序检索很明显。
为什么不使用二叉平衡搜索树:因为二叉树的层数太大了,每个节点存储的数据量又太小,每次I/o读取的数据是以页单位的,因此小数据读取一页会造成很大的I/O浪费.
同样情况下,B+的非叶子节点存储更多的索引,因此B+更矮更胖,可以有效减少I/o次数
聚集索引:记录的排列顺序和与索引的排列顺序一致(字典按拼音查)
聚集索引的查询速度非常的快,因为整个 B+树本身就是一颗多叉平衡树,叶子节点也都是有序的,定位到索引的节点,就相当于定位到了数据。
依赖于有序的数据 :因为 B+树是多路平衡树,如果索引的数据不是有序的,那么就需要在插入时排序,如果数据是整型还好,否则类似于字符串或 UUID 这种又长又难比较的数据,插入或查找的速度肯定比较慢。
更新代价大 : 如果对索引列的数据被修改时,那么对应的索引也将会被修改, 而且况聚集索引的叶子节点还存放着数据,修改代价肯定是较大的, 所以对于主键索引来说,主键一般都是不可被修改的。
- 非聚集索引:记录的排列顺序和与索引的排列顺序不一致(字典按偏旁查)
更新代价比聚集索引要小 。非聚集索引的更新代价就没有聚集索引那么大了,非聚集索引的叶子节点是不存放数据的
跟聚集索引一样,非聚集索引也依赖于有序的数据
可能会二次查询(回表) :这应该是非聚集索引最大的缺点了。 当查到索引对应的指针或主键后,可能还需要根据指针或主键再到数据文件或表中查询。(不是必须(覆盖索引):一个索引包含(覆盖)所有需要查询字段的值 select score from student where score > 90)
col
)//主键col
)//唯一col
)//普通col
)//全文column1
, column2
, column3
)//多列EXPLAIN SELECT * FROM employees.titles WHERE emp_no=‘10001’ AND title=‘Senior Engineer’ AND from_date=‘1986-06-26’;
user
WHERE DATE(create_time) = ‘2020-09-03’;user
WHERE age - 1 = 20;user
WHERE name
= ‘张三’ OR height = ‘175’;user
WHERE name
LIKE ‘%冰’;当MySQL单表记录数过⼤时,数据库的CRUD性能会明显下降
test
WHERE id
=1 FOR UPDATE; 其他事务可读,不可操作。redo log(重做日志)
redo log(重做日志)是InnoDB存储引擎独有的,它让MySQL拥有了崩溃恢复能力。
比如 MySQL 实例挂了或宕机了,重启时,InnoDB存储引擎会使用redo log恢复数据,保证数据的持久性与完整性。
刷盘时机:
1.默认 提交事务时刷盘
2.间隔1 秒的轮询机制,会把 redo log buffer 中的内容写到文件系统缓存(page cache),然后刷盘
3.当 redo log buffer 占用的空间即将达到 innodb_log_buffer_size 一半的时候,后台线程会主动刷盘
存储形式
日志文件组,采用环形数组的方式从头开始写,写到末尾又回到头循环写。
日志文件组有两个属性相当于时针和分针,记录完成一个指针向后移动,恢复数据时另一个指针向前移动,如果指针快要接近,意味着需要清楚一些记录。
binlog(归档日志)
redo log 它是物理日志,记录内容是“在某个数据页上做了什么修改”,属于 InnoDB 存储引擎。而 binlog 是逻辑日志,记录内容是语句的原始逻辑,类似于“给 ID=2 这一行的 c 字段加 1”,属于MySQL Server 层。只要发生了表数据更新,都会产生 binlog 日志。mysql依靠binlog来同步数据,保证数据一致性。
undo log(回滚日志)
我们知道如果想要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行回滚,在 MySQL 中,恢复机制是通过 回滚日志(undo log) 实现的,所有事务进行的修改都会先记录到这个回滚日志中,然后再执行相关的操作。如果执行过程中遇到异常的话,我们直接利用 回滚日志 中的信息将数据回滚到修改之前的样子即可!并且,回滚日志会先于数据持久化到磁盘上。这样就保证了即使遇到数据库突然宕机等情况,当用户再次启动数据库的时候,数据库还能够通过查询回滚日志来回滚将之前未完成的事务。
MySQL InnoDB 引擎使用 redo log(重做日志) 保证事务的持久性,使用 undo log(回滚日志) 来保证事务的原子性。依靠binlog来同步数据,保证数据一致性。
//建表
CREATE TABLE `grade` (
`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级ID',
`gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
PRIMARY KEY (`gradeid`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
//插入
INSERT INTO 表名[(字段1,字段2,字段3,...)] VALUES('值1','值2','值3')
//删除 turncate清空表数据 结构、索引不变
DELETE FROM grade WHERE gradeid = 5;
TRUNCATE [TABLE] table_name;
连接查询如需要多张数据表的数据进行查询,则可通过连接运算符实现多个查询
- 内连接 inner join 查询两个表中的结果集中的交集 (查交集)
- 外连接 outer join
左外连接 left join (以左表作为基准,右边表来一一匹配,匹配不上的,返回左表的记录,右表以NULL填充) (查左边全部 右边没有的Null补)
右外连接 right join (以右表作为基准,左边表来一一匹配,匹配不上的,返回右表的记录,左表以NULL填充)(查右边全部 左边没有的Null补)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。