数据库

1.存储引擎

数据库底层软件组织,不同引擎提供不同存储机制,索引技巧,锁定水平等功能,使用不同的存储引擎可以获得特定功能。
MyIASM InnoDB Memory Archive Federated

show engines

1.1 MyIASM

MySQL默认引擎,没有提供事务支持,行级锁,外键。
插入更新需要锁定整个表,效率低
读取速度快,不占用大量内存,存储资源,ISAM静态索引结构

  • 非聚集索引,数据文件分类,保存是数据文件指针,主键索引和辅助索引独立。
  • 保存整个表行数
  • 支持全文索引

1.2 Memory

Heap堆内存,使用在内存的内容创建表,每个表只实际对应一个磁盘文件,访问非常快,默认使用Hash索引
服务关闭,表内数据丢失,支持散列索引和B树索引,B树索引可以使用部分查询和通配查询,也可以使用><=等操作,散列索引较快但是对于比较较慢

1.3.InnDB

底层为B+树,B树每个节点对应innodb的一个page,page大小固定16k,只有非叶子结点有键值,叶子节点包含完成数据
场景适用:

  • 经常更新的表,适合处理多重并发的更新请求
  • 支持事务,每一条默认成事务默认提交,影响速度,最好吧多个语句用begin和commit之间组成事务
  • 可以从灾难中恢复(bin-log日志)
  • 外键约束 只有它支持外键
  • 自增列 auto_increment
  • 聚集索引:数据文件和索引绑在一起,必须有主键,效率高。但是辅助索引需要俩次查询,先查主键,再通过主键查数据,主键不能过大,否则索引很大
  • 不保存表行数 count需要全表扫描
  • 不支持全文索引

2.索引

MySQL高效获取数据的数据结构。

2.1 分类

  • 主键索引(PRIMARY):数据列不允许重复,NULL
  • 唯一性索引(UNIQUE):值唯一,不重复
alter table name
add unique (column1,c2)
  • 全文索引(FULLTEXT)
  • 普通索引(INDEX)
  • 联合索引 create index 索引名 on 表名(字段名1,字段名2)

2.2 索引失效

  • 不满足最左匹配原则:设置联合索引(c1,c2,c3),where 查询时顺序,只要最左边有c1,c2 c3无论有没有都会走索引
  • select *
  • 索引列有计算,函数
  • 字段类型不同 varchar类=100
  • like左边有%
  • 列对比:cl = c2
  • or 前后都要索引
  • not in关键字查询数据范围,而普通索引字段使用了not in关键字查询数据范围,索引会失效。主键字段不会
  • not exists 失效
  • order by 字段满足最左匹配且后面加了limit关键字, 配合where字段满足最左匹配,排序规则一致
    不加 where limit, 不是联合索引(失效)

2.3 大表加索引

  • 在线无锁加索引
    ALTER TABLE tbl_name ADD PRIMARY KEY (column), ALGORITHM=INPLACE, LOCK=NONE;
  • 影子拷贝
    1、创建一张和原表结构一样的空表,只是表名不一样
    create table tb_name_tmp like tb_name;
    2、把新建的空表非主键索引都删掉,因为这样在往新表导数据的时候效率会很快(因为除了必要的主键以外,不用再去建立其它索引数据了)
    alter tb_name_tmp drop index index_name;
    3、从旧表往主表里导数据,如果数据太大,建议分批导入,只需确保无重复数据就行,因为导入数据太大,会很占用资源(内存,磁盘io, cpu等),可能会影响旧表在线上的业务。
    insert into tb_name_tmp select * from tb_name where id between start_id and end_id;
    4、数据导完后,再对新表进行添加索引
    create index index_name on tb_name_tmp(column_name);
    5、当大部分数据导入后,索引也建立好了,但是旧表数据量还是会因业务的增长而增长,这时候为了确保新旧表的数据一至性和平滑切换,建议写一个脚本,判断当旧表的数据行数与新表一致时,就切换。
    rename table tb_name to tb_name_tmp1;

3.事务

3.1 特性

  • 原子性:事务是一个完整操作
  • 一致性:事务完成,数据必须一致
  • 隔离性:并发事务隔离,事务必须独立
  • 永久性:事务完成后,修改永久保持

3.2 并发事务问题

  • 脏读: 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。
  • 丢失修改: 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。 例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。
  • 不可重复读: 指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。重点在数据修改
  • 幻读: 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。重点在记录个数变化

3.3 事务隔离级别

  • READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
  • READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
  • REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
  • SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
  • innoDB 事务隔离级别可重读,使用Next-Key Lock算法,避免幻读产生。在分布式事务中用到可串行化隔离级别

4.存储过程

一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过
程是数据库中的一个重要对象。

5.触发器

触发器是一段能自动执行的程序,是一种特殊的存储过程,触发器和普通的存储过程的区别是:
触发器是当对某一个表进行操作时触发。诸如:update、insert、delete 这些操作的时候,系统会自动调用执行该表上对应的触发器。SQL Server 2005 中触发器可以分为两类:DML 触发器和DDL 触发器,其中DDL 触发器它们会影响多种数据定义语言语句而激发,这些语句有create、alter、drop 语句。

6.并发策略

6.1 乐观锁

6.2 悲观锁

  • 排它锁 写锁
  • 共享锁 读锁

6.3 时间戳

单独加一列时间戳。每次读时,对该字段加一,提交前,进行比对,如果比数据库值大,允许保存,否则不允许。

7.数据库锁

7.1 行级锁

排它锁,防止其他事务修改此行

7.2 表级锁

对整张表加锁

7.3 页级锁

锁定粒度介于行级锁和表级锁中间一种

8.视图

视图是一种虚拟的表,具有和物理表相同的功能。可以对视图进行增,改,查,操作,试图通常是有一个表或者多个表的行或列的子集。对视图的修改不影响基本表。它使得我们获取数据更容易,相比多表查询。

posted @ 2023-08-24 13:56  lwx_R  阅读(2)  评论(0编辑  收藏  举报