学习MySQL-理论知识

文章目录

综述

数据库思维导图
MySQL思维导图

MySQL概述

关系型数据库 和 非关系型数据库区别?

概念不同:
关系型数据库 = 数据结构是表,由二维表及其之间的联系组成的一个数据组织;
非关系型数据库 = 更准确的表述是一种数据结构化存储方法的集合,可以是文档或键值对;

存储方式不同:
关系型数据库 = 表格式,存储数采用行和列的形式;
非关系型数据库 = 大块存储,像文档、键值对、图结构等;

数据的操作不同:
前者支持SQL语句,后者不支持;

MySQL 和 Oracle区别?

两者都是关系型数据库。

区别MySQLOracle
公司瑞典MySQL AB公司
又被sun收购
又被Oracle收购
甲骨文公司
类型中小型数据库大型数据库
费用开源免费收费
默认端口号33061521
数据库与用户关系一个用户对一个/多个数据库一个数据库对应多个用户
字段自增设置字段为auto increment创建序列sequence,添加 序列名.nextval()
字符varcharvarchar2
数字类型smallint(2字节)
int(4字节)
integer(int同义词)
bigint(8字节)
number
分页select * from table limit(start-1)*limit,limit
start 页码,limit是每页显示的条数
使用伪列rownum

对MySQL框架的了解?

MySQL可以分为 Server层 和 存储引擎 两部分。

  • Server层:
    包括MySQL的核心功能和内置函数;所有跨引擎的功能;

  • 存储引擎:
    数据的存储和提取。
    构件是插件式的。存储引擎有InnoDB、MyISAM、memory;
    MySQL5.5.5 默认是InnoDB,可以通过engine = MyISAM来指定存储引擎;
    在这里插入图片描述
    Server层组成部分介绍:

成员作用
连接器管理连接,权限验证
查询缓存命中则直接返回结果
分析器词法分析、语法分析
优化器执行计划生成,索引选择
执行器操作引擎,返回结果

一条SQL语句在数据库框架中的执行流程?

执行过程:

  • 应用程序把查询SQL语句发送给服务器端执行;
  • 检查缓存中是否存在该查询。存在,返回缓存中的结果;否则,执行下一步;
  • 分析器进行SQL的词法、语法分析,再由优化器生成对应的执行计划;
  • 执行器根据执行计划,调用存储引擎的接口进行查询;
  • 最终将查询结果返回给客户端。

数据库的三范式是什么?

使用原因:
设计数据库必须要遵循的规则,就好比一个部门、一个小组都会有其自己的规章制度一样,数据库的规章制度就是三范式;

分别是:所有域都是原子性的 = 所有的列都是不可拆分的,是原子数据项,而不是集合、数组、记录等非原子数据项;非主键约束依赖于主键约束 = 表示表中的数据可以被唯一的区分开来;任何非主属性不可以依赖其他非主属性 = 要求一个关系表中不能包括其他表非主属性;

具体介绍:

名字含义解释
第一范式(1NF)
原子性
所有域都应该是原子性的
每个列都是不可拆分的
数据库表的每一列都是不可分割的原子数据项,而不是集合、数组、记录等非原子数据项
实体的某个属性有多个值时,必须拆分为不同的属性
第二范式(2NF)
唯一性
非主键列完全依赖于主键列,不依赖于其他非主键要求数据库表中的每个实例或记录必须可以被唯一地区分
第三范式(3NF)
独立性
任何非主属性不依赖于其他非主属性要求一个关系中不包含其它关系已包含的非主键信息
举例:部门信息表中,主键=部门编号,其余信息有部门名称、部门简介等;员工信息表中列出部门编号后,不再列出部门名称、部门简介等信息

专业术语 或 关键词

DB:Database 数据库
DBMS:Database Management System 数据库管理系统
RDBMS:Relative Database Management System 关系型数据库管理系统
数据库:是表的集合,带有相关的数据;
表:一个表是一个数据的矩阵;
列(字段):一个列(数据元素)包含同一类型的数据;
行(记录):一组相关的数据;

MySQL问题排查都有哪些手段?

  • 使用 show processlist 命令查看当前所有连接信息;
    在这里插入图片描述
  • 使用 Explain 命令查询 SQL 语句执行计划;
    使用explain关键字分析你的查询语句或是表结构的性能瓶颈;
    explain 关键字后面跟着的是 查询语句。
    在这里插入图片描述
    十列参考网址
    命令执行后出来十二列,具体介绍如下:(介绍中只有十列)
列名含义
idselect查询的序列号,包含一组数字,表示查询中执行select子句 或 操作表的顺序
type访问类型
const:表示通过索引一次就找到了。用于比较primary key 或者 unique索引。
key显示实际决定使用的键
rows所需读取的行数
Extra包含MySQL解决查询的详细信息
select_type查询的类型,主要是用于区分普通查询、联合查询、子查询等复杂的查询
Simple = 普通查询;
table显示这一行数据是关于哪张表
possible_keys使用哪个索引,指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用
key_len索引中使用的字节数
ref显示索引使用哪一列
显示索引的哪一列被使用了,如果可能,是一个常量const
  • 开启慢查询日志,查看慢查询的 SQL。
    慢查询日志默认状态为OFF状态。(不知道为什么查询结果总是NO)
    在这里插入图片描述
  • 设置慢查询日志状态
    在这里插入图片描述
    相关参数说明:
参数名介绍
slow_query_log慢查询开启状态
slow_query_log_file慢查询日志存放的位置(这个目录需要MySQL的运行帐号的可写权限,一般设置为MySQL的数据存放目录)
long_query_time查询超过多少秒才记录
log_output输出方式,可以是file和table,当为file时会输出到slow_query_log_file文件,当为table时则会输出到mysql数据库中的slow_log表

备注

2022/6/24
MySQL服务启动:net start 服务名

MySQL数据库CPU飙升到500%的话如果处理?

以Linux系统背景介绍:
①通过Linux系统的top命令查看是否是mysqld占用导致;
不是—找出占用高的进程,进行处理;
是——通过show processlist查看正在运行的线程,是否存在消耗资源的SQL运行,看其执行计划是否正确、或者数据量是否很大;
②如果存在消耗资源的SQL运行,通过kill杀掉这些线程,进行相应的调整,再重新跑;
若每个SQL消耗资源都不多,只是同一时间大量的session连进来导致CPU飙升,再分析连接数增加的原因,做出相应的调整。

涉及命令:

命令说明
top实时查看系统进程
kill 进程id关闭进程

备注
mysqld 是计算机进程,是 mysql的守护进程,每次在使用mysql前必须先用它,用来执行客户程序提交的任务;

MySQL的redo log、undo log、bin log都是干什么的?

MySQL日志主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志几大类。
开发主要关注:二进制日志(bin log)、事务日志(undo log和redo log)。
日志被分为:逻辑日志和物理日志。
逻辑日志:记录的就是SQL语句。
物理日志:因为MySQL数据最终是保存在数据页中的,物理日志记录的就是数据页的变更。

bin log

  • 概念:
    用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中;
    是MySQL的逻辑日志,并且由Server层进行记录,使用任何存储引擎的MySQL数据库都会记录bin log日志。
    通过追加的方式进行写入的,可以通过max_binlog_size参数设置每个binlog文件的大小,当文件大小达到给定值之后,会生成新的文件来保存日志。

  • 应用场景:
    主从复制:在Master端开启binlog,然后将binlog发送到各个Slave端,Slave端重放binlog从而达到主从数据一致。
    数据恢复:通过使用mysqlbinlog工具来恢复数据。

  • 刷盘时机(将记录刷到磁盘中)
    InnoDB存储引擎而言,只有在事务提交时才会记录biglog,此时记录还在内存中,什么时候刷到磁盘中呢?
    MySQL通过sync_binlog参数来控制刷盘时机,取值范围是0-N;
    sync_binlog = 1 最安全,MySQL5.7.7之后版本的默认值;设置大一点的值可以提升数据库性能。

具体值说明
0不去强制要求,由系统自行判断何时写入磁盘
1每次commit的时候都要将binlog写入磁盘
commit表示的是把事务所做的修改保存到数据库
N每N个事务,才会将binlog写入磁盘
  • 日志的格式
格式说明
STATMENT
statment
基于SQL语句的复制(statement-based replication, SBR),每一条修改数据的SQL语句都会记录到binlog中
优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,从而提高了性能
缺点:在某些情况下会导致主从数据不一致,比如执行sysdate()、sleep()等
ROW
row
基于行的复制(row-based replication,RBR),不记录每条SQL语句的上下文信息,仅需记录哪条数据被修改了
优点:不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题;
缺点:会产生大量的日志,尤其是alter table的时候会让日志暴涨。
MIXED
mixed
基于STATMENT和ROW两种模式的混合复制(mixed-based replication,MBR),一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog

redo log

  • 概念:
    包括两部分:一个是内存中的日志缓存(redo log buffer),另一个是磁盘上的日志文件(redo log file)。
    MySQL每执行一条DML语句,先将记录写入redo log buffer,后续某个时间点再一次性将多个操作记录写到redo log file。
    这种先写日志,再写磁盘的技术就是MySQL里经常说到的WAL(Write-Ahead Logging)技术。
    redo log = 记录事务对数据页做了哪些修改。

在计算机操作系统中,用户空间(user space)下的缓冲区数据一般情况下是无法直接写入磁盘的,中间必须经过操作系统内核空间(kernel space)缓冲区(OS Buffer)。因此,redo log buffer写入redo log file实际上是先写入OS Buffer,然后再通过系统调用fsync()将其刷到redo log file中。
在这里插入图片描述

  • 存在原因:
    事务的四大特性里面有一个是持久性,具体来说就是只要事务提交成功,那么对数据库做的修改就被永久保存下来,不可能因为任何原因再回到原来的状态。
    MySQL保证持久性,通过记录事务对数据页做了哪些修改;
    这样可以有效缓解:每次事务提交的时候,将该事务涉及修改的数据页全部刷新到磁盘中所带来的问题。
    比如InnoDB是以页为单位进行磁盘交互的,而一个事务很可能只修改一个数据页里面的几个字节,这个时候将完整的数据页刷到磁盘的话,太浪费资源了;一个事务可能涉及修改多个数据页,并且这些数据页在物理上并不连续,使用随机IO写入性能太差;

  • redo log buffer写入redo log file的时机,通过innodb_flush_log_at_trx_commit参数配置。

参数值含义
0 延时事务提交时不会将redo log buffer中日志写入到os buffer,而是每秒写入os buffer并调用fsync()写入到redo log file中。也就是说设置为0时是(大约)每秒刷新写入到磁盘中的,当系统崩溃,会丢失1秒钟的数据。
1(实时写,实时刷)事务每次提交都会将redo log buffer中的日志写入os buffer并调用fsync()刷到redo log file中。这种方式即使系统崩溃也不会丢失任何数据,但是因为每次提交都写入磁盘,IO的性能较差。
2(实时写,延迟刷)每次提交都仅写入到os buffer,然后是每秒调用fsync()将os buffer中的日志写入到redo log file。

在这里插入图片描述
undo log

  • 概念:
    数据库事务四大特性中有一个是原子性,具体来说就是原子性是指对数据库的一系列操作,要么全部成功,要么全部失败,不可能出现部分成功的情况。
    原子性底层是通过undo log实现的;主要记录了数据的逻辑变化,有效防止发生错误时,就能回滚到事务之前的数据状态。
    比如:一条insert语句,对应一条delete的undo log;一条update更新语句,对应一条相反的update的undo log。

MySQL与SQL有什么区别?

区别SQLMySQL
概念结构化查询语言,用于在数据库上执行各种操作关系数据库管理系统,使用SQL执行所有数据库操作
作用用于访问、更新和操作数据库中的数据,用户学习该语言然后编写查询软件,为用户提供一个界面,只需单击一些按钮即可操作
更新命令总是相同的定期更新
是否支持连接不提供连接提供名为“MySQL工作台”的集成工具来设计和开发数据库

数据库 基本操作 及原理

查看、创建、修改、删除数据库。

对水平切分和垂直切分的理解?

  • 数据库拆分原则:
    通过某种特定的条件,按照某个维度,将同一个数据库中的数据分散存放到多个数据库(主机),以达到分散单库(主机)负载的效果;
  • 拆分模式:
    垂直(纵向)拆分、水平拆分。

垂直拆分:专库专用

介绍说明
概念按照业务将表分类,分布到不同的数据库上
可解决问题降低单节点数据库的负载
不能解决问题缩表,即每个数据库里面的数据量是没有发生变化的
优点拆分后业务清晰,拆分规则明确
系统之间整合或者扩展容易
数据维护简单
缺点部分业务表无法join,只能通过接口方式解决,提高了系统复杂度
受每种业务不同的限制存在单库性能瓶颈,不易数据扩展跟性能提高。
事务处理复杂

水平拆分 :分库分表

  • 概念:
    把同一个表拆到不同的数据库中;
    不是将表做分类,而是按照某个字段的某种规则来分散到多个库中,每个表中包含一部分数据;
    简单理解 = 按照数据行的切分,将某些行又切分到其他的数据库中;
  • 误解:
    水平切分出来的数据表必须保存在不同的MySQL节点上;
    其实水平切分出来的数据表也可以保存在一个MySQL节点上;
  • 为什么说水平切分不一定需要多个MySQL节点呢?
    MySQL自带一种数据分区的技术,可以把一张表的数据,按照特殊规则,切分存储在不同的目录下。
    若给Linux主机挂载了多块硬盘,可以利用MySQL分区技术,把一张表的数据切分存储在多个硬盘上。
    这样就由原来一块硬盘有限的IO能力,升级成了多个磁盘增强型的IO。

谈谈你对数据库读写分离的理解?

概念
对数据库的读写操作分散到不同的数据库节点上。其中主要是写数据在主服务器上,读数据在从服务器上。
主从服务器之间的关系是:一对一 或者 一对多。

出现原因
单台服务器无法满足快速发展的业务要求,出现了服务器集群。
单台服务器,为了优化查询,会对服务器加索引,但是会影响写入,因为写入会更新索引。
加入主从服务器之后,对从服务器(读操作)加索引,对主服务器(写操作)减少索引以提高写的效率。

好处
1.主从服务器负责各自的读和写,极大程度缓解了锁的争用;
2.从服务器可以使用MylSAM,提升查询性能以及节约系统开销;
3.增加冗余,提高可用性。

会产生主从同步延迟问题

  • 产生:
    向主库写完数据后,主库同步数据到从库是需要时间的,这个时间差会导致主从库数据之间的不一致性。
  • 解决:
    二次读取:读从库没有读到,再去读主库;
    写之后紧接着的读操作让他去读主库;
    关键业务读写都由主库实现,非关键业务由从库读写分离;

分配机制

  • 概念:
    主要怎么制定写操作去主库,读操作去从库。
  • 方式:
    代码封装——抽出一个中间层,来实现读写分离和数据库连接;
    数据库中间件——一个独立的系统,专门来实现读写分离和数据库连接管理,业务服务器和数据库中间件之间是通过标准的SQL协议交流的,所以在业务服务器看来数据库中间件其实就是个数据库。

为什么要分库分表?

  • 概述:
    分库:从单个数据库拆分成多个数据库的过程,将数据散落在多个数据库中。
    分表:从单张表拆分成多张表的过程,将数据散落在多张表内。

  • 原因:
    提升性能、增加可用性;
    一台服务器的资源(CPU、磁盘、io、内存等)是有限的,最终会导致数据库所能承载的数据量、数据处理能力出现瓶颈。

分库分表有哪些问题?

  • 事务问题:
    分库分表后,就成了分布式事务。
    如果依赖数据库本身的分布式事务管理功能去执行事务,将付出高昂的性能代价;
    如果由应用程序去协助控制,形成程序逻辑上的事务,又会造成编程方面的负担。

  • 跨库跨表的JOIN问题:
    在执行了分库分表之后,难以避免会将原本逻辑关联性很强的数据划分到不同的表、不同的库上。这时,表的关联操作将受到限制,我们无法JOIN位于不同分库的表,也无法JOIN分表粒度不同的表,结果原本一次查询能够完成的业务,可能需要多次查询才能完成。

  • 额外的数据管理负担和数据运算压力:
    额外的数据管理负担,最为常见的是数据的定位问题和数据的增删改查的重复执行问题,这些都可以通过应用程序来解决,但必然会引起额外的逻辑运算。

MySQL读写分离的实现方案?

四种方式:
基于MySQL proxy代理、
基于MySQL proxy代理
在这里插入图片描述
MySQL的代理常见的是:mysql-proxy、cobar、mycat、moeba、Atlas。
MySQL Proxy是完全透明的,应用则只需要连接到MySQL Proxy的监听端口即可。
这样会产生proxy单点失效的现象,可以通过使用多个proxy机器做冗余,在应用服务器连接池配置中配置到多个proxy的连接参数即可。

常见代理:

代理介绍
mysql-proxy是一个轻量的中间代理,是官方提供的mysql中间件产品可以实现负载平衡,读写分离,failover等,依靠内部一个lua脚本实现读写语句的判断。
项目地址: https://github.com/mysql/mysql-proxy ,该项目已经六七年没有维护了,官方也不建议应用于生产环境。
cobar是阿里提供的一个中间件,已经停止更新。
项目地址:https://github.com/alibaba/cobar
mycat前身就是cobar,活跃度比较高,完全使用java语言开发。
项目地址:https://github.com/MyCATApache/Mycat-Server ,该项目当前已经有8.3k的点赞量。
moeba(变形虫)是阿里工程师陈思儒基于java开发的一款数据库读写分离的项目(读写分离只是它的一个小功能),与MySQL官方的MySQL Proxy相比,作者强调的是moeba配置的方便(基于XML的配置文件,用SQLJEP语法书写规则,比基于lua脚本的MySQL Proxy简单)。
参考连接:https://www.biaodianfu.com/amoeba.html , 下载地址:https://sourceforge.net/projects/amoeba/ 。
Atlas奇虎360的一个开源中间代理,是在mysql官方mysql-proxy 0.8.2的基础上进行了优化,增加一些新的功能特性。
项目地址: https://github.com/Qihoo360/Atlas ,该项目当前已经有4.4k的点赞量。

基于应用内路由的方式
在这里插入图片描述
应用:
基于spring的aop实现:用aop来拦截spring项目的dao层方法,根据方法名称就可以判断要执行的sql类型(即是read还是write类型),进而动态切换主从数据库。

基于msyql-connector-java的jdbc驱动方式
实现原理:
使用mysql驱动Connector/J就可以实现读写分离,即在jdbc的url中配置为如下的形示:
jdbc:mysql:replication://master,slave1,slave2,slave3/test

基于sharding-jdbc的方式
sharding-sphere是强大的读写分离、分表分库中间件,sharding-jdbc是sharding-sphere的核心模块。
sharding-jdbc可以与springboot集成。

主从复制中涉及哪三个线程?

  • 主从复制概念:
    数据库集群,包括主数据库和从数据库。
    用户更新数据只去主数据库更新,查询数据只去从数据库查询。即更新操作仅在主数据库上,之后从数据库一起更新,查询操作仅在从数据库上。
    这样保证了读写分离,不会出现因为在高并发的情况下造成的读写冲突。

  • 涉及三个线程:

线程介绍
Binlog Dump线程
主节点 (master)
负责将主节点上的数据更改写入二进制日志(bin log)
创建的该线程使用show processlist命令在主节点的标准输出上以“Binlog Dump”名字显示
读取主节点上即将被发送到从节点的每一个事件(Event),binlog Dump线程会对该binlog添加一个锁,直到这个事件被读取到甚至发送到从节点上,这个锁才会被释放。
I/O线程
从节点(Slave)
当START SLAVE语句在从节点上发出时,从节点创建一个I/O线程;
用来连接配置好的主节点并请求其发送bin log中的更新记录
I/O线程读取从binlog Dump线程发送过来的更新信息,将其复制到本地文件内(Relay log) 。
SQL线程
从节点(Slave)
从节点创建一个Slave SQL线程去读取由Slave I/O创建的relay log中的内容,将读取到的事件在从节点上进行重现。
  • 主从复制工作原理:
    master服务器将数据的改变记录二进制bin log日志,当master上的数据发生改变时,则将其改变写入二进制日志中;
    slave服务器会在一定时间间隔内对master二进制日志进行探测,判断其是否发生改变,如果发生改变,则开始一个I/O线程请求master二进制事件;
    主库会生成一个 log dump 线程,用来给从库 I/O线程传bin log;
    I/O线程去请求主库 的bin log,并将得到的bin log日志写到relay log(中继日志) 文件中;
    SQL 线程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致;

主从同步的延迟原因及解决办法?

延迟的原因:
一个服务器开放N个连接给客户端,这样就会有大并发的更新操作,但是从服务器的里面读取 binlog 的线程仅有一个;
当某个SQL在从服务器上执行的时间稍长(读操作)或者 某个SQL要进行锁表就会导致主服务器的SQL大量积压,未被同步到从服务器里。
这就导致了主从不一致,也就是主从延迟。

解决方法

  • 分析:
    所有的SQL必须都要在从服务器里面执行一遍,但是主服务器如果不断的有更新操作源源不断的写入,那么一旦有延迟产生,延迟加重的可能性就会越来越大。
  • 解决:
    由于主服务器要负责更新操作,它对安全性的要求比从服务器高,需要修改某些设置,比如sync_binlog=1(用于控制刷盘的时机),innodb_flush_log_at_trx_commit = 1(规定按照什么策略把redo log日志从redo log buffer里刷到磁盘文件中)之类的设置;
    而slave则不需要这么高的数据安全,完全可以将sync_binlog设置为0或者关闭binlog、innodb_flushlog。
    innodb_flush_log_at _trx_commit也可以设置为0来提高SQL的执行效率。
    增加从服务器来分散读的压力,从而降低服务器负载。

数据类型

数值类型、字符串类型、转义字符、日期/时间、二进制类型、变量。

char 和 varchar 的区别?

区别charvarchar
长度固定
char(10) 字符串"abc" 存储10个字节,其中7个是空格
可变
varchar(10) 字符串"abc" 只占三个字节
效率较高较低
节省空间比char节省空间
存储类型varchar是oracle开发的数据类型
工业标准可以存储空字符串;oracle还可以存储NULL值

varchar(10) 和 varchar(20) 的区别?

varchar(10)最多放10个字符,因此varchar(10)和varchar(20)存储10个及10个以内的字符所占空间一样;
但后者在排序时会消耗更多内存,因为order by col 采用fixed_length计算col长度。
fixed_length 固定长度;

数据表 基本操作

创建、查看、修改数据表结构。

什么是超键、主键、外键、候选键?

超键
在关系中可以唯一标识元组的属性集;
一个属性、多个属性都可以作为超键;
超键包括候选键和主键;

候选键
是最小超键,即没有冗余元素的超键;
候选键包括主键;

主键
数据库表中对储存数据对象予以 唯一和完整标识的数据列或属性的组合。
一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(NULL)。

外键
在一个表中存在的另一个表的主键称为此表的外键;
外键可以是重复的, 可以是空值。
外键是用来和其他表建立联系的。

关系:
超键 》 候选键 》 主键
在这里插入图片描述

UNION 与 UNION ALL的区别?

区别UNIONUNION ALL
概念把来自多个select语句的结果组合到一个结果集中,会将结果集中重复记录删除MySQL会将所有记录返回(包括重复记录)
排序交换两个select语句的顺序后结果集一样,因为它会自动排序交换两个select语句的顺序后结果集不一样,它不会对结果自动进行排序

UNION排序

  • 自动排序规则
    按照select后面的字段(第一个)进行排序。且是升序。
    当查询的第一个字段不是数字的时候,排序会出问题。UNION 和 UNION All都是一样的。
  • 使用order by排序
    order by 子句必须写在最后一个结果集里,并且其排序规则将改变操作后的排序结果。

集合操作符

操作符说明
Union对两个结果集进行集操作,不包括重复行,同时进行默认规则的排序
Union All对两个结果集进行集操作,包括重复行,不进行排序
Intersect对两个结果集进行集操作,不包括重复行,同时进行默认规则的排序
Minus对两个结果集进行操作,不包括重复行,同时进行默认规则的排序

DROP DELETE TRUNCATE的区别?

drop、delete、truncate都是用来删除数据的,但应用场景不同。

区别dropdeletetruncate
格式drop table tablenamedelete from table where xxxtruncate table tablename
SQL语句类型DDLDMLDDL
回滚不可回滚可回滚不可回滚
删除内容从数据库中删除表,表结构、数据、索引。权限都删除表结构还在,删除部分或全部数据表结构还在,删除全部数据
删除速度最快速度慢,逐行删除较快

delete
关于是否会释放磁盘空间的问题:
在 InnoDB 中,DELETE其实并不会真的把数据删除,mysql 实际上只是给删除的数据打了个标记为已删除,因此 delete 删除表中的数据时,表文件在磁盘上所占空间不会变小,存储空间不会被释放,只是把删除的数据行设置为不可见;
DELETE执行时,会先将所删除数据缓存到rollback segement中,事务commit之后生效;
删除表的全部数据,对于MyISAM 会立刻释放磁盘空间,InnoDB 不会释放磁盘空间;
where xxx 带条件的删除, 不管是InnoDB还是MyISAM都不会释放磁盘空间;
delete操作以后使用optimize table table_name会立刻释放磁盘空间。不管是InnoDB还是MyISAM 。
delete 操作是一行一行执行删除的,并且同时将该行的的删除操作日志记录在redo和undo表空间中以便进行回滚(rollback)和重做操作,生成的大量日志也会占用磁盘空间。

truncate
执行后,立刻释放磁盘空间 ,不管是 InnoDB和MyISAM。
truncate能够快速清空一个表。并且重置auto_increment的值。
InnoDB的表本身是无法持久保存auto_increment。delete表之后auto_increment仍然保存在内存,但是重启后就丢失了,只能从1开始。

drop
立刻释放磁盘空间 ,不管是 InnoDB 和 MyISAM;
drop 语句将删除表的结构被依赖的约束(constrain)、触发器(trigger)、索引(index); 依赖于该表的存储过程/函数将保留,但是变为 invalid 状态

操作 表中的数据

查询、增加、修改、删除、清空表记录。

查询性能的优化方法?

  • 减少请求的数据量
    只返回必要的列:尽量避免使用select * 语句;
    只返回必要的行:使用limit语句来限制返回的数据;
    缓存重复查询的数据;

  • 减少服务端扫描的行数
    通过索引来覆盖查询;

sql调优

  • 创建索引:
    尽量避免全表扫描,应考虑where 或order by
  • 避免在索引上使用计算
    在where语句中,如果索引列是计算或者函数的一部分,DBMS的优化器将不会使用索引而使用全表查询
  • 使用预编译查询
    程序中通常是根据用户的输入来动态执行SQL,这时要尽量使用参数化SQL,可以避免SQL注入漏洞;
    数据库会对参数化SQL进行预编译,以后再执行直接使用预编译的结果即可。
  • 调整where子句中的连接顺序
    DBMS一般采用自上而下的顺序解析where子句;
  • 尽量将多条sql语句压缩到一句sql中
    每次执行sql的时候要经历如下过程:建立网络连接、进行权限校验、进行SQL语句的查询优化、发送执行结果
    该过程非常耗时。
  • 用where子句替换Having子句
    避免使用having,因为having只会在检索出所有记录之后才对结果集进行过滤,而where是在聚合前;
    如果可以使用where减少记录的数目,就可以减少开销;
  • 使用表的别名
    sql连接多个表,使用表的别名 可以减少解析的时间 并减少不同表的同名列名的语法歧义
  • 用union all 替换union
  • 用varchar/nvarchar 替换char / nchar
    变长字段存储空间小,可以节省存储空间;
    对于查询来说,在一个相对较小的字段内搜索效率高;

视图

创建、查看、修改、删除视图。

索引index

创建索引实例、普通索引、唯一索引、主键索引、组合索引、全文索引。(逻辑角度)

索引的分类?

数据结构角度分类:树索引(B+tree)、hash索引
物理存储角度:聚集索引、非聚集索引
逻辑角度分类:普通索引、唯一索引、主键索引、联合索引、全文索引

谈谈你对索引的理解?

  • 作用:
    索引的出现是为了提高查询效率,相当于数据库的目录;
    是对查询性能优化最有效的有段;

  • 概念:
    在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构;

  • 原理:
    通过不断缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机事件变成顺序的事件;

  • 分类:
    hash类型的索引:查询单条快,范围查询慢;
    b-tree类型的索引:b+树,层数越多,数据量指数级增长;

  • 缺点:
    创建索引和维护索引需要耗费时间;
    对数据增、删、改时,索引也需要动态维护,降低数据的维护速度;
    随着数据量的增大,索引需要占的物理空间也会越大;

  • 不适合建立索引:
    查询中很少被使用的列 或者 重复值较多的列,不宜建立索引;
    一些特殊的数据类型, 不宜建立索引。比如:文本字段(text) 等。

索引建立原则?

经常被查询的字段:where子句中出现的;
在分组的字段:即在group by子句中出现的;
存在依赖关系的子表和父表之间的联合查询,即主键或外键字段;
设置唯一完整性约束字段;

索引的底层使用的是什么数据结构?

索引的数据结构 和 具体存储引擎 的实现有关;
MySQL中使用较多的索引有 Hash索引、B+ 树 索引等;
则对应索引的底层使用的就是 Hash表 、 B + 树;

谈谈你对B+树 的理解?

图示:
在这里插入图片描述

说明根节点分支节点
除根节点、叶子节点
叶子节点
儿子数有M个儿子则有m个元素有M个儿子则有m个元素
存储内容关键字(索引)关键字(索引)关键字、指针、数据
存储所有根节点、分支节点都存在于子节点中,是最大值或最小值
包含所有关键字、指向数据记录的指针
叶子节点本身是根据关键字从小到大顺序链接的

作用:
优势1 = 更加高效的单元素查找。

对哈希索引的理解?

  • 概念:
    哈希索引(hash index)基于哈希表实现,只有精确匹配索引所有列的查询才有效;
    对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码(hash code),哈希码是一个较小的值,并且不同键值的行计算出来的哈希码是不一样的。
    在 MySQL中,只有 Memory 引擎显式支持哈希索引。

  • 优点:
    能以 O(1) 时间进行查找、只支持精确查找

  • 缺点:
    失去了有序性(指的是数据表的顺序)。无法用于排序与分组,无法用于部分查找和范围查找。

  • 案例:
    在这里插入图片描述

  • 限制:
    哈希索引只包含哈希值和行指针,而不存储字段值,所以不能使用索引中的值来直接读取行;
    哈希索引数据(表的行数据)并不是按照索引值顺序存储的;
    哈希索引也不支持部分索引列匹配查找,因为哈希索引始终是使用索引列的全部内容来计算哈希值的。(在数据列(A,B)上建立哈希索引,如果查询只有数据列A,则无法使用该索引。)
    哈希索引只支持等值比较查询,包括=、IN()、<=>(注意<>和<=>是不同的操作)、也不支持任何范围查询;
    访问哈希索引的数据非常快,除非有很多哈希冲突(不同的索引列值却有相同的哈希值)
    如果哈希冲突很多的话,一些索引维护操作的代价也会很高

聚集索引 和 辅助索引

聚集索引 = 主键索引
聚集索引就是按照每张表的主键构造一棵B+树,同时叶子节点中存放的是整张表的记录数据。
聚集索引的叶子节点称为数据页,聚集索引的这个特性决定了索引组织表中的数据也是索引的一部分。

辅助索引 = 二级索引
非主键索引,叶子节点=键值+书签。
Innodb存储引擎的书签就是相应行数据的主键索引值。

对聚簇索引、稀疏索引 的理解?

  • 聚簇索引:
    是对磁盘上实际数据重新组织,按照指定的一个或多个列的值 排序的算法。
    特点是存储数据的顺序和索引顺序一致。
    一般情况下主键会默认创建聚簇索引,且一张表只允许存在一个聚簇索引。

聚簇索引 和 非聚簇索引(稀疏索引)区别:
聚簇索引:即叶子结点中包含所有完整行记录,叶子节点中包含索引及其他所有字段信息,也就是数据节点;InnoDB 存储引擎中以主键索引构建的 B+tree 即为聚簇索引,
非聚簇索引:其他的皆为稀疏索引;叶子节点仍然是索引节点;

  • 稀疏索引:
    二级索引、联合索引、MyISAM存储引擎的索引全是稀疏索引。

对覆盖索引的理解?

  • 概念:
    select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列已被所使用的索引覆盖。
    索引是高效找到行的一个方法,覆盖索引 = 通过检索索引便可读取想要的数据。

  • 优点:
    索引通常远小于数据行的大小,只读取索引能大大减少数据访问量。
    一些存储引擎(例如:MyISAM)在内存中只缓存索引,而数据依赖于操作系统来缓存。因此,只访问索引可以不使用系统调用(通常比较费时)。
    对于 InnoDB 引擎,若辅助索引能够覆盖查询,则无需访问主索引。

对最左前缀原则的理解?

概念:
MySQL使用联合索引时,需要满足最左前缀原则。
该原则以最左边的为起点,任何连接的索引都得匹配上。
当创建(a,b,c)复合索引时,想要索引生效的时候,只能使用a、ab、abc三种组合。
案例:

# 创建的联合索引是 sex age name 使用最左前缀原则。
SELECT * FROM user where age="4"; #未使用索引 第一个是sex
SELECT * FROM user where name="2"; #未使用索引 第一个是sex
SELECT * FROM user where sex="2" and age="3"; #使用索引 使用索引sex age 
SELECT * FROM user where sex="2" and age="3" and name="4"; #使用索引 使用索引 sex age name
SELECT * FROM user where age="3" and name="4";  #未使用索引 第一个得是sex
SELECT * FROM user where sex="2" and name="4";  #使用索引 只是用了sex索引

怎么知道创建的索引有没有被使用到?或者说怎么才能知道这条语句运行很慢的原因

MySQL提供了explain命令来查看语句的执行计划,
MySQL在执行某个语句之前,会将该语句过一遍查询优化器,之后会拿到对语句的分析,也就是执行计划,其中包含了许多信息。

可以通过其中和索引有关的信息来分析是否命中了索引,例如possilbe_key,key,key_len等字段,分别说明了此语句可能会使用的索引,实际使用的索引以及使用的索引长度。

什么情况下索引会失效?即查询不走索引?

查询不走索引的情况:

  • where子句使用or连接条件,且两字段有一个没有索引,会使引擎放弃索引
  • 对于多列索引,不使用第一部分,则不会使用索引
    使用联合查询,注意最左侧原则,联合索引(a,b,c),where子句只有用到a才会用到联合索引,用到b、c引擎会放弃索引
  • where子句使用like模糊查询,以%开头,会使引擎放弃索引
  • 列类型是字符串,条件中要将数据使用引号引起来,否则不使用索引
  • mysql评估使用全表扫描比使用索引快,则不使用索引
  • where子句中对null值判断会导致引擎放弃索引
  • where子句中使用!=,<>这样的符号,会使引擎放弃索引
  • where使用between,只能是连续的数值(0,1)
  • where中避免使用in,两种情况:in(1)走索引、in(1,2)不走索引
  • where子句中等号 左侧使用表达式操作 或 函数操作,会使引擎放弃索引(索引参与表达式计算、索引参与函数运算)
  • 正则表达式不走索引

事务

描述下事务的特性(ACID)?

原子性(Atomicity)

  • 概念:
    是指事务的所有操作要么全部提交成功,要么全部失败回滚。
  • 实现:
    可以用 undo log 回滚日志来保证,回滚日志会记录当前事务的反向操作;
    当事务执行过程中出现异常时,就会触发回滚,执行 undo log 日志的回滚操作,将数据恢复到事务开始执行前的状态。

一致性(Consistency)

  • 概念:
    指数据库在事务执行前后都应当保持一致性的状态,只有满足一致性,事务的结果才是正确的。
  • 实现:
    原子性和隔离性保证了数据库的一致性。

隔离性(lsolation)

  • 概念:
    并发执行的各个事务之间的操作不能互相干涉。
  • 实现:
    如果没有了隔离性,就可能会造成脏读、不可重复读和幻读的问题。所以事务与事务之间需要存在一定的隔离性,可以通过各种锁来实现。
    其次,事务有四个隔离级别,分别是:读未提交、读提交(Oracle 默认)、可重复读(MySQL 默认)和串行化。

持久性(durability)

  • 概念:
    指当一个事务被提交之后,它对数据库的修改应当是永久的,就算数据库异常重启,只要事务提交了,数据到最后都应当被持久化到磁盘中。
  • 实现:
    由 redo log (重做日志)以及 WAL(Write-Ahead Logging:先写日志再写磁盘) 技术来实现的。
    当有一个更新数据的事务提交之后;InnoDB 存储引擎会先把更新的操作写到 redo log 日志里,并同时将数据更新到内存中(这里就是更新完成了),之后就是等待 InnoDB 将数据持久化到磁盘了。而如果在这等待的过程中,数据库发生异常重启了,也就是数据还没有被持久化到磁盘, 那这个时候就可以根据 redo log 将数据重新恢复到内存中,直到被持久化到磁盘中。

谈谈你对事务隔离级别的理解?

事务的四个隔离级别:
读未提交(READ-UNCOMMITTED)(read-uncommitted)、读已提交(READ-COMMITTED)(read-committed)、可重复读(REPEATABLE-READ)(repeatable-read)、串行化(SERIALIZABLE)(serializable)

读未提交RU
能够读取到其他事务还没有提交的信息。
出现问题:
在这里插入图片描述
读已提交RC
一个事务只能读取其他事务已经提交过的数据,即其他事务执行commit命令后的数据。
解决了脏读问题;
存在问题:幻读 和 不可以重复读
事务B提交查询两次数据,事务A对数据进行修改、增加,就会导致事务B产生不可以重复读、幻读问题。

Oracle数据库 默认事务隔离级别是 读已提交。

可重复读RR
事务不会读到其他事务对已有数据的修改,即使其他事务已经提交。
事务在开始前读到的数据是什么,在事务提交前的任何时刻,读到的数据都是一样的。
解决了不可重复读问题;
存在问题:幻读。

MySQL默认的事务隔离级别是:可重复读。

串行化
要求事务按照序列化执行,事务一个接一个执行,不能并发执行,相当于单线程。
解决了:幻读。
缺点:执行效果较差。

区别

区别读未提交读已提交可重复读串行化
脏读×××
不可重复读××
幻读×

什么叫脏读、不可重复读和幻读?

脏读
出现在隔离级别 = 读未提交;
事务A修改数据,但是由于某些原因,未提交而是发生了rollback;事务B读取了事务A修改后的值;那么该值就是脏数据。

不可以重复读
出现在隔离级别 = 读未提交、读已提交;
事务B前后两次读取数据,两次读取之间事务A对数据进行修改,导致事务B读取的数据内容不一样。
重点在于数据修改;

幻读
出现在隔离级别 = 读未提交、读已提交、可重复读;
同一个事务内多次查询返回的结果集不一样。
事务A第一次查询结果n条,第二次查询结果n+1条。
重点在于数据的删除和增加。

MySQL默认的隔离级别是什么,为什么选择这个?

可重复读。
原因:
mysql的主从复制是基于binlog复制的。
mysql5.0之前的版本,binlog支持statement记录修改SQL语句这种格式。该格式在读已提交隔离级别下主从复制有bug。
当master执行的是先删除后插入,binlog记录的顺序为先插入后删除。()salve同步的binlog就和主机master不一样,就会产生主从不一致问题。

解决方案:
隔离界别设为可重复读,并加入间隙锁。事务1执行delete,间隙锁锁住间隙;事务2插入语句就会阻塞;
将binlog格式改为row;基于行的复制;自然不会出现sql执行顺序不一致的问题;

互联网项目为什么使用读已提交的隔离级别?

不选择读未提交:
一个事务读到另一个事务未提交读数据,从逻辑上都说不过去。
不选择串行化:
每个次读操作都会加锁,快照读失效,一般是使用mysql自带分布式事务功能时才使用该隔离级别。
不选可重复读RR:
在RR隔离级别下,存在间隙锁,导致出现死锁的几率比RC大的多;
在RR隔离级别下,条件列未命中索引会锁表;而在RC隔离级别下,只锁行;
在RC隔离级别下,引入半一致性读(semi-consistent)特性增加了update操作的性能;
半一致性读,一个update语句,如果读到一行已经加锁的记录,此时InnoDB返回记录最近提交的版本,由MySQL上层判断此版本是否满足update的where条件。若满足(需要更新),则MySQL会重新发起一次读操作,此时会读取行的最新版本(并加锁)。

有哪些事务状态?

状态名说明
活动状态事务对应的数据库操作正在执行
局部提交状态事务的最后一个语句执行之后,但是还未写到磁盘中
失败状态当事务处于活动或部分提交,出错无法继续执行,或人为停止当前事务提交
中止状态回滚后的状态
提交状态部分提交状态的事务将修改的数据写到磁盘之后。

中止 和 提交的 才是事务最终的状态。

MySQL的行锁和表锁?

锁是协调多个进程或线程并发访问某一资源的一种机制。
MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。
InnoDB存储引擎支持行锁和表锁,MEMORY和MyISAM等存储引擎只支持表锁。

按照数据操作的粒度分:表锁 和 行锁

区别表锁行锁
操作操作时,会锁定整个表操作时,会锁定当前操作的表的某些行
开销开销小,加锁快开销大,加锁慢
死锁不会出现死锁会出现死锁
锁冲突锁定力度大,发生锁冲突概率高锁定粒度小,发生锁冲突的概率低
并发度最低较高

什么是死锁?如何解决死锁?

死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象。
常见的解决死锁的方法

  • 多表处理,约定访问表的顺序
    如果不同程序并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会;
  • 一次锁定所需所有资源
    在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
  • 提升锁定颗粒度,使用表级锁
    对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率。

什么是乐观锁和悲观锁?如何实现?

悲观锁Pessimistic Lock

  • 概念:
    就是很悲观,每次去拿数据的时候都认为别人会修改。
    每次拿数据都要上锁。
    悲观锁中的共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。
  • 实现:
    由于MySQL默认使用autocommit模式(执行一个更新操作,立即将结果提交),需要关闭自动提交属性;
    加锁sql语句:select num from t_goods where id = 2 for update
    事务A加锁,事务B执行会出现lock wait timeout exceeded;try restarting transaction ,表示该语句已经被锁住了。

乐观锁(Optimistic Lock)

  • 概念:
    就是很乐观,每次去拿数据的时候都认为别人不会修改。
    所以不会上锁,但是如果想要更新数据,则会在更新前检查在读取至更新这段时间别人有没有修改过这个数据。
    如果修改过,则重新读取,再次尝试更新,循环上述步骤直到更新成功。
  • 实现:
    使用数据版本(version)记录机制 或 CAS机制。
    version版本号:即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。
    当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据。
    具体案例:
    表属性是id、value、version;version表示记录被更新的次数 查询记录包括version字段的值versionValue
    每次更新表的字段,为了防止冲突 需要对version字段的值进行修改
    update tast set value = newValue,version = versionValue + 1 where version = versionValue;
    假设节点A和B都要更新task表中的value,且几乎同时读取version = 2,上述语句保证只有一个节点更新value值。
    一个节点更新,另一个就不能更新了。因为where version = 2 这个条件不满足了,更新之后version = 3;

CAS机制:
包括三个变量,内存地址V,旧的预期值A,要修改的新值B。
如果变量的预期值A与内存地址V的实际值相同,则才会将内存地址V的内容修改为新值B。

你对MVCC的了解?

Multi Version Concurrency Control(多版本并发控制)。
概念
多版本并发控制(MVCC)是一种用来解决读-写冲突的无锁并发控制,即 为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照。

作用
在原始的数据库当中,只有读读可以并发, 读写、写读、写写都需要阻塞;在引入多版本并发控制以后,就只有写写是阻塞了。这就在很大的程度上提高了数据库的并发性能。
同时可以解决脏读、幻读、不可重复读等事务隔离问题,但不能解决更新丢失问题。

数据库并发场景

场景介绍
读-读不存在任何问题,也不需要并发控制
读-写有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读;
写-读有线程安全问题,可能会存在更新丢失问题。

当前读和快照读
像select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁)这些操作都是一种当前读,当前读就是指的是事务读取的是当前最新的数据,并且会进行加锁操作,不允许其他并发事务修改当前的记录。

不加锁的select 都是快照读,前提是隔离级别不是串行级别,否则快照读就会退化称为当前读。而MVCC就是基于快照都实现的。

实现原理
主要依赖于3个隐式字段、undo日志、ReadView实现。
隐式字段
数据库中的一条数据记录,除了定义的字段之外,还有三个字段;

字段说明
DB_TRX_ID保存的是最近修改(插入)的事务ID
DB_ROLL_PTR回滚指针,指向这条记录的上一个版本地址
DB_ROW_ID隐式自增ID,当数据表中没有主键,innodb会使用字段产生一个聚簇索引

undo日志
当事务对数据库进行修改时,InnoDB会生成对应的undo log;如果事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子。

ReadView
readview 即读视图,就是在事务在进行快照读的时候生成一个列表,用来记录当前数据库中活跃的事务ID(未提交),这个id是自增的,即事务开启越晚的id就越大。
作用:通过这个列表来判断记录的某个版本是否对当前事务可见。
举例:当前列表里的事务id为[80,100]
当前查询的数据的事务id为50,比列表中事务id的最小值80还小,说明id50已经被提交了,那么当前查询的事务来说是可见的;当前查询的数据的事务id为90,显然在列表中,说明事务还没有提交,对于当前查询的事务来说是不可见的,需要通过回滚指针找到上一个版本的数据比较;当前查询的数据的事务id110,比事务列表的最大值100都大,说明这个版本是在ReadView生成之后才发生的,所以不能被访问。

ReadView是在开启事务后执行select语句时生成的,如果只开启了事务,并没有执行select语句,那么ReadView并没有生成
在RR和RC隔离级别下生成ReadView的方式也不是一致的。在RR隔离级别下,开启事务后,当执行select语句时,会生成ReadView,并且在这个事务中此后的select语句就不再生成ReadView了,使用的都是相同的一个ReadView。
而在RC隔离级别下,开启事务后每执行一次select就会生成一个ReadView。这也就是RR级别下可以防止可重复读的原因了。
在这里插入图片描述

存储索引

MyISAM、InnoDB、Memory。

为什么InnorDB存储索引采用B+树 而不是 B 树?

  • B+树空间利用率更高,可减少I/O次数。
    索引本身也很大,不可能全部存储在内存中,因此索引往往以文件的形式存储的磁盘上。
    索引查找过程中就要产生磁盘I/O消耗。
    B+树的内部节点只是作为索引使用,而不像B树那样每个节点都需要存储硬盘指针。
    B+树中每个非叶节点没有指向某个关键字具体信息的指针,所以每一个节点可以存放更多的关键字数量,即一次性读入内存所需要查找的关键字也就越多,减少了I/O操作。
  • 增删文件(节点)时,效率更高
    B+树的叶子节点包含所有关键字,并以有序的链表结构存储,这样可很好提高增删效率,基于范围查询更好。
  • B+树的查询效率更加稳定
    B+树的每次查询过程中,都需要遍历从根节点到叶子节点的某条路径。所有关键字的查询路径长度相同,导致每一次查询的效率相当。

InnoDB 和 MyISAM的比较?

区别InnoDBMyISAM
事务支持不支持
支持行级锁支持表锁
全文索引不支持支持
外键不支持支持
count()不支持直接存储总行数,需要按行扫描支持直接存储总行数
适用范围小型应用、效率较高
表保存成文件形式,跨平台更方便
管理非事务表,提供高速存储和检索以及全文搜索能力,如果在应用中执行大量select操作可选择
用于事务处理,具有ACID事务支持等特性,如果在应用中执行大量insert和update操作,可选择。

InnoDB存储引擎的锁的类型有哪些?

锁的类型有:表锁、行锁。
InnoDB存储引擎在执行更新操作(UPDATE、DELETE、INSERT等),会自动给涉及的表或行加写锁。
InnoDB存储引擎对于普通SELECT语句,不会加任何锁。
如果读的数据正在执行UPDATE或DELETE操作,这时读操作不会等待写锁的释放,而是直接读取该数据的快照,具体读取那份快照数据,和系统的隔离级别有关。

对于select语句,提供显式加锁指令:

读锁:select * fromwhere..... lock in share mode;
写锁:select * fromwhere ... for update;

约束constrain

主键约束、外键约束、唯一约束、检查约束、非空约束、默认值约束。

触发器(trigger)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值