常见的命令

  1. SELECT:用于从一个或多个表中检索数据。例如:SELECT column_name FROM table_name;
  1. INSERT INTO:用于向表中插入新的行。例如:INSERT INTO table_name (column1, column2) VALUES (value1, value2);
  1. UPDATE:用于修改表中的数据。例如:UPDATE table_name SET column1 = value1 WHERE condition;
  1. DELETE:用于从表中删除数据。例如:DELETE FROM table_name WHERE condition;
  1. CREATE DATABASE:用于创建新数据库。例如:CREATE DATABASE database_name;
  1. CREATE TABLE:用于创建新表。例如:CREATE TABLE table_name (column1 datatype, column2 datatype);
  1. DROP DATABASE:用于删除数据库。例如:DROP DATABASE database_name;
  1. DROP TABLE:用于删除表。例如:DROP TABLE table_name;
  1. ALTER TABLE:用于修改表结构,如添加或删除列。例如:ALTER TABLE table_name ADD column_name datatype;
  1. JOIN:用于结合两个或多个表的行。例如:SELECT columns FROM table1 INNER JOIN table2 ON table1.column = table2.column;

索引的结构分类

【数据结构】:B+树索引,hash索引,Full-text索引
【物理存储】:主键索引(叶子节点存放的是实际数值),二级索引(叶子节点存放的是主键值)
【字段特性】:唯一索引(建立在 UNIQUE 字段上的索引),主键索引(建立在主键字段上的索引),前缀索引(字符串的前几个字符建立索引),普通索引(建立在普通字段上的索引)
【字段个数】:单列索引,联合索引 (多列的索引是联合索引)
联合索引:CREATE INDEX index_product_no_name ON product(product_no, name);
主键索引:id bigint not null primary key AUTO_INCREMENT,
普通索引:name VARCHAR(128) not null,
唯一索引:constraint uq_nickname unique(nickname)

导致索引失效的原因:

1.使用左右模糊匹配
2.查询条件中对索引做了计算,函数,类型转换
3.where子句中,or前是索引,or后不是索引,那索引会失效
4.联合索引遵循最左匹配原则

索引优化:

覆盖索引优化:尽量从二级索引中查询,避免查询主表(可以创建一个联合索引)
前缀索引优化:减少索引项的大小
主键索引是递增的:插入新纪录都是追加操作,若非递增可能会造成页分裂,内存碎片等问题
防止索引失效
 
notion image

为什么采用B+树?

1.B+树的非叶子节点不存放数据,只存放索引,因此在数据量相同的情况下,会比B树高度更低,IO查询的次数也会更少,其复杂度是0(logdN),d是允许的最大子节点数
2.B+树有大量的冗余节点,这些节点让B+树的插入删除效率都更高,删除根节点没有B树那么复杂
3.B+树叶子节点之间用双向链表连接起来,便于范围查询,B树只能遍历整个树
4.hash表不适合做范围查询
5.二叉树的节点只有两个,意味着其搜索复杂度要比B+树高很多

事务的性质:

  • 原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节,而且事务在执行过程中发生错误,会被回滚到事务开始前的状态,
  • 一致性(Consistency):是指事务操作前和操作后,数据满足完整性约束,数据库保持一致性状态。比如,用户 A 和用户 B 在银行分别有 800 元和 600 元,总共 1400 元,用户 A 给用户 B 转账 200 元,分为两个步骤,从 A 的账户扣除 200 元和对 B 的账户增加 200 元。一致性就是要求上述步骤操作后,最后的结果是用户 A 还有 600 元,用户 B 有 800 元,总共 1400 元,而不会出现用户 A 扣除了 200 元,但用户 B 未增加的情况(该情况,用户 A 和 B 均为 600 元,总共 1200 元)。
  • 隔离性(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致,因为多个事务同时使用相同的数据时,不会相互干扰,每个事务都有一个完整的数据空间,对其他并发事务是隔离的。
  • 持久性(Durability):事务处理结束后,对数据的修改就是永久的
持久性是通过 redo log (重做日志)来保证的;
原子性是通过 undo log(回滚日志) 来保证的;
隔离性是通过 MVCC(多版本并发控制) 或锁机制来保证的;
一致性则是通过持久性+原子性+隔离性来保证;

并发事务引起的问题

1.脏读:读到其他事务未提交的数据;
2.不可重复读:一个事务内多次读取一个数据,前后读取的数据不一致;
3.幻读:前后读取的记录数量不一致。
SQL提出了四种隔离级别来规避这些现象
读未提交:3种情况都有可能发生
读提交:不可重复读,幻读
可重复读:数据一直一致,默认隔离级别,在这个级别下处理幻读,引入了next-key锁
串行化:会对记录加上读写锁

Mysql有哪些锁?

根据加锁的范围,可以分为全局锁、表级锁和行锁三类。
全局锁:执行后整个数据库都变成只读状态,应用于做全库逻辑备份
表级锁:
  • 表锁 —-给表加读写锁
  • 元数据锁—不需要显示调用的,会自动给这个表加上 MDL,在事务提交后释放
对一张表进行CRUD 操作时,加的是 MDL 读锁
对一张表做结构变更操作的时候,加的是 MDL 写锁;
  • 意向锁—-主要目的并不是为了阻止其他事务对表进行访问,而是为了告诉其他事务:“我有意在这个表的某行上设置一个锁”。这样另一个事务想要上锁的时候,可以通过检查意向锁来快速知道是否有记录被加锁
  • AUTO-INC 锁—主键自增就算靠自增锁实现的,其特性是:不是在事务提交后释放,而是在插入语句后立刻释放
行级锁:
记录锁:也就是仅仅把一条记录锁上
间隙锁:锁定一个范围,但是不包含记录本身;
Next-Key Lock:Record Lock + Gap Lock 的组合,锁定一个范围,并且锁定记录本身
 
如果两个事务分别向对方持有的间隙锁范围内插入一条记录,而插入操作为了获取到插入意向锁,都在等待对方事务的间隙锁释放,于是就造成了循环等待,满足了死锁的四个条件:互斥、占有且等待、不可强占用、循环等待,因此发生了死锁
死锁的解决办法:
1.设置事务等待锁超时时间,如果超时就回滚
2.主动开启死锁检测
 
Camellia
Camellia
明天会更好吗?🍚
公告
type
status
date
slug
summary
tags
category
icon
password
这里是一个个人博客
用于记录和分享生活