jjzjj

mysql总结

maxzhangxiaotao 2023-04-05 原文
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 * ,这样可以避免大量的回表;

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

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

有关mysql总结的更多相关文章

  1. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  2. SPI接收数据异常问题总结 - 2

    SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手

  3. ruby-on-rails - 无法安装 mysql2 0.3.14 gem - 2

    我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby​​目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin

  4. ruby - 如何使用 ruby​​ mysql2 执行事务 - 2

    我已经开始使用mysql2gem。我试图弄清楚一些基本的事情——其中之一是如何明确地执行事务(对于批处理操作,比如多个INSERT/UPDATE查询)。在旧的ruby-mysql中,这是我的方法:client=Mysql.real_connect(...)inserts=["INSERTINTO...","UPDATE..WHEREid=..",#etc]client.autocommit(false)inserts.eachdo|ins|beginclient.query(ins)rescue#handleerrorsorabortentirelyendendclient.commi

  5. Simulink方法总结和避坑指南(一)——Simulink入门与基本调试方法 - 2

    文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景  最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。  在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记

  6. ruby-on-rails - 当我通过 rvm 使用 rails3 时,如何在 ubuntu 上安装 mysql2 gem? - 2

    我正在尝试绕过rails配置这个极其复杂的迷宫。到目前为止,我设法在ubuntu上设置了rvm(出于某种原因,ruby在ubuntu存储库中已经过时了)。我设法建立了一个Rails项目。我希望我的测试项目使用mysql而不是mysqlite。当我尝试“rakedb:migrate”时,出现错误:“!!!缺少mysql2gem。将其添加到您的Gemfile:gem'mysql2'”当我尝试“geminstallmysql”时,出现错误,告诉我需要为安装命令提供参数。但是,参数列表很大,我不知道该选择哪些。如何通过在ubuntu上运行的rvm和mysql获取rails3?谢谢。

  7. Centos7-yum安装mysql-修改密码-无密码登录-安全配置 - 2

    目录1、yum安装mysql修改密码(1)在mysql里面修改(2)第二种方式,利用mysqladmin修改密码2、没有密码,登录mysql修改密码3、mysql的安全设置1、yum安装mysql在CentOS中默认安装有MariaDB(MySQL的一个分支),安装完成之后可以直接覆盖MariaDB。rpm-qa|grepmariadb查询是否安装了mariadbrpm-e--nodepsmariadb-libs-5.5.60-1.el7_5.x86_64卸载mariadwgethttp://dev.mysql.com/get/mysql57-community-release-el7-11.

  8. ruby - 安装 dm-mysql-adapter 时出错 - 2

    我是Ruby的新手。我安装了DataMapper并且正在尝试安装dm-mysql-adapter-1.0.2gem。但是当我尝试安装时,出现以下错误。我正在使用ubuntu操作系统。vinoth@vinoth-laptop:~/Downloads$geminstalldm-mysql-adapter-1.0.2----with-mysql-lib=/usr/lib/mysql----with-mysql-conf=/usr/bin/mysqlWARNING:Installingto~/.gemsince/home/vinoth/gemsand/home/vinoth/gems/bina

  9. ruby-on-rails - gem 列表中的 mysql2 gem 但获取项目找不到 gem - 2

    我目前正在构建一个需要mysql2gem的RoR项目。我成功安装了gem。因为它出现在我的gem列表中。[root@vc2cmmka035538nsimple_cms]#gemlist***LOCALGEMS***actionmailer(3.2.3)actionpack(3.2.3)activemodel(3.2.3)activerecord(3.2.3)activeresource(3.2.3)activesupport(3.2.14,3.2.3)arel(3.0.2)bigdecimal(1.1.0)builder(3.2.2,3.0.0)bundler(1.1.5)c2c_li

  10. ruby - 如何在 heroku 中使用自己的 mysql 数据库服务器? - 2

    我想使用托管在我自己服务器上的mysql数据库。我已经更改了DATABASE_URL和SHARED_DATABASE_URL配置变量以指向我的服务器,但它仍在尝试连接到heroku的amazonaws服务器。我该如何解决? 最佳答案 根据Herokudocumentation,更改DATABASE_URL是正确的方法。Ifyouwouldliketohaveyourrailsapplicationconnecttoanon-Herokuprovideddatabase,youcantakeadvantageofthissamemec

随机推荐