MySQL
基础
MySQL概述
关系型数据库
概念:建立在关系模型基础上,由多张相互连接的二维表组成的数据库
特点:
- 使用表存储数据,格式统一,便于维护
- 使用
SQL
语言操作,标准统一,使用方便
SQL
SQL通用语法
- SQL 语句可以单行或者多行书写,以分号结尾
- SQL 语句可以空格/缩进来增强语句的可读性
- MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写
- 注释
- 单行注释:-- 注释内容或 # 注释内容
- 多行注释:/* 注释内容 */
SQL 分类
分类 | 全称 | 说明 |
---|---|---|
DDL | Data Definition Language | 数据定义语言,用来定义数据库对象(数据库,表,字段) |
DML | Data Manipulation Language | 数据操作语言,用来对数据库表中的数据进行增删改 |
DQL | Data Query Language | 数据查询语言,用来查询数据库中的表的记录 |
DCL | Data Control Language | 数据控制语言,用来创建数据库用户、控制数据库访问权限 |
DDL
数据库操作
查询
# 查询所有数据库
SHOW DATABASES;
# 查询当前数据库
SELECT DATABASE();
创建
CREATE DATABASE [IF NOT EXISTS] 数据库名 [DEFAULT CHARSET 字符集] [COLIATE 排序规则];
删除
DROP DATABASE [IF EXISTS] 数据库名;
使用
USE 数据库名;
表操作-查询
查询当前数据库所有表
SHOW TABLES;
查询表结构
DESC 表名;
查询指定表的建表语句
SHOW CREATE TABLE 表名;
表操作-创建
CREATE TABLE 表名(
字段1 字段1类型[COMMENT 字段1注释],
字段2 字段2类型[COMMENT 字段2注释],
字段3 字段3类型[COMMENT 字段3注释],
...
字段n 字段n类型[COMMENT 字段n注释]
)[COMMENT 表注释];
数据类型
类型 | 大小 | 有符号 | 无符号 | 描述 |
---|---|---|---|---|
TINYINT | 1 byte | (-128, 127) | (0, 255) | 小整数值 |
SMALLINT | 2 byte | (-32768, 32767) | (0, 65535) | 大整数值 |
MEDIUINT | 3 byte | (-8388608, 8388607) | (0, 4294967295) | 大整数值 |
INT(INTEGER) | 4 byte | (-2^63, 2^63-1) | (0, 2^64-1) | 大整数值 |
BIGINT | 8 byte | 极大整数值 | ||
FLOAT | 4 byte | 单精度浮点数 | ||
DOUBLE | 8 byte | 双精度浮点数 | ||
DECIMAL | 依赖于M(精度)和D(标度)的值 | 依赖于M(精度)和D(标度)的值 | 小数值(精确定点数) |
类型 | 大小 | 描述 |
---|---|---|
CHAR | 0-255 bytes | 定长字符串 |
VARCHAR | 0-65535 bytes | 变长字符串 |
TINYBLOB | 0-255 bytes | 不超过255个字符的二进制数据 |
TINYTEXT | 0-255 bytes | 短文本字符串 |
BLOB | 0-65535 bytes | 二进制形式的长文本数据 |
TEXT | 0-65535 bytes | 长文本数据 |
MEDIUBLOB | 0-16777215 bytes | 二进制形式的中等长度文本数据 |
MEDIUTEXT | 0-16777215 bytes | 中等长度文本数据 |
LONGBLOB | 0-4294967295 bytes | 二进制形式的极大文本数据 |
LONGTEXT | 0-4294967295 bytes | 极大文本数据 |
类型 | 大小 | 范围 | 格式 | 描述 |
---|---|---|---|---|
DATE | 3 | 1000-01-01 至 9999-12-31 | YYYY-MM-DD | 日期值 |
TIME | 3 | -838:59:59 至 838:59:59 | HH:MM:SS | 时间值或持续时间 |
YEAR | 1 | 1901 至 2155 | YYYY | 年份值 |
DATETIME | 8 | 1000-01-01 00:00:00 至 9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
TIMESTAMP | 4 | 1970-01-01 00:00:01 至 2038-01-19 03:14:07 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值,时间戳 |
表操作
添加字段
ALTER 表名 ADD 字段名 类型(长度) [comment 注释] [约束]
修改数据类型
ALTER 表名 MODIFT 字段名 新数据类型(长度);
修改字段名和字段类型
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) [comment '注释'] [约束];
删除字段
ALTER TABLE 表名 DROP 字段名;
修改表名
ALTER TABLE 表名 RENAME TO 新表名;
删除表
DROP TABLE [IF EXISTS] 表名;
删除指定表,并重新创建该表
TRUNCATE TABLE 表名;
DML
添加数据
给指定字段添加数据
mysqlINSERT INTO 表名 (字段1, 字段2...) VALUES (值1, 值2...);
给全部字段添加数据
mysqlINSERT INTO VALUES (值1, 值2...);
批量添加数据
mysqlINSERT INTO 表名 (字段1, 字段2...) VALUES (值1, 值2...),(值1, 值2...);
mysqlINSERT INTO 表名 VALUES (值1, 值2...),(值1, 值2...);
修改数据
UPDATE 表名 SET 字段1 = 值1, 字段2 = 值2,... [WHERE 条件];
删除数据
DELETE FROM 表名 [WHERE 条件];
DQL
语法
SELECT 字段列表
FROM 表名列表
WHERE 条件列表
GROUP BY 分组字段列表
c 分组后条件列表
ORDER BY 排序字段列表
LIMIT 分页参数
基本查询
查询多个字段
mysqlSELECT 字段1, 字段2, ... FROM 表名; SELECT * FROM 表名;
设置别名
mysqlSELECT 字段1 [AS 别名1], 字段2 [AS 别名2], ... 表名;
去重
mysqlSELECT DISTINCT 字段列表 FROM 表名;
条件查询
语法
mysqlSELECT 字段列表 FROM 表名 WHERE 条件列表;
条件
比较运算符 功能 > 大于 >= 大于等于 < 小于 <= 小于等于 = 等于 <> 或 != 不等于 BETWEEN...AND... 在某个范围之间(含最大、最小值) IN(...) 在in之后的列表中的值,多选一 LIKE 占位符 模糊匹配(_匹配单个字符,%匹配任意个字符) IS NULL 是 null 逻辑运算符 功能 AND 或 && 并且(多个条件同时成立) OR 或 || 或者(多个条件满足一个) NOT 或 ! 非,不是
聚合函数
介绍:
将一列数据作为整体,进行纵向计算。
常见的聚合函数:
函数 功能 count 统计数量 max 最大值 min 最小值 avg 平均值 sum 求和 语法
mysqlSELECT 聚合函数(字段列表) FROM 表名;
分组查询
语法
mysqlSELECT 字段列表 FROM 表名 [where 条件] GROUP BY 分组字段名 [HAVING 分组后过滤条件];
where 和 having 去区别:
- 执行时机不同:where 是分组之前进行过滤,不满足条件不参与分组;而 having 是分组之后对结果进行过滤。
- 判断条件不同:where 不能对聚合函数进行判断,而 having 可以。
GROUP_CONCAT([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符'])
分组查询中的字段列表,使用某个符号进行分隔
排序查询
语法
mysqlSELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1, 字段2 排序方式2;
排序方式
- ASC:升序
- DESC:降序
分页查询
语法
mysqlSELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询记录数;
注意
- 起始索引从0开始,起始索引 = (查询页码 - 1) * 每页显示记录数。
- 分页查询是数据库的方言,不同的数据库有不同的实现,MYSQL 中是LIMIT。
- 如果查询的是第一页数据,起始索引是可以省略的,直接简写为 limit 10。
DCL
用户管理
查询用户
mysqlUSE MYSQL; SELECT * FROM user;
创建用户
mysqlCREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
修改用户密码
mysqlALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码';
删除用户
mysqlDROP USER '用户名'@'主机名';
权限管理
常用权限
权限 功能 ALL, ALL PRIVILEGES 所有权限 SELECT 查询数据 INSERT 插入数据 UPDATE 修改数据 DELETE 删除数据 ALTER 修改表 DROP 删除数据库/表/视图 CREATE 创建数据库/表 权限控制
查询权限
mysqlSHOW GRANTS FOR '用户名'@'主机名';
授予权限
mysqlGRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
撤销权限
mysqlREVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
函数
函数是指一段可以直接被另一段程序调用的程序或代码。
字符串函数
函数 | 功能 |
---|---|
CONCAT(S1,S2,...Sn) | 字符串拼接 |
LOWER(str) | 将str 转为小写 |
UPPER(str) | 将str 转为大写 |
LPAD(str,n,pad) | 左填充,用字符串pad对str的左边进行填充,达到n个字符 |
RPAD(str,n,pad) | 右填充,用字符串pad对str的右边进行填充,达到n个字符 |
TRIM(str) | 去掉字符串前后空格 |
SUBSTRING(str,start,len) | 字符串截取 |
数值函数
函数 | 功能 |
---|---|
CEIL(x) | 向上取整 |
FLOOR(x) | 向下取整 |
MOD(x,y) | 返回x/y的模 |
RAND() | 返回0~1内的随机数 |
ROUND(x,y) | 求参数x的四舍五入值,保留y位小数 |
日期函数
函数 | 功能 |
---|---|
CURDATE() | 返回当前日期 |
CURTIME() | 返回当前时间 |
NOW() | 返回当前日期和时间 |
YEAR(date) | 获取指定date的年份 |
MONTH(date) | 获取指定date的月份 |
DAY(date) | 获取指定date的日期 |
DATE_ADD(date, INTERVAL expr unit) | 返回一个日期/时间值加上一个时间间隔 |
DATEDIFF(date1, date2) | 返回两个时间之间的天数 |
DATE_ADD()用于指定日期添加时间间隔的函数。 它的语法如下: DATE_ADD(date, INTERVAL expr unit)
date是需要增加(减少)时间的日期, expr是需要增加(减少)的时间数量, unit是需要增加(减少)的时间单位(如天、小时、分钟等)。
流程控制函数
函数 | 功能 |
---|---|
IF(value, t, f) | 如果value为true,则返回t,否则返回f |
IFNULL(value1, value2) | 如果value1不为空,返回value1,否则返回value2 |
CASE WHEN [val1] THEN [res1] ... ESLE [default] END | 如果val1为true,返回res1,...否则返回默认值 |
CASE [expr] WHEN [val1] THEN [res1] ... ELSE [dafault] END | 如果expr的值等于val1,返回res1, ...否则返回默认值 |
约束
- 概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。
- 目的:保证数据库中的数据正确、有效性和完整性。
- 分类:
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | 限制字段的数据不能为null | NOT NULL |
唯一约束 | 保证该字段的所有数据都是唯一、不重复的 | UNIQUE |
主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | PRIMARY KTY |
默认约束 | 保存数据时,如果未指定该字段的值,则采用默认约束 | DEFAULT |
检查约束 | 保证字段值满足某一个条件 | CHECK |
外键约束 | 用来让两张表的数据之间建立连接,保证数据一致性和完整性 | FOREIGN KEY |
外键
- 添加外键
CREATE TABLE 表名(
字段名 数据类型,
...
[CONSTRAINT] [外键名称] FOREIGN KEY(外键字段名) REFERENCES 主表(主列表名)
);
ALERT TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(外键字段名) REFERENCES 主表(主列表名);
- 删除外键
ALERT TABLE 表名 DROP FOREIGN KEY 外键名称;
多表查询
概述
项目开发中,在进行数据库结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表之间也存在着各种联系。
- 一对多
- 多对多
- 一对一
概述:指从多张表中查询数据
笛卡儿积:笛卡尔乘积是指在数学中,两个集合A集合和B集合的所有组合情况。(在多表查询时,需要消除无效的笛卡尔积)
分类
- 连接查询
- 内连接:相当于查询A、B交集部分数据
- 外连接:
- 左外连接:查询左表的所有数据,以及两张表交集部分数据
- 右外连接:查询右表的所有数据,以及两张表交集部分数据
- 自连接:当前表与自身的连接查询,自连接必须使用表别名
- 子查询
内连接
# 隐式内连接
SELECT 字段列表 FROM 表1, 表2 WHERE 条件;
# 显示内连接
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件;
外连接
# 左外连接 查询表1数据
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件;
# 右外连接 查询表2数据
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件;
自连接
SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件;
联合查询
对于联合查询的多张表,列数必须保持一致,字段类型也需要保持一致
union all 会将全部的数据直接合并,union 会对合并之后的数据去重
SELECT 字段列表 FROM 表A...
UNION [ALL]
SELECT 字段列表 FROM 表B...;
自查询
概念:SQL 语句中嵌套 SELECT 语句,成为嵌套查询,又称子查询
- 标量子查询(子查询结果为单值)
- 列子查询(结果为一列)
- 行子查询(结果为一行)
- 表子查询(结果为多行多列)
标量子查询
# 常见操作符 = <> > >= < <=
SELECT 字段列表 FROM 表A WHERE (SELECT 字段 FROM 表B WHERE 条件);
列子查询
# 常见操作符 IN、 NOT IN、ANY、SOME、ALL
行子查询
# 常见操作符 =、<>、IN、NOT IN、
表子查询
# 常见操作符 IN
事务
事务操作
# 方法一
# 事务自动提交
select @@autocommit;
# 事务设置
set @@autocommit = 1;
# 提交事务
commit;
# 回滚事务
rollback;
# 方法二
# 开启事务
start transaction 或 begin;
# 提交事务
commit;
# 回滚事务
rollback;
事务四大特性
- 原子性:事务时不可分隔的最小操作单元,要么全部成功,要么全部失败。
- 一致性:事务完成时,必须使所有的数据都保持一致。
- 隔离性:数据库系统提交的隔离机制,保证事务在不受外部并发操作影响的独立环境下进行。
- 持久性:事务一旦提交或回滚,他对数据哭中数据的改变就是永久的。
事务并发问题
- 脏读:一个事务读到另一个事务还没有提交的数据。
- 不可重复读:一个事务先后读取同一条数据,但两次读取的数据不同,称之为不可重复读。
- 幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据存在,好像出现了幻影。
事务隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncommitted | ✔ | ✔ | ✔ |
Read committed | ✘ | ✔ | ✔ |
Repeatable(默认) | ✘ | ✘ | ✔ |
Serializable | ✘ | ✘ | ✘ |
# 查看隔离级别
select @@transaction_isolation;
# 设置隔离级别
set [session | global] transaction isolation level { 隔离级别 }
进阶
存储引擎
MySQL 体系结构
- 连接层
- 服务层
- 引擎层
- 存储层
存储引擎简介
存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎事基于表的,而并不是基于库的,所以存储引擎可也呗成为表引擎。
创建表时选择存储引擎
CREATE TABLE 表名(
...
) ENGINE=INNODB;
查看当前数据库支持的存储引擎
SHOW ENGINES;
存储引擎特点
- InnoDB
- 介绍:InnoDB是一种兼顾高可靠性和高性能的通用存储引擎
- 特点
- DML操作遵从ACID模型,支持事务
- 行级锁,提高并发访问性能
- 支持外键约束,保证数据的完整性和正确性
- 文件:xxx.ibd,xxx表示表名,InnoDB引擎的每张表都会对应这样的一个表空间,存储该表的表结构、数据和索引
- MyISAM
- 介绍:MyISAM是MySQL在早期的默认存储引擎
- 特点
- 不支持事务,不支持外键
- 支持表锁,不支持行锁
- 访问速度快
- 文件
- xxx.sdi:存储表结构信息
- xxx.MYD:存储数据
- xxx.MYI:存储索引
- Memory
- 介绍:Memory引擎的表数据是存储在内存中的,由于受到硬件问题或断电问题的影响,只能讲这些表作为临时表或缓存使用。
- 特点
- 内存存放
- hashsuoy
- 文件:xxx.sdi:存储表结构信息
存储引擎选择
- InnoDB:是Mysql默认的存储引擎,支持事务,外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询之外,还包含很多的更新、删除操作,那么InnoDB村粗引擎比较合适。
- MyISAM:如果应用事宜读操作和插入操作为主,只有很少的更新和删除,并且对事务的完整性、并发性要求不高
- Memory:将所有数据保存在内存中,访问速度快,通常用于临时表及缓存,Memory的缺陷是对表的大小有限制,太大的表无法缓存在内存中,而且无法保障数据的安全性。
索引
索引的帮助MySQL 高效获取数据的数据结构。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。
优缺点
- 优势
- 提高数据检索效率,降低数据库的IO成本
- 通过索引对数据进行排序,降低数据排序的成本,降低CPU的消耗。
- 劣势
- 索引列也是要占用空间的
- 索引大大提高了查询效率,同时却也降低更新表的速度,如对表进行INSERT,UPDATE,DELETE,效率降低。
索引结构
索引结构 | 描述 |
---|---|
B+Tree索引 | 最常见的索引类型,大部分引擎都支持B+索引 |
Hash索引 | 底层数据结构是用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范围查询 |
R-Tree(空间索引) | 空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类型 |
Full-text(全文索引) | 是一种通过建立倒排索引,快速匹配文档的方式 |
索引分类
分类 | 含义 | 特点 | 关键字 |
---|---|---|---|
主键索引 | 针对于表中主键创建的索引 | 默认自动创建,只能有一个 | PRIMARY |
唯一索引 | 避免同一个表中某数据列中的值重复 | 可以有多个 | UNIQUE |
常规索引 | 快速定位特点数据 | 可以有多个 | |
全文索引 | 全文索引查找的是文本中的关键词,而不是比较索引中的值 | 可以有多个 | FULLTEXT |
分类 | 含义 | 特点 |
---|---|---|
聚焦索引 | 将数据存储与索引放到了一块,索引结构的叶子节点保存了行数据 | 必须有,而且只有一个 |
二级索引 | 将数据与索引分开存储,索引结构的叶子节点关联的是对应主键 | 可以存在多个 |
索引语法
创建索引
CREATE [UNIQUE | FULLTEXT] INDEX index_name ON table_name (index_col_name);
查看索引
SHOW INDEX FROM table_name;
删除索引
DROP INDEX index_name ON table_name;
SQL性能分析
SQL执行频率
MySQL 客户端连接成功后,通过 show [session | global] status 命令可以提供服务器状态信息。
mysqlSHOW GLOBAL STATUS LIKE 'Com_______'
慢查询日志
慢查询日志记录了所有执行时间超过指定参数(long_query_time, 单位秒,默认10秒)的所有SQL语句的日志
MySQL默认没有开启,需要自行开启。
profile详情
show profile 能够在SQL优化时帮助我们了解时间都耗费到哪里去了。通过have_profile参数,能够看到当前MySQL是profile操作:
mysqlSELECT @@have_profile; SHOW PROFILES;
explain执行计划
EXPLAIN或者 EDSC命令获取 MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序。
mysqlEXPLAIN SELECT 字段列表 FROM 表名 WHERE 条件;