之前的写的太碎了,把之前的四篇博客合在一起,去除代码及冗杂。

一、数据库

Database:用于存储和管理数据的仓库。
使用MySQL客户端—Navicat for MySQL----使用介绍

1、概述:

特点:

1、可以持久化地存储数据,本身是一个文件系统。
2、可以方便地存储和管理数据。
3、使用统一的SQL来操作数据库。


data/mysql文件夹下 :文件夹对应数据库, .frm文件都是一些表
安装目录下,my.ini 是配置文件。

2、SQL:

1、什么是SQL?

 结构化查询语言(Structured Query Language)是定义了操作所有关系型数据库的规则。---对接各种关系数据库(MySQL、Oracle等)每一种数据库操作的方式存在不一样的地方---“方言”。

2、SQL通用语法

 1、SQL语句可以单行或多行书写,以分号结尾。2、可使用空格和缩进来增强语句的可读性。3、MySQL数据库的SQL语句不区分大小写,但是关键字建议使用大写。4、三种注释:1、-- + 空格    + 注释内容2、# + 注释内容3、/*  */   中间放多行注释

3、SQL分类

 1、DDL--Data Definition Language 数据定义语言: 操作数据库、表2、DML--Manipulation 操作语言: 增删改 表中的数据3、DQL--Query 查询语言: 查询表中的数据4、DCL--Control 控制语言: 授权操作

1、DDL:操作数据库、表

 1、操作数据库:CRUD1、Create: 创建* 创建数据库:create database 数据库名称;* 创建数据库,判断不存在,再创建: create database if not exists 数据库名称;* 创建数据库,并指定字符集: create database 数据库名称 character set 字符集名;* 练习: 创建db4数据库,判断是否存在,并制定字符集为gbk* create database if not exists db4 character set gbk;2、Retrieve : 查询* 查询所有数据库的名称:------show databases;* 查询某个数据库的字符集:查询某个数据库的创建语句:----show create database 数据库名称;3、Update : 修改* 修改数据库的字符集:alter database 数据库名称 character set 字符集名称;4、Delete : 删除*删除数据库: drop database 数据库名称;* 判断数据库存在,存在再删除: drop database if exists 数据库名称; 5、使用数据库*查询当前正在使用的数据库名称:  select database();*使用数据库:use 数据库名称;2、操作表1、Create: 创建1、语法:create table 表名(列名1 数据类型1,列名2 数据类型2,....列名n 数据类型n);* 注意:最后一列,不需要加逗号(,)2、数据库类型:1. int:整数类型* age int,2. double:小数类型* score double(5,2)3. date:日期,只包含年月日,yyyy-MM-dd4. datetime:日期,包含年月日时分秒     yyyy-MM-dd HH:mm:ss5. timestamp:时间戳类型  包含年月日时分秒     yyyy-MM-dd HH:mm:ss    * 如果将来不给这个字段赋值,或赋值为null,则默认使用当前的系统时间,来自动赋值6. varchar:字符串* name varchar(20):姓名最大20个字符* zhangsan 8个字符  张三 2个字符3、   创建表create table student(id int,name varchar(32),age int ,score double(4,1),birthday date,insert_time timestamp);4、 复制表: create table 表名 like 被复制的表名;      2、Retrieve : 查询*查询某个数据库中所有的表名称: show tables;*查询表结构:desc 表名称;*查询某个表的创建语句: show create table 表名称;3、Update : 修改1. 修改表名:alter table 表名 rename to 新的表名;2. 修改表的字符集:alter table 表名 character set 字符集名称;3. 添加一列:alter table 表名 add 列名 数据类型;4. 修改列名称 类型alter table 表名 change 列名 新列别 新数据类型;alter table 表名 modify 列名 新数据类型;5. 删除列alter table 表名 drop 列名;4、Delete : 删除* drop table 表名;* drop table  if exists 表名 ;

2、DML : 增删改表中的数据

1、添加数据语法:insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);注意:1. 列名和值要一一对应。2. 如果表名后,不定义列名,则默认给所有列添加值insert into 表名 values(值1,值2,...值n);3. 除了数字类型,其他类型需要使用引号(单双都可以)引起来    2、删除数据语法:delete from 表名称 [where 条件] ;注意:1、如果不加条件,则会删除表中所有记录。2、如果要删除所有记录:1、delete from 表名称; -------不推荐使用,有多少条记录就会执行多少次删除操作,效率低。2、TRUNCATE TABLE 表名称;-----推荐使用,效率更高,先删除表然后再创建一张一样的表。-----drop+create
3、修改数据语法:  update 表名 set 列名1 = 值1, 列名2 = 值2,... [where 条件];-----UPDATE stud SET age = 234, score = 100 WHERE id = 3;注意: 如果不添加任何where条件,则会将表中所有记录全部修改。

3、DQL:查询表中的记录

select * from 表名称;**1、语法:**select字段列表from表名列表where条件列表group by分组字段having分组之后的条件order by排序limit分页限定**2、基础查询**1. 多个多个字段的查询select 字段名1,字段名2... from 表名;* 注意:* 如果查询所有字段,则可以使用*来替代字段列表。2. 去除重复:* distinct3. 计算列* 一般可以使用四则运算计算一些列的值。(一般只会进行数值型的计算)* ifnull(表达式1,表达式2):null参与的运算,计算结果都为null* 表达式1:哪个字段需要判断是否为null* 如果该字段为null后的替换值。4. 起别名:* as:as也可以省略**3、条件查询**1. 条件查询语句---在where子句后跟条件2. 运算符* > 、< 、<= 、>= 、= 、<>* BETWEEN...AND  * IN( 集合) * LIKE:模糊查询* 占位符:* _:单个任意字符* %:多个任意字符* IS NULL  * and  或 &&* or  或 || * not  或 !**4、排序查询*** 语法:order by 子句* order by 排序字段1 排序方式1 ,  排序字段2 排序方式2...* 排序方式:* ASC:升序,默认的。* DESC:降序。* 注意:* 如果有多个排序条件,则当前边的条件值一样时,才会判断第二条件。**5、聚合函数:**将一列数据作为一个整体,进行纵向的计算。----比如计算数学成绩平均分这些。1. count:计算个数1. 一般选择非空的列:主键2. count(*)2. max:计算最大值3. min:计算最小值4. sum:计算和5. avg:计算平均值* 注意:聚合函数的计算,排除null值。解决方案:1. 选择不包含非空的列进行计算       2. IFNULL函数**6、分组查询:**1. 语法:group by 分组字段;2. 注意:1. 分组之后查询的字段:分组字段、聚合函数 ----sex,avg(),count 别的像name这些没有意义2. where 和 having 的区别?1. where 在分组之前进行限定,如果不满足条件,则不参与分组。having在分组之后进行限定,如果不满足结果,则不会被查询出来2. where 后不可以跟聚合函数,having可以进行聚合函数的判断。**7、分页查询**  ---limit子句1. 语法:limit  开始的索引, 每页查询的条数;2. 公式:开始的索引 = (当前的页码 - 1) * 每页显示的条数3. 分页操作 limit 是一个MySQL"方言"

4、DCL:管理用户,授权

SQL分类:1、DDL:操作数据库和表    Definition2、DML:增删改表中数据   Manipulation3、DQL:查询表中数据       Query4、DCL:管理用户,授权    Control
DBA:数据库管理员DCL:管理用户,授权    Control1、管理用户1、添加用户:语法:CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';CREATE USER 'wang'@'localhost' IDENTIFIED By '123';CREATE USER 'chen'@'%' IDENTIFIED By '123';2、删除用户:语法:DROP USER '用户名'@'主机名';DROP USER 'wang'@'localhost';DROP USER 'chen'@'%';3、修改用户密码: -- MySQL数据库中password函数加密函数UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名';UPDATE USER SET PASSWORD = PASSWORD('abc') WHERE USER = 'lisi';another方法:DCL特有的方式。SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123');-- 修改当前登录的用户密码mysql中忘记了root用户的密码?1. cmd -- > net stop mysql 停止mysql服务* 需要管理员运行该cmd -- 右键管理员运行cmd,停止MySQL服务2. 使用无验证方式启动mysql服务: mysqld --skip-grant-tables3. 打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登录成功4. use mysql;5. update user set password = password('你的新密码') where user = 'root';6. 关闭两个窗口7. 打开任务管理器,手动结束mysqld.exe 的进程8. 启动mysql服务9. 使用新密码登录。4、查询用户:-- 1. 切换到mysql数据库USE myql;-- 2. 查询user表SELECT * FROM USER;* 通配符: % 表示可以在任意主机使用用户登录数据库2、 权限管理:1.、查询权限:-- 查询权限SHOW GRANTS FOR '用户名'@'主机名';SHOW GRANTS FOR 'lisi'@'%';2.、授予权限:-- 授予权限grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';-- 给张三用户授予所有权限,在任意数据库任意表上GRANT ALL ON *.* TO 'zhangsan'@'localhost';3、 撤销权限:-- 撤销权限:revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';REVOKE UPDATE ON db3.`account` FROM 'lisi'@'%';

3、多表查询

查询语法:select  列名列表 from 表明列表 where ...准备SQL:代码放在代码块。笛卡尔积:有两个集合A,B,取这两个集合的所有组成情况。要完成多表查询,需要消除无用的数据。多表查询的分类:1、内连接查询:--查询 的就是交集部分1、隐式内连接:使用where条件消除无用数据SELECT *FROM emp, dept WHERE emp.dept_id = dept.id;2、显示内连接:语法: select 字段列表 from 表名1 [inner] join 表名2 on 条件-- 显式内连接SELECT *FROM emp INNER JOIN dept ON emp.dept_id = dept.id;SELECT *FROM emp JOIN dept ON emp.dept_id = dept.id;3、内连接查询:1、从哪些表中查询数据2、条件是什么3、查询哪些字段2、外连接查询:-- 左外查询和右外查询相对应1、左外连接:语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;查询的是左表所有数据以及其交集部分* 例子:-- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称SELECT   t1.*,t2.`name` FROM emp t1 LEFT JOIN dept t2 ON t1.`dept_id` = t2.`id`;2、右外连接:语法:select 字段列表 from 表1 right [outer] join 表2 on 条件;查询的是右表所有数据以及其交集部分。* 例子:SELECT   * FROM dept t2 RIGHT JOIN emp t1 ON t1.`dept_id` = t2.`id`;3、子查询:概念:在查询中嵌套查询,称嵌套查询为子查询SELECT *FROM emp WHERE salary = (SELECT MAX(salary) FROM emp);--后面括号里就是子查询子查询不同情况:1、子查询的结果是单行单列的子查询可以作为条件,使用运算符去判断。大于小于等于。运算符: > >= < <= =-- 子查询作为条件-- 查询员工工资小于平均工资的员工信息SELECT *FROM emp WHERE (salary < (SELECT AVG(salary) FROM emp));2、子查询的结果是多行单列的子查询可以作为条件,使用运算符in进行判断-- 查询财务部和市场部所有的员工信息                       SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部';SELECT *FROM emp WHERE dept_id IN (2,3);-- 子查询SELECT *FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部');3、子查询的结果是多行多列的子查询可以作为一张虚拟表来参与查询-- 多行多列的子查询结果,可以做一个虚拟表-- 把这个查询到的表称为虚拟表,和部门信息作关联SELECT *FROM dept t1, (SELECT *FROM emp WHERE join_date > '2011-11-11') t2 WHERE t1.id = t2.dept_id;

4、数据库的备份和还原

1. 命令行:* 语法:* 备份: mysqldump -u用户名 -p密码 数据库名称 > 保存的路径* 备份的是一些数据库的表、数据等* 还原:1. 登录数据库2. 创建数据库3. 使用数据库4. 执行文件。source 文件路径------------把原有的生成的SQL文件source一下
2. 图形化工具:右键就可以进行转储SQL文件也可以直接导入SQL备份文件

二、约束及事务

1、约束

 概念: 对表中的数据进行限定,保证数据的正确性、有效性、完整性。分类:1、主键约束:primary key2、非空约束:not null3、唯一约束:unique4、外键约束:foreign key

1、非空约束: not null 值不能为空

2、 唯一约束:unique,值不能重复
注意:唯一约束可以有null值,但是只能有一条记录为null。

3、主键约束:primary key

注意:1、含义:非空且唯一2、一张表只能有一个字段为主键3、主键就是表中记录的唯一标识

自动增长--------(一般都同主键一起使用):
概念:如果某一列是数值类型的,使用auto_increment可以来完成值的自动增长。

4、外键约束:foreign key,让表与表之间产生关系,从而保证数据的正确性。

1、在创建表时,可以添加外键语法:create table 表名(....外键列constraint 外键名称 foreign key (外键列名称) references 主表名称(主表列名称));
2. 删除外键ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;3. 创建表之后,添加外键ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);4. 级联操作1. 添加级联操作语法:ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称) ON UPDATE CASCADE ON DELETE CASCADE  ;2. 分类:1. 级联更新:ON UPDATE CASCADE 2. 级联删除:ON DELETE CASCADE

2、数据库的设计

1、多表之间的关系

 1、分类:1、一对一的关系:(了解,在工程中用的少)人和身份证的关系:一个人只有一个身份证,一个身份证只能对应一个人2、一对多(多对一):部门和员工的关系:一个部门有多个员工,一个员工只能对应一个部门3、多对多:学生和课程的关系:一个学生可以选择多门课程,一个课程也可以被很多个学生选择2、实现关系:1、一对多(多对一)  :员工和部门:多个员工对一个部门实现方式:在多的一方建立外键,指向一的一方的主键2、多对多:学生和课程:多个学生对多个部门实现方式:需要借助中间表,中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键----联合主键3、一对一关系学生和身份证实现方式:可以在任意一方设置外键指向另一方的主键,注意外键要加上唯一约束----直接合成一张表不香嘛

2、数据库设计的范式

 概念: 设计数据库时,需要遵循的一些规范。范式越高,要求越多,如要遵循后面的范式,必须遵循前面的所有范式要求。设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。* 分类:1. 第一范式(1NF):每一列都是不可分割的原子数据项------所有的列都是单独不可分的--- 如果全是第一范式的表格,存在的问题:1、存在严重的数据冗余问题。姓名、系名、系主任重复过多2、数据添加存在问题,只添加新开设的系和系主任的时候,数据不合法3、数据删除存在问题,如果只有一个学生,学生毕业删除数据时,会将系的数据一起删除------ 第一范式是一张表--学生表      2. 第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于码(在1NF基础上消除非主属性对主码的部分函数依赖)----------第二范式就是消除部分依赖。* 几个概念:1. 函数依赖:A-->B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A例如:学号-->姓名。  (学号,课程名称) --> 分数学号可以唯一确定姓名的值,因此姓名依赖于学号。学号和课程名称可以唯一确定分数,分数依赖于属性组(学号,课程名称)2. 完全函数依赖:A-->B, 如果A是一个属性组,则B属性值得确定需要依赖于A属性组中所有的属性值。例如:(学号,课程名称) --> 分数分数依赖于学号和课程名称两个,即属性组中所有属性值。3. 部分函数依赖:A-->B, 如果A是一个属性组,则B属性值得确定只需要依赖于A属性组中某一些值即可。例如:(学号,课程名称) -- > 姓名属性组中某个属性就可确定该属性,学号就可以确定姓名4. 传递函数依赖:A-->B, B -- >C . 如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性组)的值可以确定唯一C属性的值,则称 C 传递函数依赖于A例如:学号-->系名,系名-->系主任学号唯一确定系名,系名唯一确定系主任,则称传递函数依赖5. 码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码例如:该表中码为:(学号,课程名称)通过学号和课程名称,可以唯一确定其他的所有属性值* 主属性:码属性组中的所有属性   ----   学号、课程名称* 非主属性:除过码属性组的属性   ---    其他的属性---  第二范式分成了学生表和选课表        3. 第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)---- 第三范式分成了学生表、选课表、系表---- 此时存在的问题都被解决。

3、事务

1、事务的基本介绍

事务是逻辑上的一组操作,要么都执行,要么都不执行。

1、概念:指满足ACID特性的一组操作,可以通过Commit提交一个事务,也可以使用Rollback进行回滚。---如果一个包含多个步骤的业务操作,被事务管理,这些操作要么同时成功,要么同时失败。例子:张三给李四转账500元   --- 被事务管理 --- 要开启事务、回滚、提交事务1、查询张三余额是否大于5002、张三账户金额 - 5003、李四账户金额 + 5002、操作:1、开启事务:start transaction2、回滚:rollback3、提交:commit4、MySQL数据库中事务默认自动提交* 事务提交的两种方式:* 自动提交:* mysql就是自动提交的* 一条DML(增删改)语句会自动提交一次事务。* 手动提交:* Oracle 数据库默认是手动提交事务 -- 在Oracle中执行完必须要commit一下* 需要先开启事务,再提交* 修改事务的默认提交方式:* 查看事务的默认提交方式:SELECT @@autocommit; -- 1 代表自动提交  0 代表手动提交* 修改默认提交方式: set @@autocommit = 0;

2、事务的四大特征ACID

1、原子性(Atomicity):是不可分割的最小操作单位,事务的所有操作要么同时提交成功,要么同时失败回滚。
2、一致性(Consistency):数据库在事务执行前后都保持一致性状态,数据总量不变。---一致性状态下,所有事务对同一个数据的读取结果是相同的。
3、隔离性(Isolation):多个事务之间,相互独立。--一个事务所做的修改在最终提交之前,对其它事务不可见。
4、持久性(Durability):当事务提交或回滚之后,数据会持久化地保存数据,保存在硬盘上。

ACID特性不是一种平级关系:

1、只有满足一致性,事务的执行结果才是正确的。
2、在无并发的情况下,事务串行执行,隔离性一定能够满足。此时只要能满足原子性,就一定能满足一致性。
3、在并发的情况下,多个事务并行执行,事务不仅要满足原子性,还需要满足隔离性,才能满足一致性。
4、事务满足持久化是为了能应对系统崩溃的情况。

3、事务的隔离级别

1、概念:
多个事务之间具有隔离性,是相互独立的。
但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。

2、并发存在的问题:
1、脏读:一个事务,读取到另一个事务中没有提交的数据。----别的事务撤销了这次修改。
2、不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。----可能别的事务作了修改
3、幻读:一个事务操作(DML)数据表中所有的记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。 — 在MySQL数据库中见不到
4、丢失修改:一个事务的更新操作被另外一个事务的更新操作替换。

产生并发不一致性问题的主要原因是破坏了事务的隔离性,解决方法是通过并发控制保证隔离性。
数据库管理系统提供了事务的隔离级别,用户可以更轻松地处理并发一致性问题。

3、隔离级别:
1、read uncommitted:读未提交
—事务中的修改,即使没有提交,对其它事务也是可见的。
产生的问题:脏读、不可重复读、幻读
2、read committed : 读已提交(Oracle数据库默认级别)
—一个事务只能读取已经提交的事务所做的修改。==一个事务所做的修改在提交之前对其它事务不可见。
产生的问题:不可重复读、幻读
3、repeatable read:可重复读 (MySQL数据库默认级别)
—保证在同一个事务中多次读取同一数据的结果是一样的。
产生的问题: 幻读
4、serializable:串行化
—强制事务串行执行,使多个事务互不干扰,不会出现并发一致性问题。
—需要加锁实现,使用加锁机制保证同一时间只有一个事务执行,保证事务串行执行。
可以解决所有问题

 注意: 隔离级别从小到大,从1到4,安全性越来越高,但是效率越来越低。数据库查询隔离级别:* select @@tx_isolation;数据库设置隔离级别:* set global transaction isolation level  级别字符串;

4、封锁

并发控制还可以通过封锁实现,封锁操作需要用户自己控制。

1、封锁粒度
MySQL中提供了两种封锁粒度:行级锁、表级锁
应该尽量只锁定需要修改的那部分数据。锁定的数据量越少,发生锁争用的可能就越小,系统的并发程度就越高。
加锁需要消耗资源,锁的各种操作都会增加系统开销。因此封锁粒度越小,系统开销就越大。

2、封锁类型
1、读写锁
1、互斥锁(Exclusive),简写为 X 锁,又称写锁。
2、共享锁(Shared),简写为 S 锁,又称读锁。
规定:-----写锁和读锁阻塞(读写互斥),读与读共享,写和写阻塞(写写互斥)
1、一个事务对数据对象A加了写锁,该事务可以对A进行读取和写入。加锁期间其它事务不能对A加任何锁。
2、一个事务对数据对象A加了读锁,可以对A进行读取操作,但是不能更新写入。
加锁期间其它事务能对 A 加读锁,但是不能加 写 锁。
2、意向锁
使用意向锁(Intention Locks)可以更容易地支持多粒度封锁。
在存在行级锁和表级锁的情况下,事务 T 想要对表 A 加 X 锁,就需要先检测是否有其它事务对表 A 或者
表 A 中的任意一行加了锁,那么就需要对表 A 的每一行都检测一次,这是非常耗时的。

     意向锁在原来读写锁之上引入了IX/IS,IX/IS都是表锁,用来表示一个事务想在表中的某数据行上加X锁或S锁。规定:---任意 IS/IX 锁之间都是兼容的--表级的 IX 锁和行级的 X 锁兼容,两个事务可以对两个数据行加 X 锁。1、一个事务在获得某个数据行对象的S锁之前,必须先获得表的IS锁或者更强的锁。2、一个事务在获得某个数据行对象的X锁之前,必须先获得表的IX锁。通过引入意向锁,事务想对表A加X锁,只需要先检测是否有其他事务对表A加了X/IX/S/IS 锁,如果加了就表示有其它事务正在使用这个表或者表中某一行的锁,因此事务 T 加 X 锁失败。

3、封锁协议

 1、三级封锁协议1、一级封锁协议事务T要修改数据A时必须加X写锁,直到事务结束才释放锁。可以解决丢失修改问题。因为不能同时有两个事务对同一个数据进行修改,那么事务的修改就不会被覆盖。2、二级封锁协议在一级的基础上,要求读取数据时必须加S读锁,读取完马上释放锁。可以解决数据脏读问题。因为如果一个事务在对数据 A 进行修改,根据 1 级封锁协议,会加 X 锁,那么就不能再加 S 锁了,也就是不会读入数据。3、三级封锁协议在二级的基础上,要求读取数据 A 时必须加 S 锁,直到事务结束了才能释放 S 锁。可以解决不可重复读的问题,因为读 A 时,其它事务不能对 A 加 X 锁,从而避免了在读的期间数据发生改变。2、两段锁协议--指加锁和解锁分为两个阶段进行。可串行化调度是指,通过并发控制,使得并发执行的事务结果与某个串行执行的事务结果相同。串行执行的事务互不干扰,不会出现并发一致性问题。事务遵循两段锁协议是保证可串行化调度的充分条件,但不是必要条件。满足两段锁协议,它是可串行化调度:lock-x(A)...lock-s(B)...lock-s(C)...unlock(A)...unlock(C)...unlock(B)不满足两段锁协议,但它还是可串行化调度:lock-x(A)...unlock(A)...lock-s(B)...unlock(B)...lock-s(C)...unlock(C)

4、MySQL隐式与显示锁定

 MySQL 的 InnoDB 存储引擎采用两段锁协议,会根据隔离级别在需要的时候自动加锁,并且所有的锁都是在同一时刻被释放,这被称为隐式锁定。InnoDB 也可以使用特定的语句进行显示锁定:

补充:

1、InnoDB存储引擎的锁算法有三种:Record Lock:单个行记录上的锁Gap Lock:间隙锁,锁定一个范围,不包括记录本身Next-key Lock:record + gap锁定一个范围,包含记录本身2、InnoDB对于⾏的查询使⽤next-key lock
3、Next-key Lock为了解决幻读问题
4、当查询的索引含有唯⼀属性时,将next-key lock降级为record key
5、Gap锁设计的⽬的是为了阻⽌多个事务将记录插⼊到同⼀范围内,⽽这会导致幻读问题的产生
6、有两种⽅式显式关闭gap锁:(除了外键约束和唯⼀性检查外,其余情况仅使⽤record lock)A. 将事务隔离级别设置为RC B. 将参数Innodb_locks_unsafe_for_binlog设置为1

三、MySQL

这一部分主要记录一下MySQL的一些本身的知识。

面试题:字符集及校对规则?

字符集指的是一种从二进制编码到某类字符符号的映射。
校对规则是指某种字符集下的排序规则。
MySQL中每一种字符集都会对应一系列的校对规则。

1、B树、B+树、红黑树

1、B Tree

B Tree 指的是 Balance Tree,也就是平衡树。平衡树是一颗查找树,并且所有叶子节点位于同一层。
M=3 的 B树:

B树(B-树)是一种多路搜索树(并不是二叉的):1.定义任意非叶子结点最多只有M个儿子;且M>2;2.根结点的儿子数为[2, M];3.除根结点以外的非叶子结点的儿子数为[M/2, M];4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)5.非叶子结点的关键字个数=指向儿子的指针个数-1;6.非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];7.非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;8.所有叶子结点位于同一层;

2、B+ Tree

B+ Tree 是基于 B Tree 和叶子节点顺序访问指针进行实现,它具有 B Tree 的平衡性,并且通过顺序访问指针来提高区间查询的性能。
M = 3 的B+树:

B+树是B-树的变体,也是一种多路搜索树:1.其定义基本与B-树同,除了:2.非叶子结点的子树指针与关键字个数相同;3.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);5.为所有叶子结点增加一个链指针;6.所有关键字都在叶子结点出现;

操作B+树:

进行查找操作时,首先在根节点进行二分查找,找到一个 key 所在的指针,然后递归地在指针所指向的节点进行查找。
直到查找到叶子节点,然后在叶子节点上进行二分查找,找出 key 所对应的 data。插入删除操作会破坏平衡树的平衡性,因此在进行插入删除操作之后,
需要对树进行分裂、合并、旋转等操作来维护平衡性。

3、红黑树:

红黑树

红黑树是自平衡的二叉查找树,进行插入、删除等可能破坏树的平衡的操作时,需重新自处理达到平衡状态。满足以下性质:

1、每个节点要么黑色,要么红色。
2、根节点是黑色。
3、每个叶子节点是黑色。
4、每个红色节点的两个子节点一定都是黑色。
5、任意一节点到每个叶子节点的路径包含数量相同的黑色节点。
5.1、如果一个节点存在黑色子节点,那么该节点肯定有两个子节点。

自平衡的三种操作:

1、左旋:以某个结点作为支点-旋转节点,其右子节点变为旋转节点的父节点。右子节点的左子节点变为旋转节点的右子节点,左子节点保持不变。
2、右旋:以某个节点作为支点-旋转节点,其左子节点变为旋转节点的父节点。左子节点的右子节点变为旋转节点的左子节点,右子节点保持不变。
3、变色:节点的颜色由红变黑或由黑变好。

B+ 树与红黑树对比:

红黑树等平衡树也可以实现索引,但是文件系统及数据库系统普遍使用B+ 树作为索引结构,因为使用B+树访问磁盘数据性能更高。

1、B+ 树有更低的树高
平衡树的树高 O(h)=O(logdN),其中 d 为每个节点的出度。红黑树的出度为 2,而 B+ Tree 的出度一般都非常大,所以红黑树的树高 h 很明显比 B+ Tree 大非常多。

2、磁盘访问原理
操作系统一般将内存和磁盘分割成固定大小的块,每一块称为一页,内存与磁盘以页为单位交换数据。数据库系统将索引的一个节点的大小设置为页的大小,使得一次 I/O 就能完全载入一个节点。

如果数据不在同一个磁盘块上,那么通常需要移动制动手臂进行寻道,而制动手臂因为其物理结构导致了移动效率低下,从而增加磁盘数据读取时间。B+ 树相对于红黑树有更低的树高,进行寻道的次数与树高成正比,在同一个磁盘块上进行访问只需要很短的磁盘旋转时间,所以 B+ 树更适合磁盘数据的读取。

3、磁盘预读特性
为了减少磁盘 I/O 操作,磁盘往往不是严格按需读取,而是每次都会预读。预读过程中,磁盘进行顺序读取,顺序读取不需要进行磁盘寻道,并且只需要很短的磁盘旋转时间,速度会非常快。并且可以利用预读特性,相邻的节点也能够被预先载入。

2、MyISAM和InnoDB存储引擎

InnoDB

1、是 MySQL 默认的事务型存储引擎,只有在需要它不支持的特性时,才考虑使用其它存储引擎。
2、实现了四个标准的隔离级别,默认级别是可重复读(REPEATABLE READ)。
在可重复读隔离级别下,通过多版本并发控制(MVCC)+ Next-Key Locking 防止幻影读。
3、主索引是聚簇索引,在索引中保存了数据,从而避免直接读取磁盘,因此对查询性能有很大的提升。

4、内部做了很多优化,包括从磁盘读取数据时采用的可预测性读、能够加快读操作并且自动创建的自适应哈希索引、能够加速插入操作的插入缓冲区等。
5、支持真正的在线热备份。其它存储引擎不支持在线热备份,要获取一致性视图需要停止对所有表的写入,而在读写混合场景中,停止写入可能也意味着停止读取。

MyISAM

1、设计简单,数据以紧密格式存储。对于只读数据,或者表比较小、可以容忍修复操作,则依然可以使用它。
2、提供了大量的特性,包括压缩表、空间数据索引等。
3、不支持事务
4、不支持行级锁,只能对整张表加锁读取时会对需要读到的所有表加共享锁,写入时则对表加排它锁。但在表有读取操作的同时,也可以往表中插入新的记录,这被称为并发插入(CONCURRENT INSERT)。
5、可以手工或者自动执行检查和修复操作,但是和事务恢复以及崩溃恢复不同,可能导致一些数据丢失,而且修复操作是非常慢的。
6、如果指定了 DELAY_KEY_WRITE 选项,在每次修改执行完成时,不会立即将修改的索引数据写入磁盘,而是会写到内存中的键缓冲区,只有在清理键缓冲区或者关闭表的时候才会将对应的索引块写入磁盘。这种方式可以极大的提升写入性能,但是在数据库或者主机崩溃时会造成索引损坏,需要执行修复操作。

比较

1、事务:InnoDB 是事务型的,可以使用 Commit 和 Rollback 语句。
2、并发:MyISAM 只支持表级锁,而 InnoDB 还支持行级锁。
3、外键:InnoDB 支持外键。
4、备份:InnoDB 支持在线热备份。
5、崩溃恢复:MyISAM 崩溃后发生损坏的概率比 InnoDB 高很多,而且恢复的速度也更慢。
6、其它特性:MyISAM 支持压缩表和空间数据索引。

3、多版本并发控制

多版本并发控制(Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,用于实现读已提交可重复读两种隔离级别。
读未提交隔离级别总是读取最新的数据行,要求很低,无需使用MVCC。
串行化隔离级别需要对所有读取的行都加锁,单纯使用MVCC无法实现。

1、基本思想:

加锁可以解决多个事务同时执行时出现的并发一致性问题。
但是在实际场景中读操作往往多于写操作,因此可以使用读写锁避免不必要的加锁操作。
读读之间没有互斥关系,读和写操作之间仍然是互斥的。
MVCC利用多版本的思想,写操作更新最新的版本快照读操作则读旧版本快照,没有互斥关系,类似CopyOnWrite。

在MVCC中事务的修改操作(delete、insert、update)会为数据行新增一个版本快照。

脏读和不可重复读最根本的原因是事务读取到其它事务未提交的修改。
在事务进行读取操作时,为了解决脏读和不可重复读问题,MVCC 规定只能读取已经提交的快照
当然一个事务可以读取自身未提交的快照,这不算是脏读。

2、版本号

系统版本号 SYS_ID:是一个递增的数字,每开始一个新的事务,系统版本号就会自动递增。
事务版本号 TRX_ID :事务开始时的系统版本号。

3、Undo 日志

MVCC 的多版本指的是多个版本的快照
快照存储在 Undo 日志中,该日志通过回滚指针 ROLL_PTR 把一个数据行的所有快照连接起来。

例子:
在 MySQL 创建一个表 t,包含主键 id 和一个字段 x。
我们先插入一个数据行,然后对该数据行执行两次更新操作。

INSERT INTO t(id, x) VALUES(1, "a");
UPDATE t SET x="b" WHERE id=1;
UPDATE t SET x="c" WHERE id=1;

没有使用 START TRANSACTION 将上面的操作当成一个事务来执行,根据 MySQL 的 AUTOCOMMIT 机制,每个操作都会被当成一个事务来执行,所以上面的操作总共涉及到三个事务。
快照中除了记录事务版本号 TRX_ID 和操作之外,还记录了一个 bit 的 DEL 字段,用于标记是否被删除。

INSERT、UPDATE、DELETE 操作会创建一个日志,并将事务版本号 TRX_ID 写入。
DELETE 可以看成是一个特殊的 UPDATE,还会额外将 DEL 字段设置为 1。

4、ReadView

MVCC 维护了一个 ReadView 结构,主要包含了当前系统未提交的事务列表 TRX_IDs {TRX_ID_1, TRX_ID_2, …},还有该列表的最小值 TRX_ID_MINTRX_ID_MAX

在进行 SELECT 操作时,根据数据行快照的 TRX_ID 与 未提交事务列表的TRX_ID_MIN 和 TRX_ID_MAX 之间的关系,从而判断数据行快照是否可以使用:

1、TRX_ID < TRX_ID_MIN,表示该数据行快照时在当前所有未提交事务之前进行更改的,因此可以使用。
2、TRX_ID > TRX_ID_MAX,表示该数据行快照是在事务启动之后被更改的,因此不可使用。
3、TRX_ID_MIN <= TRX_ID <= TRX_ID_MAX,需要根据隔离级别再进行判断:提交读:如果 TRX_ID 在 TRX_IDs 列表中,表示该数据行快照对应的事务还未提交,则该快照不可使用。否则表示已经提交,可以使用。可重复读:都不可以使用。因为如果可以使用的话,那么其它事务也可以读到这个数据行快照并进行修改,那么当前事务再去读这个数据行得到的值就会发生改变,也就是出现了不可重复读问题。

在数据行快照不可使用的情况下,需要沿着 Undo Log 的回滚指针 ROLL_PTR 找到下一个快照,再进行上面的判断。

5、快照读与当前读

1、快照读
MVCC 的 SELECT 操作快照中的数据,不需要进行加锁操作。

2、当前读
MVCC 其它会对数据库进行修改的操作(INSERT、UPDATE、DELETE需要进行加锁操作,从而读取最新的数据。可以看到 MVCC 并不是完全不用加锁,而只是避免了 SELECT 的加锁操作

在进行 SELECT 操作时,可以强制指定进行加锁操作。
以下第一个语句需要加 S 锁,第二个需要加 X 锁:

 SELECT * FROM table WHERE ? lock in share mode;SELECT * FROM table WHERE ? for update;

4、Next-Key Locks

Next-Key Locks 是 MySQL 的 InnoDB 存储引擎的一种锁实现。

MVCC 不能解决幻读问题,Next-Key Locks 就是为了解决这个问题而存在的。
在可重复读(REPEATABLE READ)隔离级别下,使用 MVCC + Next-Key Locks 可以解决幻读问题。

1、Record Locks

锁定一个记录上的索引,而不是记录本身。
如果表没有设置索引,InnoDB 会自动在主键上创建隐藏的聚簇索引,因此 Record Locks 依然可以使用。

2、Gap Locks

锁定索引之间的间隙,但是不包含索引本身。
例如当一个事务执行以下语句,其它事务就不能在 t.c 中插入 15。

SELECT c FROM t WHERE c BETWEEN 10 and 20 FOR UPDATE;

3、Next-Key Locks

它是 Record Locks 和 Gap Locks 的结合,不仅锁定一个记录上的索引,也锁定索引之间的间隙。
锁定一个前开后闭区间,例如一个索引包含以下值:10, 11, 13, and 20,那么就需要锁定以下区间:

(-∞, 10]
(10, 11]
(11, 13]
(13, 20]
(20, +∞)

面试题:怎么进行大表优化?

**1、限定数据的范围:**务必禁止不带任何限制数据范围条件的查询语句。
**2、读/写分离:**经典的数据库拆分⽅案,主库负责写,从库负责读;
**3、水平切分:**将同一个表中的记录拆分到多个结构相同的表中。
**4、垂直切分:**根据数据库里面数据表的相关性进行拆分,把⼀张列⽐较多的表拆分为多张表。

5、切分

1、水平切分

水平切分又称为 Sharding,它是将同一个表中的记录拆分到多个结构相同的表中。
当一个表的数据不断增多时,Sharding 是必然的选择,它可以将数据分布到集群的不同节点上,从而缓存单个数据库的压力。

2、垂直切分

垂直切分是将一张表按列切分成多个表,通常是按照列的关系密集程度进行切分,也可以利用垂直切分将经常被使用的列和不经常被使用的列切分到不同的表中。

在数据库的层面使用垂直切分将按数据库中表的密集程度部署到不同的库中,例如将原来的电商数据库垂直切分成商品数据库、用户数据库等。


3、Sharding 策略

哈希取模:hash(key) % N;
范围:可以是 ID 范围也可以是时间范围;
映射表:使用单独的一个数据库来存储映射关系。

4、Sharding 存在的问题

1. 事务问题使用分布式事务来解决,比如 XA 接口。
2. 连接可以将原来的连接分解成多个单表查询,然后在用户程序中进行连接。
3. ID 唯一性使用全局唯一 ID(GUID)为每个分片指定一个 ID 范围分布式 ID 生成器 (如 Twitter 的 Snowflake 算法)

6、复制

主从复制

主要涉及三个线程:binlog 线程、I/O 线程和 SQL 线程。

binlog 线程 :负责将主服务器上的数据更改写入二进制日志(Binary log)中。
I/O 线程 :负责从主服务器上读取二进制日志,并写入从服务器的中继日志(Relay log)
SQL 线程 :负责读取中继日志,解析出主服务器已经执行的数据更改并在从服务器中重放(Replay)。


读写分离

主服务器处理写操作以及实时性要求比较高的读操作,而从服务器处理读操作

读写分离能提高性能的原因在于:
1、主从服务器负责各自的读和写,极大程度缓解了锁的争用
2、从服务器可以使用 MyISAM,提升查询性能以及节约系统开销;
3、增加冗余,提高可用性。

读写分离常用代理方式来实现,代理服务器接收应用层传来的读写请求,然后决定转发到哪个服务器。

四、索引

资料补充:MySQL 索引及查询优化

1、索引

1、什么是索引?

MySQL索引

索引是一种帮助MySQL 高效获取数据数据结构
----是一种为了提高数据获取速度的数据结构
----主键一定是唯一性索引,唯一性索引并不一定就是主键。

创建每张表的时候都有个.MYI文件生成
索引一般都是指B树(多路搜索树,不一定是二叉树)结构组织的索引---MySQL的索引结构都是B+树---除了B+Tree索引,还有Hash索引、full-text全文索引、R-Tree索引
B-Tree---多路平衡查找树-----对应一个数据表,一共两列数据  id及值,最左边是数据记录的物理地址--查找速度快索引类型:单值索引、唯一索引(该字段数据不可重复)、复合索引(建立在多个字段上)--ALTER TABLE ..... ADD UNIQUE INDEX .....USING BTREE;

2、MySQL索引

索引在存储引擎层实现的,不是在服务器层实现的。不同的存储引擎具有不同的索引类型和实现:

MyISAM:B+Tree的叶子节点的data域存放的是数据记录的地址。在索引检索的时候,首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,取出其data域的值,然后以data域的值为地址读取相应的数据记录。--非聚簇索引。InnoDB:其数据文件本身就是索引文件。索引文件和数据文件是分离的。表数据文件本身就是按B+Tree组织的一个索引结构,树的叶子节点data域保存了完成数据记录。索引的key是数据表的主键,InnoDB表数据文件本身就是主索引。---聚簇索引其余的索引都作为辅助索引,辅助索引的data域存储相应记录主键的值,而不是地址。根据主索引搜索时,直接找到key所在的节点即可取出数据;根据辅助索引查找时,需要先取出主键的值,再走一遍主索引。

1、B+Tree索引

是大多数 MySQL 存储引擎的默认索引类型。
因为不再需要进行全表扫描,只需要对树进行搜索即可,所以查找速度快很多。
因为 B+ Tree 的有序性,所以除了用于查找,还可以用于排序和分组
可以指定多个列作为索引列,多个索引列共同组成键。
适用于全键值、键值范围和键前缀查找,其中键前缀查找只适用于最左前缀查找。如果不是按照索引列的顺序进行查找,则无法使用索引。

InnoDB 的 B+Tree 索引分为主索引和辅助索引主索引的叶子节点 data 域记录着完整的数据记录,这种索引方式被称为聚簇索引。因为无法把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。

辅助索引的叶子节点的 data 域记录着主键的值,因此在使用辅助索引进行查找时,需要先查找到主键值,然后再到主索引中进行查找。

2、哈希索引

哈希索引能以 O(1) 时间进行查找,但是失去了有序性:
1、无法用于排序与分组;
2、只支持精确查找,无法用于部分查找和范围查找。

InnoDB 存储引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非常频繁时,会在 B+Tree 索引之上再创建一个哈希索引,这样就让 B+Tree 索引具有哈希索引的一些优点,比如快速的哈希查找。

3、全文索引

MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而不是直接比较是否相等

查找条件使用 MATCH AGAINST,而不是普通的 WHERE。
全文索引使用倒排索引实现,它记录着关键词到其所在文档的映射
InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。

4、空间数据索引

MyISAM 存储引擎支持空间数据索引(R-Tree),可以用于地理数据存储
空间数据索引会从所有维度来索引数据,可以有效地使用任意维度来进行组合查询。

必须使用 GIS 相关的函数来维护数据。

3、索引的优点及使用条件

索引的优点:

1、大大减少了服务器需要扫描的数据行数。
2、帮助服务器避免进行排序和分组,以及避免创建临时表(B+Tree 索引是有序的,可以用于 ORDER BY 和 GROUP BY 操作。临时表主要是在排序和分组过程中创建,不需要排序和分组,也就不需要创建临时表)。
3、将随机 I/O 变为顺序 I/O(B+Tree 索引是有序的,会将相邻的数据都存储在一起)。

索引的使用条件:

1、对于非常小的表、大部分情况下简单的全表扫描比建立索引更高效;
2、对于中到大型的表,索引就非常有效;
3、但是对于特大型的表,建立和维护索引的代价将会随之增长。这种情况下,需要用到一种技术可以直接区分出需要查询的一组数据,而不是一条记录一条记录地匹配,例如可以使用分区技术。

2、Explain关键字:

将SQL语句执行过程中MySQL引擎的执行参数陈列出来
---可以模拟执行SQL语句,通过模拟执行的参数,知道MySQL怎么处理SQL语句,分析查询语句或表结构的性能瓶颈,进一步优化SQL。
用法:在SQL语句前加上EXPLAIN关键字作用:---可以得知以下信息:表的读取顺序数据读取操作的操作类型哪些索引可以使用哪些索引被实际使用表之间的引用每张表有多少行被优化器查询EXPLAIN得到的参数概念:id:--EXPLAIN中的标识,表示select查询的序列号,包含一组数字,表示查询顺序--说明每个对象(表)的执行顺序,id越大执行越早,id越小执行越晚,id一样的按照从前到后的顺序执行
select_type:--是指查询方式的类型、查询类型---主查询PRIMARY、子查询SUBQUERY、简单查询SIMPLE(单表--无伤大雅)、联合查询UNION(union all)、衍生表查询DERIVED(假表、虚拟表、衍生表)
table:--查询所涉及到的表,真实存在的表或者衍生表
type:--索引使用情况的类型--说本次查询所使用到的索引类型,如果没有用到索引则为ALL--速度优劣由最好到最差:system(系统常量,写死在程序中--const特例)>const(记录在表中的常量,从表中匹配一下)>eq_ref(关联别的表--唯一性索引扫描,对每个索引键,表中只有一条记录与之匹配--主键)(前三个要求过高,过于特殊)>ref(索引不是单独用的,关联别的表--有一个表提供数据----非唯一性索引扫描,返回匹配每个单独值的所有行)>range(范围索引,使用索引树上的范围)>index(查询的东西正好在索引上,也是读全表,但是index是从索引中读取的)(尽量到达上面三种级别,加快速度)>ALL (没有用到索引,遍历全表找到匹配的行)possible_keys:--在多表关联时,可能用到的索引(一般是两张表的所有索引)--可能应用到这张表中的索引,一个或者多个,查询到的索引不一定被查询实际使用。
key:--实际使用的索引。如果为NULL,则没有使用索引
key_len:--被用到的索引的长度--所使用的的索引的果实越短,查询越快----int:4、Varchar:3字节(utf-8)*20(字段长度)+1(null)+2(varchar的存储长度)=63
ref:--两张表在索引关联查询时所关联的索引字段是什么---两表联合查询联合索引是什么--type为ref时,这里的显示所关联的表的名字
rows:--查询字段表中的数据数量--根据表统计信息及索引选用情况,大致估算出找到所需记录所需要读取的行数
Extra:--包含不适合在其他列中显示但是重要的额外信息--using filesort文件内排序(检索到的结果不符合order by)及using temporary(临时空间)尽量不要出现,出现说明效率低

3、索引优化(几十万条以下都差不多)


原则:—避免索引失效

1、全值匹配我最爱—用上所有的组合索引—key_len优先级低于ref
–全值匹配我最爱
–最左前缀要遵守
2、最佳左前缀法则–如果索引了多列,查询从索引的最左前列开始并且不跳过索引中的列。
–带头大哥不能死,中间兄弟不能断
3、不在索引列上做任何操作(计算、函数、类型转换),会导致索引失效转向全表扫描。
–索引列上少计算
4、存储引擎不能使用索引中范围条件右边的列。
–范围之后全失效
5、尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select *
– 覆盖索引不写 *
6、mysql在使用不等于(!=、>、<)的时候有时候无法使用索引会导致全表扫描。
7、null及not null也尽量不要有。
8、like以通配符开头(%…),导致mysql索引失效会变成全表扫描的操作。----匹配时左侧尽量不要模糊
–like百分写最右
9、字符串不加单引号也会导致索引失效。
–VAR引号不可丢
10、少用or,用它连接会导致索引失效。
–不等空值还有OR

如何注意索引优化?

1、SQL语句的优化,充分利用索引
2、创建数据结构时,要尽量考虑到索引的使用,复合索引在建立和使用时,尽量考虑在用户应用查询时,常用的排序方向和字段组合顺序。

4、数据库函数(用户数据库函数导入大的测试数据–上百万级别)

plsql---首创于oracle的一种扩展sql语言,PL/SQL是Oracle数据库对SQL语句的扩展。---SQL的程序化语言--运行在oracle内部的一个类似js脚本的语言--有返回值的叫函数;--没有返回值的叫存储过程(执行一些列的复杂的数据库操作,如自动生成表数据,如对多张表的关联增删改查)

设置参数log_bin_trust_function_creators为true
-------其实就是在Navicat中写函数,表示各种
新建函数----------------随机生成字符串函数、生成随机数字-部门编号
新建存储过程----------插入部门、调用函数—生成部门、员工参数(部门编号起始值,最大值)

5、数据库锁(如何防止库存超卖)

如何解决库存超卖现象?

在高并发的情况下,多个人同时抢购同一库存时,由于数据库的读写操作可以并行执行的原因,会导致修改库存时,库存不足出现超卖现象。
---redis解决:分布式锁、lua脚本、Redisson
---mysql解决:用锁将查询库存的操作和写入库存的操作互斥(1)悲观锁解决库存问题:在select时,将select语句加入一个行锁,与更新库存是语句互斥,可以保证在查询库存时库存不被修改。(2)乐观锁解决库存问题:在select时,加入一个版本字段,每次更新,同时查询和更新版本字段,如果版本字段发生变化,则SQL语句不会执行成功。Select kc,version from sku_info where sku_id = ?----查询两个字段Update sku_info set kc = kc - 1, version = version + 1 where sku_id = ? and version = version

MyISAM–查询用—不存在事务—基本已经淘汰
InnoDB数据库引擎–事务型–支持行锁、表锁----三种锁指行锁、表锁、页锁

表锁

在偏读型数据库中使用表锁----如MyISAM
–很少用表锁–安全–

Lock table 表名
Unlock tables

写锁和读锁阻塞(读写互斥),读与读共享,写和写阻塞(写写互斥)

行锁

------行锁支持事务----没有行锁就没有事务
------没开启事务就是默认提交—开启事务后提交需要手动commit

------行锁可以让读读互斥,可以避免在查询到库存时,库存已经被修改的情况发生
-----update自带行锁—事务

-----在无索引操作时,注意锁的升级(行锁升级表锁)

--- 如何锁定一行?--加上一个行锁
-----查询加上行锁for update ,避免查询和更新同时发生,导致读到的库存数量发生不可重复读的错误
set autocommit = 0;
select kc from product where productname = '电脑' for update
update product set kc = kc - 1 where productname = '电脑'
commit

间隙锁

当使用范围条件不是相等条件检索数据时,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁。
对于键值在条件范围内但是并不存在的记录叫作“间隙”(GAP)
InnoDB也会对这个间隙加锁–这种锁机制就是间隙锁(Next-Key锁)

可能会锁定一个并不存在的记录。
可能也会导致锁的升级,危害别的数据。—因此查询时尽量不使用范围条件检索

页锁

开销和加锁时间介于表锁和行锁之间,会出现死锁;
锁定粒度介于表锁和行锁之间,并发度一般。

数据库的死锁
----多线程死锁

形成了一种因果关系,死循环。—彼此占用了对方的解锁的钥匙

MySQL及数据库部分笔记相关推荐

  1. mysql markdown_mysql+数据库学习笔记(markdown)

    mysql是一种数据库管理系统 数据库>数据表>数据 数据库可以建立多个数据表 数据表中的字段就是表格中列的意思 数据表的数据可以通过php代码(sql语句)来处理 (添加,删除,整理等) ...

  2. 输入mysql -v_Mysql数据库使用笔记

    1.mysql的安装 https://www.cnblogs.com/jintheway/p/6542059.html   (Linux版本) 2.远程连接 windows  https://blog ...

  3. linux数据库创建score表,MySQL数据库学习笔记

    MySQL数据库学习笔记phpma (实验环境:Redhat9.0,MySQL3.23.54) 纲要: 一,连接MySQL phpma 二,MySQL管理与授权 三,数据库简单操作 四, 数据库备份 ...

  4. MySQL数据库学习笔记(十二)----开源工具DbUtils的使用(数据库的增删改查)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  5. 组态王6.55连接MySql数据库(笔记)

    组态王6.55连接MySql数据库(笔记) 1. 安装Mysql数据库 此步骤注意设置用户名和密码 比如设置:root用户的密码为123 2. 安装Navicat图形界面 安装Navicat 8 fo ...

  6. mysql数据库查询笔记_MySql数据库基础笔记(一)

    一.表与库的概念 数据库管理数据,它是以什么样的形式组成的? 生活中的表---->表 table 多行多列,传统的数据库都是这样的;声明了表头,一个表创建好了,剩下的就是往表中添加数据 多张表放 ...

  7. MySQL数据库学习笔记(九)----JDBC的ResultSet接口(查询操作)、PreparedStatement接口重构增删改查(含SQL注入的解释)...

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  8. mysql root密码忘记2018_MySQL数据库之2018-03-28设置及修改mysql用户密码学习笔记

    本文主要向大家介绍了MySQL数据库之2018-03-28设置及修改mysql用户密码学习笔记 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 退出mysql方法 quit或者e ...

  9. 最新、最全、最详细的 MySQL 数据库学习笔记总结(2021最新版)

    数据库是什么 数据库管理系统,简称为DBMS(Database Management System),是用来存储数据的管理系统. DBMS 的重要性 无法多人共享数据 无法提供操作大量数据所需的格式 ...

最新文章

  1. 项目10天投产,测试仅剩2天,如何处理?
  2. Memcache 笔记
  3. change from a ppt to the report
  4. Excel里,vlookup函数各种应用-匹配多列、多条件匹配
  5. 济南“凡尔赛”大姨:一儿一女俩博士,还算可以吧!网友:俺孩要这么棒,我一天发18遍朋友圈...
  6. ORACLE数据库管理工具EM
  7. 【JDBC】JDBC的使用(数据库的增删改查询)
  8. 新兴IT企业特斯拉(六)——Win-Win
  9. Awesome Mac :好用的Mac软件和教程
  10. php毕业综合实践报告范文,php毕业实习报告
  11. 用对象的上转型对象、方法重写,抽象编程:求柱体的体积。
  12. 一个自动化专业的工控人自学编程之路
  13. Koo叔说Shader—开篇
  14. iOS/MAC 数据压缩与解压缩及常用算法 LZMA、ZLIB
  15. 【C语言 实现图书管理系统】
  16. fiddle 下载及配置
  17. GPS导航(4):SIM908模块
  18. 取消win7共享打印机等需要输入密码
  19. strong_alias、weak_alias
  20. 学习SAR和INSAR的一点随笔

热门文章

  1. oracle table()函数
  2. C++ int,long和long long
  3. 【深入理解SSD 实践】对NVMe SSD热插拔时,正确做法是怎样的?
  4. Hypermesh三维网格划分技能,以汽车发动机连杆结构为例
  5. android 系统复位(Reset 恢复出厂设置)9.0源码分析
  6. 计算机网络设备安装检验批,智能建筑工程分为哪些子分部工程与分项工程
  7. java如何判断一个点在一条线段上
  8. 揭秘家用路由器0day漏洞挖掘技术原始环境搭建
  9. fms5序列号_FMS 开发 准备
  10. 推断基因调控网络的算法的评估