目录
一、数据库相关概念
1.数据库
存储和管理数据的仓库,数据是有组织的进行存储
数据库英文名是DataBase,简称DB
2.数据库三大范式
第一范式(1NF):属性不可分割,即每个属性都是不可分割的原子项。(实体的属性即表中的列)
第二范式(2NF):满足第一范式;且不存在部分依赖,即非主属性必须完全依赖于主属性。(主属性即主键;完全依赖是针对于联合主键的情况,非主键列不能只依赖于主键的一部分)
第三范式(3NF):满足第二范式;且不存在传递依赖,即非主属性不能与非主属性之间有依赖关系,非主属性必须直接依赖于主属性,不能间接依赖主属性。(A -> B, B ->C, A -> C)
3.数据库管理系统
管理数据库的大型软件
英文:DataBase Management System,简称DBMS
MySQL是数据库管理系统
常见的数据库管理系统
Oracle:收费的大型数据库,Oracle 公司的产品
MySQL: 开源免费的中小型数据库。后来 Sun公司收购了 MySQL,而 Sun 公司又被 Oracle 收购
SQL Server:MicroSoft 公司收费的中型的数据库。C#、.net 等语言常使用
PostgreSQL:开源免费中小型的数据库
DB2:IBM 公司的大型收费数据库产品
SQLite:嵌入式的微型数据库。如:作为 Android 内置数据库
MariaDB:开源免费中小型的数据库
4.SQL
英文:Structured Query Language,简称 SQL,结构化查询语言
操作关系型数据库的编程语言
定义操作所有关系型数据库的统一标准,可以使用SQL操作所有的关系型数据库管理系统,以后工作中如果使用到了其他的数据库管理系统,也同样的使用SQL来操作。
二、MySQL数据库
1.安装
MySQL :: Download MySQL Community Server (Archived Versions)
建议下载稳定版本,选择适合自己操作系统的版本下载
解压安装包即可
2.配置环境变量
在Path中新建%MYSQL_HOME%\bin
3.配置MySql
在mysql的bin目录下新建my.ini
内容如下:
[mysql]
default-character-set=utf8
[mysqld]
character-set-server=utf8
default-storage-engine=INNODB
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CR
EATE_USER,NO_ENGINE_SUBSTITUTION
上面代码意思就是配置数据库的默认编码集为utf-8和默认存储引擎为INNODB
使用管理员权限打开命令行,输入以下命令
mysqld --initialize-insecure
注意:如果文件夹中有data文件夹,则data文件夹必须为空
出现这样的情况就说明MySQL目录data目录生成成功
4.注册MySQL
同样的,在刚才的命令行中输入一下命令,注册MySQL服务
mysqld -install
5.启动MySQL服务
net start mysql
现在你的计算机已经成为MySQL服务器了
6.修改默认账户密码
在命令行中敲入
mysqladmin -u root password 1234
这里的 1234 就是指默认管理员(即root账户)的密码,可以自行修改成你喜欢的
7.登录
mysql -uroot -p1234
退出:quit
登陆参数:
mysql -u用户名 -p密码 -h要连接的mysql服务器的ip地址(默认127.0.0.1) -P端口号(默认3306) 1
三、MySQL数据库模型
关系型数据库:
关系型数据库是建立在关系模型基础上的数据库,简单说,关系型数据库是由多张能互相连接的 二维表 组成的数据库
看关系型数据库的优点:
·都是使用表结构,格式一致,易于维护。
·使用通用的 SQL 语言操作,使用方便,可用于复杂查询。
·关系型数据库都可以通过SQL进行操作,所以使用方便。
·复杂查询。现在需要查询001号订单数据,我们可以看到该订单是1号客户的订单,而1号订单是李聪这个客户。以后也可以在一张表中进行统计分析等操作。
·数据存储在磁盘中,安全。
MySQL数据模型
四、SQL
1.SQL简介
英文:Structured Query Language,简称 SQL
结构化查询语言,一门操作关系型数据库的编程语言
定义操作所有关系型数据库的统一标准
对于同一个需求,每一种数据库操作的方式可能会存在一些不一样的地方,我们称为“方言”
2.通用语法
①SQL 语句可以单行或多行书写,以分号结尾。
如上,以分号结尾才是一个完整的sql语句。
MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写。
同样的一条sql语句写成下图的样子,一样可以运行处结果。
注释:
单行注释:“-- 注释内容” 或 “#注释内容”
多行注释:/*注释内容*/
3.SQL分类
DDL(Data Definition Language) : 数据定义语言,用来定义数据库对象:数据库,表,列等
DDL简单理解就是用来操作数据库,表等
DML(Data Manipulation Language) 数据操作语言,用来对数据库中表的数据进行增删改
DML简单理解就对表中数据进行增删改
DQL(Data Query Language) 数据查询语言,用来查询数据库中表的记录(数据)
DQL简单理解就是对数据进行查询操作。从数据库表中查询到我们想要的数据。
DCL(Data Control Language) 数据控制语言,用来定义数据库的访问权限和安全级别,及创建用户
DCL简单理解就是对数据库进行权限控制。比如我让某一个数据库表只能让某一个用户进行操作等。
五、DDL:操作数据库
1.查询
show databases;
这四个数据库是mysql安装好自带的数据库 ,以后不要操作这些数据库
2.创建
create database 数据库名称;
3.删除数据库
drop database 数据库名称;
4.使用数据库
使用数据库
use 数据库名称;
查看当前使用的数据库
select database();
六、DDL:操作表
1.查询表
查询当前数据库下所有表名称
show tables;
查询表结构
desc 表名称;
2.创建表
CREATE TABLE 表名 (
字段名1 数据类型1,
字段名2 数据类型2,
…
字段名n 数据类型n
);
# 示例
create table tb_user (
id int,
username varchar(20),
password varchar(32)
);
3.数据类型
①数值
tinyint : 小整数型,占一个字节
int : 大整数类型,占四个字节
eg : age int
double : 浮点类型
使用格式: 字段名 double(总长度,小数点后保留的位数)
eg : score double(5,2)
②日期
date : 日期值。只包含年月日
eg :birthday date :
datetime : 混合日期和时间值。包含年月日时分秒
③字符串
char : 定长字符串。
长度:2^8 字符
优点:存储性能高
缺点:浪费空间
eg : name char(10) 如果存储的数据字符个数不足10个,也会占10个的空间
varchar : 变长字符串。
长度:2^16 字符
优点:节约空间
缺点:存储性能底
eg : name varchar(10) 如果存储的数据字符个数不足10个,那就数据字符个数是几就占几个的空间
tinytext:小文本
长度:2^8 字节
text:文本
长度:2^16 字节
mediumtext:中文本
长度:2^24 字节
longtext:长文本
长度:2^32 字节
4.删除表
DROP TABLE 表名;
5.修改表
①修改表名
ALTER TABLE 表名 RENAME TO 新的表名;
②添加一列
ALTER TABLE 表名 ADD 列名 数据类型;
③修改数据类型
ALTER TABLE 表名 MODIFY 列名 新数据类型;
④修改列名和数据类型
ALTER TABLE 表名 CHANGE 列名 新列名 新数据类型;
⑤删除列
ALTER TABLE 表名 DROP 列名;
七、DML
1.添加数据
给指定列添加数据
INSERT INTO 表名(列名1,列名2,…) VALUES(值1,值2,…);
给全部列添加数据
INSERT INTO 表名 VALUES(值1,值2,…);
批量添加数据
INSERT INTO 表名(列名1,列名2,…) VALUES(值1,值2,…),(值1,值2,…),(值1,值2,…)…;
INSERT INTO 表名 VALUES(值1,值2,…),(值1,值2,…),(值1,值2,…)…;
查询数据
# 查询某表的全部数据
select * from 表名;
# 查询某表的某一列数据
select 列名 from 表名;
2.修改数据
UPDATE 表名 SET 列名1=值1,列名2=值2,… [WHERE 条件] ;
修改语句中如果不加条件,则将所有数据都修改!
3.删除数据
DELETE FROM 表名 [WHERE 条件] ;
如果不加条件,则将所有数据都删除!
八、DQL
1.查询的完整语法
SELECT
字段列表
FROM
表名列表
WHERE
条件列表
GROUP BY
分组字段
HAVING
分组后条件
ORDER BY
排序字段
LIMIT
分页限定
sql语句的查询顺序
FROM-->WHERE-->GROUP BY-->HAVING-->SELECT-->ORDER
2.基础查询
查询多个字段
SELECT 字段列表 FROM 表名;
SELECT * FROM 表名; -- 查询所有数据
去除重复记录
SELECT DISTINCT 字段列表 FROM 表名;
起别名
AS: AS 也可以省略
eg:
select name as 姓名,age as 年龄 from func;
3.条件查询
语法
SELECT 字段列表 FROM 表名 WHERE 条件列表;
条件列表
模糊查询
模糊查询使用like关键字,可以使用通配符进行占位:
(1)_ : 代表单个任意字符
(2)% : 代表任意个数字符
eg:
select * from stu where name like '马%';
4.排序查询
语法
SELECT 字段列表 FROM 表名 ORDER BY 排序字段名1 [排序方式1],排序字段名2 [排序方式2] …;
ASC:升序排列(默认值)
DESC:降序排列
5.聚合函数
函数名 | 功能 |
count(列名) | 统计数量(一般选用不为null的列) |
max(列名) | 最大值 |
min(列名) | 最小值 |
sum(列名) | 求和 |
avg(列名) | 平均值 |
语法
SELECT 聚合函数名(列名) FROM 表;
6.分组查询
语法
SELECT 字段列表 FROM 表名 [WHERE 分组前条件限定] GROUP BY 分组字段名 [HAVING 分组后条件过滤];
where 是分组之前进行限定,不满足where条件,则不参与分组,而having是分组之后对结果进行过滤。
where 不能对聚合函数进行判断,having 可以
7.分页查询
语法
SELECT 字段列表 FROM 表名 LIMIT 起始索引 , 查询条目数;
8.占位符
- ${xxx}:
- 直接将xxx中的内容直接放入sql中的位置,在编译前完成变量替换,会出现sql注入的问题
- ${}本身设计的初衷就是为了参与SQL语句的语法生成,自然而然会导致SQL注入的问题(不会考虑字符过滤问题)。
- ${}将传入的参数直接显示生成在sql中,不会添加引号
- #{xxx}:
- 使用预编译技术,能防止sql注入;
- #{}之所以能够预防SQL注入是因为底层使用了PreparedStatement类的setString()方法来设置参数,此方法会获取传递进来的参数的每个字符,然后进行循环对比,如果发现有敏感字符(如:单引号、双引号等),则会在前面加上一个'/'代表转义此符号,让其变为一个普通的字符串,不参与SQL语句的生成,达到防止SQL注入的效果。
- #{}将传入的参数当成一个字符串,会给传入的参数加一个双引号
九、约束
1.概念
约束是作用于表中列上的规则,用于限制加入表的数据
约束的存在保证了数据库中数据的正确性、有效性和完整性
2.分类
①非空约束
关键字是NOT NULL
保证列中所有的数据不能有null值
②唯一约束
关键字是UNIQUE
保证列中所有的数据各不相同
③主键约束
关键字是PRIMARY KEY
主键是一行数据的唯一标识,要求非空且唯一。
④检查约束
关键字是CHECK
保证列中的值满足某一条件
⑤默认约束
关键字是DEFAULT
保存数据时,未指定值则采用默认值
⑥外键约束
关键字是FOREIGN KEY
外键用来让两个表的数据之间建立连接,保证数据的一致性和完整性
创建表的时候添加键
create table score(
score int(3),
st_id int(16),
cs_id int(16),
primary key(st_id,cs_id),
FOREIGN KEY (st_id) REFERENCES student(id),
FOREIGN KEY (cs_id) REFERENCES classes(id)
);
3.非空约束
-- 创建表时添加非空约束
CREATE TABLE 表名(
列名 数据类型 NOT NULL,
…
);
-- 建完表后添加非空约束
ALTER TABLE 表名 MODIFY 字段名 数据类型 NOT NULL;
-- 删除约束
ALTER TABLE 表名 MODIFY 字段名 数据类型;
4.唯一约束
-- 创建表时添加唯一约束
CREATE TABLE 表名(
列名 数据类型 UNIQUE [AUTO_INCREMENT],
-- AUTO_INCREMENT: 当不指定值时自动增长
…
);
CREATE TABLE 表名(
列名 数据类型,
…
[CONSTRAINT] [约束名称] UNIQUE(列名)
);
-- 建完表后添加唯一约束
ALTER TABLE 表名 MODIFY 字段名 数据类型 UNIQUE;
-- 删除约束
ALTER TABLE 表名 DROP INDEX 字段名;
5.主键约束
-- 创建表时添加主键约束
CREATE TABLE 表名(
列名 数据类型 PRIMARY KEY [AUTO_INCREMENT],
…
);
CREATE TABLE 表名(
列名 数据类型,
[CONSTRAINT] [约束名称] PRIMARY KEY(列名)
);
-- 建完表后添加主键约束
ALTER TABLE 表名 ADD PRIMARY KEY(字段名);
-- 删除约束
ALTER TABLE 表名 DROP PRIMARY KEY;
6.默认约束
-- 创建表时添加默认约束
CREATE TABLE 表名(
列名 数据类型 DEFAULT 默认值,
…
);
-- 建完表后添加默认约束
ALTER TABLE 表名 ALTER 列名 SET DEFAULT 默认值;
-- 删除约束
ALTER TABLE 表名 ALTER 列名 DROP DEFAULT;
7.外键约束
-- 创建表时添加外键约束
CREATE TABLE 表名(
列名 数据类型,
…
[CONSTRAINT] [外键名称] FOREIGN KEY(外键列名) REFERENCES 主表(主表列名)
);
-- 建完表后添加外键约束
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
十、数据库设计
1.简介
数据库设计步骤
需求分析
逻辑分析(通过ER图对数据库进行逻辑建模)
物理设计
维护设计
2.表关系
① 一对多
-- 删除表
DROP TABLE IF EXISTS tb_emp;
DROP TABLE IF EXISTS tb_dept;
-- 部门表
CREATE TABLE tb_dept(
id int primary key auto_increment,
dep_name varchar(20),
addr varchar(20)
);
-- 员工表
CREATE TABLE tb_emp(
id int primary key auto_increment,
name varchar(20),
age int,
dep_id int,
-- 添加外键 dep_id,关联 dept 表的id主键
CONSTRAINT fk_emp_dept FOREIGN KEY(dep_id) REFERENCES tb_dept(id)
);
②多对多
建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
-- 删除表
DROP TABLE IF EXISTS tb_order_goods;
DROP TABLE IF EXISTS tb_order;
DROP TABLE IF EXISTS tb_goods;
-- 订单表
CREATE TABLE tb_order(
id int primary key auto_increment,
payment double(10,2),
payment_type TINYINT,
status TINYINT
);
-- 商品表
CREATE TABLE tb_goods(
id int primary key auto_increment,
title varchar(100),
price double(10,2)
);
-- 订单商品中间表
CREATE TABLE tb_order_goods(
id int primary key auto_increment,
order_id int,
goods_id int,
count int
);
-- 建完表后,添加外键
alter table tb_order_goods add CONSTRAINT fk_order_id FOREIGN key(order_id) REFERENCES tb_order(id);
alter table tb_order_goods add CONSTRAINT fk_goods_id FOREIGN key(goods_id) REFERENCES tb_goods(id);
③一对一
create table tb_user_desc (
id int primary key auto_increment,
city varchar(20),
edu varchar(10),
income int,
status char(2),
des varchar(100)
);
create table tb_user (
id int primary key auto_increment,
photo varchar(100),
nickname varchar(50),
age int,
gender char(1),
desc_id int unique,
-- 添加外键
CONSTRAINT fk_user_desc FOREIGN KEY(desc_id) REFERENCES tb_user_desc(id)
);
3.多表查询
①内连接查询
语法
-- 隐式内连接
SELECT 字段列表 FROM 表1,表2… WHERE 条件;
-- 显示内连接
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 条件;
②外连接查询
语法
-- 左外连接
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件;
-- 右外连接
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件;
左外连接:相当于查询A表所有数据和交集部分数据
右外连接:相当于查询B表所有数据和交集部分数据
③子查询
查询中嵌套查询,称嵌套查询为子查询。
select * from emp where salary > (select salary from emp where name = '猪八戒');
子查询语句结果是单行单列,子查询语句作为条件值,使用 = != > < 等进行条件判断
子查询语句结果是多行单列,子查询语句作为条件值,使用 in 等关键字进行条件判断
子查询语句结果是多行多列,子查询语句作为虚拟表
十一、事务
1.概念
数据库的事务(Transaction)是一种机制、一个操作序列,包含了一组数据库操作命令。
事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么同时成功,要么同时失败。
事务是一个不可分割的工作逻辑单元
2.语法
开启事务
START TRANSACTION;
或者
BEGIN;
提交事务
commit;
回滚事务
rollback;
3.步骤
①开启事务
②执行相关操作
③无异常则提交事务;出现异常则回滚事务
4.特征
事务四个特性:ACID
- 原子性(Atomicity):指事务是一个不可分割的最小工作单位,事务中的操作只有都发生和都不发生两种情况
- 一致性(Consistency):数据库总是从一个一致性的状态转换到另外一个一致性的状态。
- 隔离性(Isolation):一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
- 持久性(Durability):一个事务一旦提交成功,它对数据库中数据的改变将是永久性的,接下来的其他操作或故障不应对其有任何影响。
实现这些特性的原理
- 原子性:靠Undo log实现,即如果一个事务异常或执行失败后进行回滚
- 当事务对数据库进行修改时,InnoDB会生成对应的 undo log;
- 如果事务执行失败或调用了 rollback,导致事务需要回滚,便可以利用 undo log 中的信息将数据回滚到修改之前的样子。
- undo log 属于逻辑日志,它记录的是sql执行相关的信息。
- 当发生回滚时,InnoDB 会根据 undo log 的内容做与之前**相反**的工作
- 一致性:事务的最终目的,即需要数据库层面保证,又需要应用层面进行保证,并且MySQL底层通过两阶段提交事务保证了事务持久化时的一致性。
- 隔离性:靠锁和MVCC实现
- 锁:
- 在 InnoDB 事务中,行锁通过给索引上的索引项加锁来实现。
- 只有通过索引条件检索数据,InnoDB才使用行级锁,否则将使用表锁。
- 行级锁定同样分为两种类型:共享锁和排他锁
- 使用Record Lock和Gap Lock(解决幻读)
- MVCC:多版本并发控制
- DB_TRX_ID:最近修改(修改/插入)事务 ID:记录创建这条记录/最后一次修改该记录的事务 ID
- DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本(存储于 rollback segment 里)
- DB_ROW_ID:隐含的自增 ID(隐藏主键),如果数据表没有主键,InnoDB 会自动以DB_ROW_ID产生一个聚簇索引
- MVCC在事务开启时会为事务生成一个ID,并且在查询时生成一个快照,能看到当前活跃的事务,然后通过比较快照的生成时间和活跃事务的提交时间进行对比,判断读取哪个版本的数据。
- 锁:
- 持久性:靠Redo log实现
- mysq|修改数据的时候会在redo log中记录一份日志数据,就算数据没有保存成功,只要日志保存成功了,数据仍然不会丢失
- 当一条数据需要更新时,InnoDB会先将数据更新,然后记录redoLog 在内存中,然后找个时间将redoLog的操作执行到磁盘上的文件上。
5.事务的提交
mysql中事务是自动提交的
#查询默认提交方式
SELECT @@autocommit;
-- 结果是1表示自动提交,结果是0表示手动提交
#修改提交方式
set @@autocommit = 0;
6.隔离级别
mysql具有四种隔离级别
隔离级别 | 说明 |
---|---|
读未提交 | 一个事务还没提交时,它做的变更就能被别的事务看到 |
读已提交 | 一个事务提交之后,它做的变更才会被其他事务看到 |
可重复读 | 一个事务中,对同一份数据的读取结果总是相同的,无论是否有其他事务对这份数据进行操作,以及这个事务是否提交。InnoDB默认级别 |
串行化 | 事务串行化执行,每次读都需要获得**表级共享锁**,读写相互都会阻塞,隔离级别最高,牺牲系统并发性。 |
不同的隔离级别是为了解决不同的问题。也就是脏读、幻读、不可重复读。
问题 | 说明 |
---|---|
脏读 | 读到了其他事务未提交的数据 |
不可重复读 | 在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据出现不一致的情况 |
幻读 | 在一个事务中,后续读取的数据,在最开始读取的数据中不存在 |
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | 可以出现 | 可以出现 | 可以出现 |
读已提交 | 不允许出现 | 可以出现 | 可以出现 |
可重复读 | 不允许出现 | 不允许出现 | 可以出现 |
串行化 | 不允许出现 | 不允许出现 | 不允许出现 |
十二、索引
0.索引结构
mysql使用B+树做索引
- B+树是一种平衡多叉树结构,有良好的平衡性和稳定性。每个节点可以存储多个关键字和对应指针,在查找、插入、删除操作时,能够快速定位到目标数据所在的叶子节点。
- B+树叶子节点使用双向链表相连,范围查询、排序效率很高。
- B+树高度低,减少磁盘I/O操作,提高检索效率。
1.索引分类
主键索引:PRIMARY KEY
唯一索引:UNIQUE
普通索引:INDEX
全文索引:FULLTEXT
组合索引:最左前缀原则
2.添加索引
(1)创建表时添加索引
create table TableName ([index/unique index/fulltext index] IndexName(ColumnName,...) )
(2)创建表后添加索引
create [unique index/fulltext index/index] IndexName on TableName(ColumnName,...)
(3)修改表的方式添加索引
alter table TableName add [primary key/unique/fulltext/index] IndexName(ColumnName,...)
(4)对字段进行限制
将ColumnName改为ColumnName(n)即可限定只索引该字段的前n个字符
3. 删除索引
drop index IndexName on TableName; -- 主键索引不能用此方法删除
alter table TableName drop index IndexName; -- 主键索引不能用此方法删除
alter table TableName drop primary key; -- 可以删除主键索引,前提是主键没有自增 auto_increment,如果有自增将无法删除,需先删除自增
4.组合索引&前缀索引
组合索引和前缀索引都是索引技巧 不是索引类型
组合索引:即 将多个字段放在一起进行索引,将多个字段一起添加到同一索引中
示例:
alter table user_demo add index name_city_age (login_name(16), city, age);
该组合即login_name,city,age共同索引
前缀索引:组合索引具有最左前缀索引的特点,即:想使用后面的字段索引,它前面的字段必须全部存在
可以理解为:这三个字段的优先级 login_name > city > age
5.不走索引的sql
使用 explain + sql 可以看出该sql语句使用了什么索引,方便优化
(1)索引列中有空值,Count(*)不走索引
(2)索引列上有函数运算
(3)所有索引列参与计算,不走索引
(4)隐式转换不走索引
(5)表的数据小或者查询大部分数据不走索引
(6)like "%ab%"不走索引,like "ab%"走索引
十三、SQL优化
sql优化
1. `select *` 浪费资源,减少使用,且不走索引
2. `union all`比`union`更快(但是不去重)
3. 小表驱动大表:大表 `in` 小表 ; 小表 `exists` 大表;
4. 批量插入数据尽量使用`insertBatch`,而不是循环(循环会多次请求数据库)
5. 多使用`limit`,减少内存消耗
6. 海量数据查询分页,使用条件查询结合 `limt size`,去替代`limit start size`
7. 使用连接查询代替子查询(子查询会为子查询额外创建一个表)
8. `join`的表不能太多,否则容易选错索引
9. 索引不宜太多,因为在增删改查的时候都需要更新索引表(使用联合索引)
10. 将`group by` 后接的`having`条件适当提到前面的`where`中
慢查询日志
当语句执行时间较长时,通过日志的方式进行记录
临时开启慢查询日志:`set global slow_query_log = on;`
临时设置慢查询时间临界点(高于该临界点的都记录):`set long_query_time = 1;` (单位:秒)
设置慢查询日志的存储方式:
- set globle log_output = table; (这里是将慢查询日志以表的形式存储到mysql的slow_log中)
- set globle log_output = file;(将慢查询日志以文件的形式存储,使用以下命令查看文件存储位置:show variables like 'slow_query_log_file';)
如永久生效需要修改配置文件 my.cnf 中[mysqld]下配置
[mysqld]
slow_query_log=1
slow_query_log_file=/var/lib/mysql/cakin-slow.log
long_query_time=1
log_output=table
explain执行计划
- id: 在一个大的查询语句中**每个 SELECT** 关键字都对应一个唯一的 id
- select_type: SELECT 关键字对应的哪个查询的类型
- SIMPLE:简单的 select 查询,不使用 union 及子查询
- PRIMARY:最外层的 select 查询
- UNION:UNION 中的第二个或随后的 select 查询,不依赖于外部查询的结果集
- UNION RESULT:UNION 结果集
- SUBQUERY:子查询中的第一个 select 查询,不依赖于外 部查询的结果集
- DEPENDENT UNION:UNION 中的第二个或随后的 select 查询,依赖于外部查询的结果集
- DEPENDENT SUBQUERY:子查询中的第一个 select 查询,依赖于外部查询的 结果集
- DERIVED: 用于 from 子句里有子查询的情况。 MySQL 会 递归执行这些 子查询, 把结果放在临时表里。 MATERIALIZED:物化子查询
- UNCACHEABLE SUBQUERY: 结果集不能被缓存的子查询,必须重新为外层查 询的每一行进行评估,出现极少。
- UNCACHEABLE UNION:UNION 中的第二个或随后的 select 查询,属于不可缓 存的子查询,出现极少
- table:表名
- partitions:匹配的分区信息
- type:针对单表的访问方法
- possible_keys:可能用到的索引
- key:实际上使用的索引
- key_len:实际使用到的索引长度
- ref:当使用索引列等值查询时,与索引列进行等值匹配的对象信息
- rows:预估的需要读取的记录条数
- filtered:某个表经过搜索条件过滤后剩余记录条数的百分比
- Extra:—些额外的信息
十四、MySQL和MangoDB对比(关系型数据库和文档型对比)
Mysql:
- 关系数据库系统,相关信息可能存储在单独的表中,但通过使用关联查询来关联。通过使用这种方式,使得数据重复量被最小化。
- 关系型数据库的最大特点就是事务的一致性
- 为了维护一执行需要消耗大量的性能
MangoDB:
- 少量数据时,数据存在内存中。当内存不够时,只将热点数据放在内存,其他存入磁盘
- 数据存储在类似JSON的文档中,并且文档中每个json串结构可能有所不同
- 使用动态模式,这意味着您可以在不首先定义结构的情况下创建记录,例如字段或其值的类型
- 支持多种存储格式(mysql只支持基本类型)
- 设计了高可用性和可扩展性,并提供了即用型复制和自动分片功能。
- 简化了开发,因为 MongoDB 文档自然映射到现代的面向对象编程语言。使用 MongoDB 可以避免将代码中的对象转换为关系表的复杂对象关系映射(ORM)层。