mysql总结

MyiSAM和innodb

MyiSAM:非聚集索引、B+树、叶子结点保存data地址;

innodb:聚集索引、B+树、聚集索引中叶子结点保存完整data,innodb非聚集索引需要两遍索引,innoDB要求表必须有主键;

innodb为什么要用自增id作为主键:

自增主键:顺序添加,页写满开辟新的页;

非自增主键(学号等):主键值随机,有碎片、不够紧凑的索引结构;

分库与分表设计、分片:

水平分表

垂直分表:不常用的加入另一张表、大文本字段单独拆分到另一张表、不经常修改的字段放入另一张表;

聚集索引与非聚集索引:

聚集索引:聚集索引查找完整数据;

非聚集索引:查找对应的主键值,然后根据主键值查找聚集索引,查找到完整数据

事务四大特性(ACID):

原子性:一个事务中的所有操作,要么全部完成,要么全部不完成,在执行过程中发生错误,会发生回滚(rollback);

一致性:事务开始前和结束后,数据库的完整性没有被破坏;

隔离性:多个事务执行,防止多个事务之间由于交叉执行而导致数据不一致。读未提交、读提交、可重复度、串行化。

持久性:事务提交后,对数据库的修改是永久的。

事务的并发?事务隔离级别,每个级别会引发什么问题,MySQL默认是哪个级别?

脏读:一个事务处理过程中读到了另一个事务未提交的数据;

不可重复读:一个事务多次读取一个数据,获得不同的数据结果;

幻读:一个事务读的过程中,另一个事务删除或者增加一条数据,影响这条事务的读的结果。

Mysql级别:可重复读

事务隔离级别:

读未提交:读取未提交的数据,脏读;

不可重复读:事务A多次读取同一数据,事务B在该过程中对数据进行修改并提交,导致A多次读取数据不一致;

可重复读:同一事务里,多次读操作结果一致,但是存在幻读;

串行化:事务并发,一个个按顺序执行。

MySQL常见的存储引擎InnoDB、MyISAM的区别?

MyISAM:事务×,锁级别:表级锁,存储表总行数,非聚集索引;

(适用于插入不频繁,查询频繁)

InnoDB:事务,锁级别:行级锁和外键约束,不存储表总行数,聚集索引;

(可靠性要求比较高,或要求事务,表更新和查询都频繁)

数据库三范式,根据某个场景设计数据表?优缺点
  • 所有字段值都是不可分解的原子值。
  • 在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
  • 数据表中的每一列数据都和主键直接相关,而不能间接相关。
第一范式(确保每列保持原子性):

表中字段值不可再分,提高数据库性能;

第二范式(确保表中的每列都和主键相关):

第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。比如要设计一个订单信息表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键。

第三范式(确保每列都和主键列直接相关,而不是间接相关):

比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段。

优点:可以尽量得减少数据冗余 缺点:对于查询需要多个表进行关联,更难进行索引优化 反范式化: 优点:可以减少表得关联 缺点:数据冗余以及数据异常

Explain关键字:

table:当前语句访问的表;

id:id相同,顺序执行,id越大,执行优先度越高;

select_type:小查询语句扮演的角色,比如SIMPLE、PRIMARY、UNION等。

type表示MySQL在表中找到所需行的方式,又称”访问类型“。

常见类型:NULL,system,const,eq_ref,ref,range,index,ALL

(性能由好到差)

ALL:遍历全表;

EXPLAIN SELECT * FROM s1;

index:只遍历索引树;

EXPLAIN SELECT key_part2 FROM s1 WHERE key_part3 = 'a';

range:检索给定范围的行;

EXPLAIN SELECT * FROM s1 WHERE key1 IN ('a', 'b', 'c');

ref:表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值;

eq_ref:类似ref,区别:唯一索引;

const、system:查询优化时,转换为常量;system:只查询一行;

# const
EXPLAIN SELECT * FROM s1 WHERE id = 10005;
# system
INSERT INTO t VALUES(1);

NULL:不需要访问表。

rows:预估的需要读取的记录条数,值越小越好

key_len :

实际使用到的索引长度 (即:字节数)

帮你检查是否充分的利用了索引值越大越好,主要针对于联合索引,有一定的参考意义。

MVCC多版本并发控制(Multiversion Concurrency Control):

InnoDB中实现MVCC机制;

快照读当前读

快照读:不加锁的简单的 SELECT 都属于快照读;

当前读:读取的记录进行加锁;

MVCC:包括:隐藏字段Undo LogRead View

隐藏字段:当前事务id,undo指针(指向历史版本的当前记录);

Undo Log:undo日志,通过undo指针串联历史版本;

ReadView:在查询时创建,

包含:

创建这个Read View的事务ID;

当前活跃的事务id列表

活跃事务最小事务ID;

系统事务最大ID(并不一定是活跃的);

Read View规则:判断当前查询事务与Read View中最小事务的关系,

如果小于最小活跃ID,那么说明当前读取的行已提交;

如果大于最大ID,说明当前的行是由一个活跃的事务还未提交,正在处理,需要按照Undo Log往下找,找到不在活跃事务id列表中的最新的提交的数据。

简而言之:每一行存储历史信息,查找时获取当前活跃id,找到历史信息中最新的,并且不在活跃id的事务。

处理读已提交:

每次select时创建一个新的Read View;

处理可重复读:

每次同样的select只在最初的select创建一个Read View;

索引优化:

优化的角度:

  • 索引失效、没有充分利用到索引——建立索引
  • 关联查询太多JOIN(设计缺陷或不得已的需求)——SQL优化
  • 服务器调优及各个参数设置(缓冲、线程数等)——调整my.cnf
  • 数据过多——分库分表
索引失效情况:

最左前缀:MySQL可以为多个字段创建索引,一个索引可以包含16个字段。对于多列索引,过滤条件要使用索引必须按照索引建立时的顺序,依次满足,一旦跳过某个字段,索引后面的字段都无法被使用。如果查询条件中没有用这些字段中第一个字段时,多列(或联合)索引不会被使用。

递增主键:减少页分裂,不用随机字段作为主键。

计算、函数、类型转换(自动或手动)导致索引失效

函数失效

# 使用like
EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE student.name LIKE 'abc%';
# 使用函数
EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE LEFT(student.name,3) = 'abc';
# 创建索引之后
CREATE INDEX idx_name ON student(NAME);

函数将导致索引失效;

计算失效

# 创建索引
CREATE INDEX idx_sno ON student(stuno);
# 查询时使用计算
EXPLAIN SELECT SQL_NO_CACHE id, stuno, NAME FROM student WHERE stuno+1 = 900001;

导致索引失效;

类型转换失效

# 未使用到索引
# name的类型为字符串,下面发生了类型转换,导致失效
EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE name=123;

# 使用到索引
EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE name='123';

范围条件右边的列索引失效

SELECT SQL_NO_CACHE * FROM student
WHERE student.age=30 AND student.classId>20 AND student.name = 'abc' ;

idx_age_classId_name索引将会失效,因为ID>20作为范围条件,导致右侧的name失效。

除非如下修改,将ID>20放到最后:

create index idx_age_name_classId on student(age,name,classId);
EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE student.age=30 AND student.name = 'abc' AND student.classId>20;

不等于(!= 或者<>)索引失效;

is null可以使用索引,is not null无法使用索引;

like以通配符%开头索引失效

OR 前后存在非索引的列,索引失效

OR前后的两个条件中的列都是索引时,查询中才使用索引。

查询优化:

① 尽可能的使用联合索引而不是索引的组合;

②创建索引尽量让辅助索引进行索引覆盖 而不是回表;

③在可以使用主键id的表中,尽量使用自增主键id,这样可以避免页分裂;

④查询的时候尽量不要使用select * ,这样可以避免大量的回表;

⑤尽量少使用子查询,能使用外连接就使用外连接,这样可以避免产生笛卡尔集;

⑥能使用短索引就使用短索引,这样可以在非叶子节点存储更多的索引列降低树的层高,并且减少空间的开销;

原文链接:https://www.cnblogs.com/maxzhangxiaotao/p/17222892.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:mysql总结 - Python技术站

(0)
上一篇 2023年4月17日
下一篇 2023年4月17日

相关文章

  • 对于mysql的query_cache认识的误区

    标题:对于MySQL的query_cache的认识误区 MySQL的query_cache是一个在内存中缓存查询结果的机制,可以极大地提升查询效率。然而,有些人对query_cache存在一些错误的认识,这里我将列举一些常见的误区。 误区一:query_cache会自动适应场景 有些人认为,只要开启了query_cache, MySQL就会自动判断什么时候缓…

    MySQL 2023年5月19日
    00
  • mysql 恢复数据时中文乱码

    mysql恢复数据时中文乱码,解决办法。 用source命令导入mysql数据库怎么设置中文编码 1.导出数据时指定编码在导出mysql sql执行文件的时候,指定一下编码格式: mysqldump -uroot -p –default-character-set=utf8 mo(dbname) > E://xxxx.sql 2.导入数据时指定编码 …

    MySQL 2023年4月12日
    00
  • 读《mysql是怎样运行的》有感

    最近读了一本书《mysql是怎样运行的》,读完后在大体上对mysql的运行有一定的了解。在以前,我对mysql有以下的为什么: InnoDB中的表空间、段、区和页是什么? redo log为什么就能实现事务的持久性? 到底什么是意向锁?意向锁有什么用? mysql中的外连接、内连接到底是什么? 事务中的一致性到底是什么意思?一致性和原子性有什么不一样? 现在…

    MySQL 2023年4月23日
    00
  • Mysql 数据库 基础代码

    — 创建数据库 CREATE DATABASE book; — 创建作者表 CREATE TABLE authors( Id int not NULL, — 作者编号 Fname VARCHAR(10), — 姓 Lname VARCHAR(12), — 名 Sex CHAR(2), Sage int ); — 创建图书表 CREATE tabl…

    MySQL 2023年4月13日
    00
  • MySQL命令行界面中出现字符错误提示的原因及解决方法

    当我们在MySQL命令行进程中进行操作时,有时会出现字符错误的提示,这主要是由于终端的字符集和MySQL服务器的字符集不匹配所造成的。在这种情况下,需要对终端的字符集和MySQL服务器的字符集进行相应的设置,下面就详细讲解一下如何解决这个问题。 确定终端支持的字符集 在终端中输入以下命令,可以查看当前终端支持的字符集: $ locale charmap 执行…

    MySQL 2023年5月18日
    00
  • MySQL数据库INNODB表损坏修复处理过程分享

    MySQL数据库INNODB表损坏修复处理过程分享 背景 MySQL数据库中使用INNODB存储引擎的表,可能会因为各种原因出现损坏导致无法正常访问,这会给网站运营和管理带来很大影响,因此需要快速处理。下面分享一下INNODB表损坏修复的过程。 前置条件 在开始修复INNODB表之前,需要准备以下工具和环境: MySQL数据库客户端 确认INNODB存储引擎…

    MySQL 2023年5月18日
    00
  • php如何查询MySQL的8条数据

    这篇文章主要介绍“php如何查询MySQL的8条数据”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“php如何查询MySQL的8条数据”文章能帮助大家解决问题。 PHP是一款非常流行并且实用的编程语言,它可以用于各种不同的项目,从简单Java应用程序到大型Web应用程序。对于许多网站工程师来说,查询数据库中的数据是一个…

    MySQL 2023年4月10日
    00
  • MySQL Version确认问题(版本确认)

    MySQL是一个非常流行的关系型数据库管理系统,版本确认问题是使用MySQL时需要注意的重要问题之一。在确认MySQL版本时,我们需采取以下步骤: 步骤一:登录 MySQL 我们需要使用命令行工具来访问MySQL数据库,输入以下命令并按下回车键: mysql -u 用户名 -p 密码 其中,用户名和密码是你MySQL数据库的登录信息。登录成功后,系统会提示输…

    MySQL 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部