第一范式:每个列都不可被拆分。
第二范式:在第一范式的基础上,非主键只完全依赖于主键,不依赖于主键的一部分。
第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键
首先分为两大模块:
(1)存储模块:存储数据,类似于文件系统。将数据持久化到存储设备中。
(2)程序实例模块:对存储的数据进行逻辑化的管理。
1.首先要说到全表扫描:
数据库存储数据的最小单元块或者页,是由多行组成的。(整个表就是多个块或页)我们把这些块或者页加载到内存。然后每个块或者页去轮询,找到目标返回。这适合数据比较小的情况。
2.索引的灵感来自于字典,查字典可以通过偏旁部首等。查数据我们就可以通过主键、唯一键、普通键(就是我们说的关键字)。除此之外,我们还要将这些关键字以一种友好的形式组织起来,就是我们说的索引的数据结构。例如建立二叉查找树进行二分查找,建立B-Tree结构、B+Tree结构(MySQL)、Hash结构进行查找。
查询效率O(logn)
缺陷:
在插入可能导致树变成线性表,查询效率降低为O(n)
查询过程中,遇到一个节点需要进行一次IO,如果树的高度过大将导致多次IO。营销那个查询效率。
阶是每个节点上最多的关键字+1,此处是3阶。
8/12 26/30 为节点中的关键字,也为概念中的K
B+Tree的定义:
B+Tree适合做索引的原因
hash索引,根据hash函数的运算,只需经过一次定位就可以找到所需数据在的桶。
B+Tree索引 根节点-->非叶子节点---->叶子节点 (稳定查询)
理论上hash索引比B+Tree快。
hash索引的缺点:
密集索引文件中的每个搜索码值都对应一个索引值。(叶子节点保存的不仅仅是键值,还保存了为了同一行记录的其他列的信息,由于密集索引决定了表的排列顺序,一个表只能有一个物理排列顺序,所以一个表只能创建一个密集索引)
稀疏索引文件只为索引码的某些值建立索引项。(叶子节点只保存了键位信息,以及该行数据的地址,(有的仅保存键位信息和主键),定位到叶子节点之后,需要地址或者主键信息定位到数据)
InnoDB有且仅有一个密集索引,它密集索引的选取规则:
为什么InnoDB非要有主键索引?
因为非主键索引存储相关键位和其对应的主键值,包括两次查找。
InnoDB和Myisam索引的区别
InnoDB采用的密集索引+ 稀疏索引,主键索引可以直接找到叶子节点中的数据,辅助索引需要先找到主键索引,再通过主键B+Tree找到数据。即InnoDB数据和索引是存放在一个文件的。
Myisam全部采用稀疏索引,根据主键和辅助键的索引都只能找打一个地址信息,要在根据这个地址信息去另外一个文件中寻找数据,即Myisam的索引和数据是分开的。
1.根据慢日志定位慢查询sql
2.使用explain等工具分析SQL
语法:explain 慢SQL语句
Explain关键字:
3.修改SQL或者尽量让SQL走索引
MySQL创立复合索引的规则是首先会对复合索引的最左边第一个索引字段的数据进行排序,在第一个字段的基础上,对第二个字段进行排序,实现类似于order by 字段1,order by 字段2,这样的一个排序规则。所以第一个索引绝对是有序的,第二个字段是无序的,因此使用第二个字段进行条件判断是用不到索引的,这就是MySQL强调联合索引的原因。
不是,因为:
对于myisam,当查询数据的时候,会自动加上一个表级的读锁;对数据进行增删改的时候,会为表加上一个表级别的写锁。当读锁未被释放的时候,要想为表加上写锁,就要等待读锁释放之后。
如何显示的给表加/释放读写锁呢?
lock tables person_info_myisam read/write;
unlock tables;
读锁也叫共享锁,多个session能够同时获取,同时读取数据,不会被阻塞。写锁也叫排它锁,与其他所有的锁互斥。
myisam默认是表级锁,不支持行级锁,表级锁会锁着整张表。
innoDB默认是行级锁的。支持表级锁。InnoDB在使用索引的情况下,用的是行级锁,没有索引的情况下,用的表级锁。
MySQL是默认提交事务的。innoDB 用的是二段锁,二段锁就是加锁和解锁是分两个步骤进行的,即先对同一个事务中的一批操作,分别加锁,commit的时候,在对事务里面加上的锁进行统一的解锁。而当前commit是自动提交的,看起来和myisam没什么区别,set commit=0,关闭自动提交,设置仅对当前的session的生效,其他的session仍然是自动提交的。
MyISAM适合的场景
InnoDB适合的场景:
数据库锁的分类;
(1)事务并发访问引起的问题以及如何避免
更新丢失:一个事务的更新覆盖了另一个事务的更新。解决方法:MySQL所有事务隔离级别在数据库层面上均可避免。
脏读:一个事务读到另一个事务未提价的数据(READ-uncommitted级别会发生)。解决方法:READ-Committed事务隔离级别上可避免。
查看事务的隔离级别: select@_@tx_isolation
设置事务的隔离级别:set session transaction isolation level read uncommitted
不可重读:(READ-Committed隔离级别下会发生)事务A多次读取数据,事务B在事务A读取的过程中对数据进行了更新并提交,导致事务A多次读取的数据不一致。解决方法:Repeatable=read事务隔离级别上可避免。
幻读:事务A读取当前若干行数据,事务B以插入或者删除的方式修改事务A的隔离集,导致事务A多次读取同一数据时的结果不一致。Serializable事务隔离级别可以避免。
不可重复读与幻读比较相似,不可重复读重在对同一数据的修改,幻读则重在插入和删除数据。
隔离级别越高,对性能影响的越大。
(1)表象:快照度(非阻塞读)---伪MVCC
当前读和快照读
当前读就是加了锁的增删改查语句。读取的是记录的最新版本,读取的时候保证其他事务不能对数据进行修改。例如:select....lock in share mode, select ...for update , update ,delete, insert。
快照读:不加锁的非阻塞读,读到的数据不一定是最新版本,例如:select
RC、RR级别下的InnoDB的非阻塞读(快照度)如何实现?
(2)内在:next-key锁 (行锁+gap锁)
行锁:
Gap锁:
对主键索引或者唯一键索引会用gap锁吗?
关键词:
group by :
满足“select 字句中的列名必须为分组列或者列函数”。
列函数对group by 子句定义的每个组返回一个结果。
having
通常与group by 子句一起使用
where 过滤行,having 过滤组
出现在同一sql语句中 : where >group by>having
统计相关: