mysql

事务的四大特性

ACID

  • 原子性(atomicty) 事务包含的所有操作要么全部成功,要么全部失败回滚.

原子性不能保证一致性, 因为即使每个事务都符合原子性, 但是整体结果不能满足一致性(比如,事务2可能覆盖事务1的结果, 比如给A转账100元的事物,B也转入100元, 理论上是需要转入200元, 转入100元就满足原子性, 但是不满足一致性.)

  • 一致性(consistency)

一致性是最基本的属性,其它的三个属性都为了保证一致性而存在的. 更趋向于业务相关.(比如转账, 帐户A转一笔钱到帐户B上,如果帐户A上的钱减少了,而帐户B上的钱却没有增加,那么我们认为此时数据处于不一致的状态.)

  • 隔离性(isolation) 保证并发情况下的一致性,引入了隔离性.

实现就是两种锁, 悲观-每个操作的前后都加锁(保证并发情况下的一致性,引入了隔离性)
乐观锁, 不同的事务可以同时看到同一对象(一般是数据行)的不同历史版本(通过日志UNDO的方式来获取数据行的历史版本;内存中保存同一数据行的多个历史版本,通过时间戳来区分)

  • 持久性(durability)数据库中的数据的改变就是永久性的

三大范示

  • 1NF 数据库表字段的原子性, 不可拆分
  • 2NF 1NF的基础上, 非主键必须依赖完整主键, 而不是主键的一部分
  • 3NF 2NF的基础上, 非主键必须直接依赖主键, 不能存在传递依赖

事务隔离级别

不考虑隔离性的时候,可能导致脏读、幻读和不可重复读的问题

  • 脏读: 读到还没提交的
  • 幻读: 一个事务内的读取操作的结论不能支撑之后业务的执行
  • 不可重复读: 一个事务期间读的两次结果不同

MySQL数据库为我们提供的四种隔离级别:

  • Serializable (串行化)
  • Repeatable read (可重复读), 解决事务并发不可重复读问题, Mysql默认
  • Read committed (读已提交), 只能读取已经提交的, 解决了脏读
  • Read uncommitted (读未提交),

mysql 查看和设置隔离级别

select @@transaction_isolation;
set session transaction isolation level read uncommitted;

生产环境的隔离级别
** RC(Read Commited)**

在RR隔离级别下,存在间隙锁,导致出现死锁的几率比RC大的多; 在RR隔离级别下,条件列未命中索引会锁表!而在RC隔离级别下,只锁行.
结论是RC的并发性高于RR

utf8和utf8mb4

utf8mb4_general_ci ,挨个字符进行比较(general),并且不区分大小写(_ci,case insensitice)
utf8mb4_bin, 比较二进制

索引

索引是存储引擎用于提高数据库表的访问速度的一种数据结构。

优缺点:

  • 优点:加快数据查找的速度; 加快分组和排序的速度,加快表与表之间的连接
  • 缺点:占用物理空间; 动态维护索引,增删改时间变长.

不需要索引的场景:

  • where用不到
  • 表记录较少
  • 经常增删改查需要评估
  • 参与列计算
  • 区分度不高的字段不适合建立索引,如性别,只有男/女/未知三个值。加了索引,查询效率也不会提高。

索引的数据结构:

InnoDB引擎的索引类型有B+树索引和哈希索引,默认的索引类型为B+树索引

B+数
二分法
B+树的节点只存储索引key值,具体信息的地址存在于叶子节点的地址中,相邻的叶子节点之间是通过链表指针连起来的;而B+树则需要通过索引找到叶子结点中的数据才结束, 而B+树关键字可以出现多次。

Hash索引
基本用于精确查找, 由于hash的特点, 不支持排序,不支持范围查找, 不支持模糊查询, 会存在hash冲突.

索引的分类

主键索引;唯一索引(只有null可以多值);组合索引;全文索引(类char可用);普通索引

索引的最左匹配

如果用到了组合索引中的最左边的索引,那么这条 SQL 语句就可以利用这个组合索引去进行匹配。当遇到范围查询(>、<、between、like)就会停止匹配

聚集索引

InnoDB使用表的主键构造主键索引树,同时叶子节点中存放的即为整张表的记录数据。聚集索引叶子节点的存储是逻辑上连续的,使用双向链表连接,叶子节点按照主键的顺序排序,因此对于主键的排序查找和范围查找速度比较快。

覆盖索引

select的数据列只用从索引中就能够取得,不需要回表进行二次查询,也就是说查询列要被所使用的索引覆盖

# 在查询前面使用explain,输出的extra列会显示为using index。
explain select blog_id from user_like where user_id = 13;
# explain结果的Extra列为Using where; Using index

设计原则

  • 区分度越高越值得用索引
  • 尽量使用短索引
  • 索引不是越多越好
  • 利用最左前缀原则

索引实效

%开头的like查询如%abc; 查询条件中列类型是字符串,没有使用引号(类型转化导致); 索引列!=; 索引列计算;查询条件使用or连接

前缀索引

// email列创建前缀索引
ALTER TABLE table_name ADD KEY(column_name(prefix_length));

索引下推

索引条件下推,也叫索引下推,英文全称Index Condition Pushdown,简称ICP。
存储部分做部分筛选工作.

MyISAM和InnoDB的区别

  1. 是否支持行级锁 : MyISAM 只有表级锁,而InnoDB 支持行级锁和表级锁,默认为行级锁。
  2. 是否支持事务和崩溃后的安全恢复: MyISAM 不提供事务支持。而InnoDB提供事务支持,具有事务、回滚和崩溃修复能力。
  3. 是否支持外键:MyISAM不支持,而InnoDB支持。
  4. 是否支持MVCC :MyISAM不支持,InnoDB支持。应对高并发事务,MVCC比单纯的加锁更高效。
  5. MyISAM不支持聚集索引,InnoDB支持聚集索引。

MVCC

MVCC(Multiversion concurrency control) 就是同一份数据保留多版本的一种方式,进而实现并发控制。在查询的时候,通过read view和版本链找到对应版本的数据。

快照读和当前读

表记录有两种读取方式。

  • 快照读:读取的是快照版本。普通的SELECT就是快照读。通过mvcc来进行并发控制的,不用加锁。
  • 当前读:读取的是最新版本。UPDATE、DELETE、INSERT、SELECT … LOCK IN SHARE MODE、SELECT … FOR UPDATE是当前读。

在快照读情况下,MySQL通过mvcc来避免幻读。
在当前读情况下,MySQL通过next-key来避免幻读(加行锁和间隙锁来实现的)。

InnoDB通过mvcc机制避免了幻读现象。而mvcc机制无法避免当前读情况下出现的幻读现象。

共享锁和排他锁

select * from table where id<6 lock in share mode;--共享锁
select * from table where id<6 for update;--排他锁

# bin /redo /undo log
bin 数据库级别. 
redo log是innodb引擎级别,记录innodb存储引擎的事务日志,innodb_flush_log_at_tx_commit设置为1,执行commit时会将redo log同步写到磁盘.
undo log
undo log用于数据的撤回操作,它保留了记录修改前的内容。

Mysql架构

Server 层: 连接器, 查询缓存, 分析器,优化器, 执行器
存储引擎

分库分表

垂直划分:
比如, 10列分成4列和6列
业务进行划分
水平划分

缺点: 分片事务一致性难以解决; 跨节点join性能差,逻辑复杂;数据分片在扩容时需要迁移

分区表

1张表的数据分成N多个区块,分区一般都是放在单机里的,用的比较多的是时间范围分区,方便归档。只不过分库分表需要代码实现,分区则是mysql内部实现。
range分区
list分区
hash分区

processlist

show processlist 或 show full processlist 可以查看当前 MySQL 是否有压力,正在运行的SQL,有没有慢SQL正在执行。返回参数如下:

id:线程ID,可以用kill id杀死某个线程
db:数据库名称
user:数据库用户
host:数据库实例的IP
command:当前执行的命令,比如Sleep,Query,Connect等
time:消耗时间,单位秒
state:执行状态,主要有以下状态:
Sleep,线程正在等待客户端发送新的请求
Locked,线程正在等待锁
Sending data,正在处理SELECT查询的记录,同时把结果发送给客户端
Kill,正在执行kill语句,杀死指定线程
Connect,一个从节点连上了主节点
Quit,线程正在退出
Sorting for group,正在为GROUP BY做排序
Sorting for order,正在为ORDER BY做排序


info:正在执行的SQL语句


其他细节

  1. 查询语句执行流程: 权限校验、查询缓存、分析器、优化器、权限校验、执行器、引擎
  2. 更新语句执行过程: 分析器、权限校验、执行器、引擎、redo log(prepare状态)、binlog、redo log(commit状态)
  3. exist和in的区别, exists用于对外表记录做筛选, 循环外表记录。in是循环内表.
  4. int(10)和char(10) 显示数据的长度,而char(10)表示的是存储数据的长度.
  5. 深分页怎么优化
    limit 500000, 10 会取出500010数据丢弃500000条
select * from xxx order by id limit 500000, 10;
使用下面的
select * from xxx  where id >=(select id from xxx order by id limit 500000, 1) order by id limit 10;
select * from xxx  where id >=500000 order by id limit 10;
  1. 高度3的b+数, 可以存2千万条数据, 所以在 InnoDB 中B+树高度一般为3层时,就能满足千万级的数据存储。

posted on 2022-08-01 14:45  WillingCPP  阅读(24)  评论(0)    收藏  举报

导航