TINYINT,SMALLINT,MEDUIINT,BIGINT
任何数据都可以指定长度,不是指定合法长度,而是限制了显示长度
CHAR,VARCHAR,TXT
第一范式:不会有重复的列,体现原子性
第二范式:存在主键,体现唯一性
第三范式:非主属性必须互不依赖
范式:范式化的表减少了数据冗余,更新操作快,占用存储时间少
缺点:经常需要多表查询
反范式:查询表较快
缺点:存在大量冗余数据,数据的维护成本更高
索引是对数据库中一列或多列的值进行排序的数据结构,用于快速访问数据表中的特定结构
聚簇非聚簇:聚簇索引值的逻辑顺序与表中相应行顺序不一致
优点:大大加快检索速度,通过创建唯一性索引,可以保证数据表中每一行数据的唯一性
缺点:索引本身需要空间,聚簇索引会更大;创建和维护索引需要时间
由于Hash的随机特性,一定范围的值在hash映射后范围不一致,所以无法范围查询,只能等值查询
我们看到 最左边的a 都是有序的,分别是 : 1,1,2,2,3,3 但是右边的b 不一定有序: 1,2,1,4,3,2
但是在a都为 1 的情况下 b是有序的, 如: a=1时 b =1,2 ; a=2时, b= 1,4; a=3时 ,b=1,2;
覆盖索引指的是在索引树中,所有需要查询的列都能够通过B+树的叶子节点来完成查询,而不必再回到数据页中查找对应的数据行。因此,覆盖索引可以大幅度减少磁盘IO的次数,从而提高查询效率。
MySQL 服务器将这一部分判断条件传递给存储引擎,然后由存储引擎通过判断索引是否符合 MySQL 服务器传递的条件,只有当索引符合条件时才会将数据检索出来返回给 MySQL 服务器。索引条件下推优化可以减少存储引擎查询基础表的次数,也可以减少 MySQL 服务器从存储引擎接收数据的次数。
假设一个页内的数据过少,那么操作系统就需要读取更多的页,涉及磁盘随机 I/O 访问的次数就更多。将数据从磁盘读入内存涉及随机 I/O 的访问,是数据库里面成本最高的操作之一。因而这种树高会随数据量增多急剧增加,每次更新数据又需要通过左旋和右旋维护平衡的二叉树,不太适合用于存储在磁盘上的索引文件
InnoDB支持事务,支持外键,MyISAM不支持
InnoDB 和 MyISAM 均支持 B+ Tree 数据结构的索引。但 InnoDB 是聚集索引,而 MyISAM 是非聚集索引。具体体现在Innodb的数据文件和索引文件绑定在一起,而mysiam索引和数据是分离的,索引保存的是数据文件的指针
InnoDB推荐使用自增主键的原因主要是为了提高写入效率和避免数据碎片。因为InnoDB的数据结构是B+树,如果使用自增主键,那么每次插入数据都会在B+树的最右边,不会导致树的分裂和重平衡。而如果使用非自增的主键或者没有指定主键,那么每次插入数据都可能会在B+树中间或者随机位置,导致树的结构变化和空间浪费。
InnoDB 会监控对表上各索引页的查询执行情况,如发现建立哈希索引可以提升速度,则建立哈希索引,这是过程不需要用户干预。
页:和内存的页类似
区:区是页的集合
段:B+ 树将数据分为了两部分,叶子节点部分和非叶子节点部分,也就我们要介绍的段 Segment,也就是说 InnoBD 中每一个索引都会创建两个Segment段来存放对应的两部分数据
定义:Buffer Pool 是 InnoDB 存储引擎层的缓冲池
预读机制:线性预读(程序的局部性原理):线性预读认为如果前面的请求顺序访问当前区(extent)的页,那么接下来的若干请求也会顺序访问下一个区的页,并将下一个区加载到 Buffer Pool。
预读失效:要优化预读失效,则让预读失败的页停留在缓冲池里的时间尽可能短,预读成功的页停留时间尽可能长。具体将 LRU 链分代实现,即新生代和老年代(old subList),预读的页加入缓冲池时只加入到老年代头部,只有真正被预读成功,则再加入新生代。
缓冲池污染:当批量扫描大量数据时,可能导致把缓冲池的所有页都替换出去,导致大量热数据被换出,MySQL 性能急剧下降。
InnoDB 缓冲池加入了一个老生代停留时间窗口的机制,只有满足预读成功并且在老生代停留时间大于该窗口才会被放入新生代头部
定义:事务是逻辑上的一组操作,要么都执行,要么都不执行
脏读:事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的
幻读:一个事务中两次读取的数据量不一致。 系统管理员 A 将数据库中所有学生的成绩从具体分数改为 ABCDE 等级,但是系统管理员 B 就在这个时候插入了一条具体分数的记录,当系统管理员 A 改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
不可重复读:一个事务中两次读取的数据的内容不一致。 事务 A 多次读取同一数据,事务 B 在事务 A 多次读取的过程中,对数据作了更新并提交,导致事务 A 多次读取同一数据时,结果 不一致。
定义:当数据库有并发事务的时候,可能会产生数据的不一致,这时候需要一些机制来保证访问的次序,锁机制就是这样的一个机制。即锁的作用是解决并发问题。
快照读就是读取的是快照数据,不加锁的简单 Select 都属于快照读。
当前读就是读的是最新数据,而不是历史的数据。加锁的 SELECT,或者对数据进行增删改都会进行当前读。
定义:存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需要创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。
1.返回值不同 函数只有一个返回值,而存储过程通过参数返回,可以有多个也可以没有
2.参数不同 函数可以在查询语句中字节调用,而存储过程必须单独调用
二进制日志会记录所有日志记录,包括InnoDB、MyISAM等存储引擎的日志;重做日志只记录innoDB自身的事务日志。
二进制只在事务提交前写入到磁盘,一个事务只写一次;而在事务进行过程,会有重做日志不断写入磁盘。
定义:主从复制是用来建立一个与主数据库完全一样的数据库环境,即从数据库。主数据库一般是准实时的业务数据库
作用:读写分离,使数据库能支撑更大的并发;高可用,做数据的热备,作为后备数据库,主数据库故障可以切换到从数据库
数据库有个 binlog 二进制文件,记录了数据可执行的所有 SQL 语句。主从同步的目标就是把主数据库的 binlog 文件中的 SQL 语句复制到从数据库,让其在从数据的 relaylog 文件中再执行一次这些 SQL 语句即可。
异步复制:MySQL 默认的主从复制方式就是异步复制,因为 Master 根本不考虑数据是否达到了 Slave,或 Slave 是否成功执行。
半同步:一主一从,一主多从情况下,Master 节点只要确认至少有一个 Slave 接受到了事务,即可向发起请求的客户端返回执行成功的操作。同时 Master 是不需要等待 Slave 成功执行完这个事务,Slave 节点接受到这个事务,并成功写入到本地 relay 日志中就算成功。
主机宕机后,数据可能丢失:使用半同步复制,确保事务提交后至少传输到一个从库
从库只有一个sql Thread,主库写压力大,复制很可能延时:从库多线程apply binlog,解决从库复制延迟的问题。
当单表的数据量达到1000W或100G以后,优化索引、添加从库等可能对数据库性能提升效果不明显,此时就要考虑对其进行切分了。切分的目的就在于减少数据库的负担,缩短查询的时间。
数据切分可以分为两种方式:垂直划分和水平划分。
垂直划分:
垂直划分数据库是根据业务进行划分,例如购物场景,可以将库中涉及商品、订单、用户的表分别划分出成一个库,通过降低单库的大小来提高性能。同样的,分表的情况就是将一个大表根据业务功能拆分成一个个子表,例如商品基本信息和商品描述,商品基本信息一般会展示在商品列表,商品描述在商品详情页,可以将商品基本信息和商品描述拆分成两张表。
水平划分:
水平划分是根据一定规则,例如时间或id序列值等进行数据的拆分。比如根据年份来拆分不同的数据库。每个数据库结构一致,但是数据得以拆分,从而提升性能。