前端进阶-MySQL知识点
近段时间,利用工作之外的闲暇时间学习了koa和mysql,丰富了些许自己的技术体系;也在此将自己所总结的关于mysql的基础知识点提供给一样学习mysql的小伙伴们做一个参考,希望对大家有所帮助,如其中有错误之处,欢迎大家在评论区指正,谢谢!
一、数据库的基础概念
1-1、传统数据库与新型数据库的区别
传统数据库(关系型数据库):MySQL,Oracle,SQL Server等
优点:
- 易于维护:都是使用表结构,格式一致;
- 使用方便:SQL语言通用,可用于复杂查询;
- 复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。
缺点:
- 读写性能比较差,尤其是海量数据的高效率读写;
- 固定的表结构,灵活度稍欠;
- 高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。
新型数据库(非关系型数据库):mongoDB,redis等
优点:
- 格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。
- 速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;
- 高扩展性;
- 成本低:nosql数据库部署简单,基本都是开源软件。
缺点:
- 不提供sql支持,学习和使用成本较高;
- 无事务处理;
- 数据结构相对复杂,复杂查询方面稍欠。
1-2、传统数据库组成
传统型数据库中,数据的组织结构分为数据库(database),数据表(table),数据行(row),字段(field)四部分组成。
1-3、MySQL的体系结构
- 连接层
最上层是一些客户端和链接服务,包含本地sock 通信和大多数基于客户端/服务端工具实现的类似于 TCP/IP的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程 池的概念,为通过认证安全接入的客户端提供线程。同样在该层上可以实现基于SSL的安全链接。服务 器也会为安全接入的每个客户端验证它所具有的操作权限。
- 服务层
第二层架构主要完成大多数的核心服务功能,如SQL接口,并完成缓存的查询,SQL的分析和优化,部 分内置函数的执行。所有跨存储引擎的功能也在这一层实现,如 过程、函数等。在该层,服务器会解 析查询并创建相应的内部解析树,并对其完成相应的优化如确定表的查询的顺序,是否利用索引等, 最后生成相应的执行操作。如果是select语句,服务器还会查询内部的缓存,如果缓存空间足够大, 这样在解决大量读操作的环境中能够很好的提升系统的性能。
- 引擎层
存储引擎层, 存储引擎真正的负责了MySQL中数据的存储和提取,服务器通过API和存储引擎进行通 信。不同的存储引擎具有不同的功能,这样我们可以根据自己的需要,来选取合适的存储引擎。数据库 中的索引是在存储引擎层实现的。
- 存储层
数据存储层, 主要是将数据(如: redolog、undolog、数据、索引、二进制日志、错误日志、查询 日志、慢查询日志等)存储在文件系统之上,并完成与存储引擎的交互。
二、数据库语法操作(DDL)
2-1、操作数据库类
- 查询所有数据库:
how databases; - 查询当前数据库:
select database(); - 创建数据库:
create database [ if not exists ] 数据库名 [ default charset 字符集 ] [ collate 排序 规则 ] ; - 删除数据库:
drop database [ if exists ] 数据库名 ; - 切换数据库:
use 数据库名 ;
2-2、操作数据库表
- 查询当前数据库所有表:
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 表注释 ] ;
create table tb_user(
id int comment '编号',
name varchar(50) comment '姓名',
age int comment '年龄',
gender varchar(1) comment '性别'
) comment '用户表';
- 表操作-修改:
- 添加字段:
ALTER TABLE 表名 ADD 字段名 类型 (长度) [ COMMENT 注释 ] [ 约束 ]; - 修改数据类型:
ALTER TABLE 表名 MODIFY 字段名 新数据类型 (长度); - 修改字段名和字段类型:
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型 (长度) [ COMMENT 注释 ] [ 约束 ]; - 删除字段:
ALTER TABLE 表名 DROP 字段名; - 修改表名:
ALTER TABLE 表名 RENAME TO 新表名;
2-3、表操作-删除
- 删除表:
DROP TABLE [ IF EXISTS ] 表名; - 删除指定表, 并重新创建表:
TRUNCATE TABLE 表名 ;
2-3、表操作-删除
2-3-1、数值类型
2-3-2、字符串类型
备注: char 与 varchar 都可以描述字符串,char是定长字符串,指定长度多长,就占用多少个字符,和 字段值的长度无关 。而varchar是变长字符串,指定的长度为最大占用长度 。相对来说,char的性 能会更高些。
2-3-3、日期时间类型
三、MySQL的增删改查基本语法
3-1、select查询数据
SELECT 语句用于从表中查询数据。执行的结构被存储在一个结果表中(被称为结果集)。
-- 从 FROM 指定的【表】,查询出【所有的】数据。* 表示【所有列】
SELECT * FROM 表名称
-- 从 FROM 指定的【表】,查询出【指定的】类名称(字段)的数据。
SELECT 列名称 FROM 表名称
注意: SQL 语句中的关键字对 大小写不敏感 。 SELECT 等效于 select ,FROM 等效于 from。
3-2、insert into增加插入数据
-- 语法解读 向指定的表中,插入如下几列的数据,列的值通过 values 指定
-- 注意: 列和值要 一一 对应,多个列和多个值之间,使用英文逗号分隔
INSERT INTO table_name(列1,列2,...) VALUES (值1,值2,...)
注意: MySQL 新版本插入语法:INSERT INTO ev_users SET ?
3-3、update 更新数据
-- 语法解读 :
-- 1、用 UPDATE 指定要更新哪个表中的数据
-- 2、用 SET 指定列对应的新值
-- 3、用 WHERE 指定更新的条件
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
3-4、where根据条件增删改查
-- 语法解读 :
-- 1、查询语句中的 WHERE 条件
SELECT 列名称 FROM 表名称 WHERE 列 运算符 值
-- 2、更新语句中的 WHERE 条件
UPDATE 表名称 SET 列 = 新值 WHERE 列 运算符 值
-- 3、删除语句中的 WHERE 条件
DELETE FROM 表名称 WHERE 列 运算符 值
WHERE 子句用于 限定选择的标准。在 SELECT,UPDATE,DELETE 语句中,皆可使用 WHERE 子句来限定选择的标准。
3-5、where中的运算符
3-6、where 中的 and 和 or
- AND 和 OR 在 WHERE 子语句中把两个或多个条件结合起来。
- AND 表示
必须同时满足多个条件,相当于 JavaScript 中的 && 运算符。 - OR 表示
只要满足任意一个条件即可,相当于 JavaScript 中的 || 运算符。
SELECT * FROM users WHERE status = 0 and id < 3
3-7、order by升序降序
语法: SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1 , 字段2 排序方式2
排序方式:
ASC: 升序(默认值)DESC: 降序
3-8、as 给列起别名
-- 使用 AS 关键字给列起别名
SELECT count(*) as total FROM users WHERE status=0
注意: as 可以省略: select workaddress '工作地址' from emp;
3-9、分页查询数据
语法: SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询记录数 ;
注意事项:
- 起始索引从0开始,起始索引 = (查询页码 - 1)* 每页显示记录数。
- 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL中是LIMIT。
- 如果查询的是第一页数据,起始索引可以省略,直接简写为 limit 10。
3-10、分页查询数据
语法: SELECT 字段列表 FROM 表名 [ WHERE 条件 ] GROUP BY 分组字段名 [ HAVING 分组 后过滤条件 ]
3-11、聚合函数
语法: SELECT 聚合函数(字段列表) FROM 表名 ; ( 注意 : NULL值是不参与所有聚合函数运算的)
案例:
-- 根据性别分组,统计男性员工 和 女性员工的数量
select gender, count(*) from emp group by gender
3-12、having 与 where 的区别
执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组执行 之后对结果进行过滤。
判断条件不同:where不能对聚合函数进行判断,而having可以。
注意事项:
- 分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义。
- 执行顺序: where > 聚合函数 > having 。
- 支持多字段分组, 具体语法为 : group by columnA,columnB 。
3-13、语法执行顺序
四、数据控制语言(DCL)
4-1、管理用户
- 查询用户:
select * from mysql.user; - 创建用户:
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码'; - 修改用户密码:
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码' ; - 删除用户:
DROP USER '用户名'@'主机名' ;
注意事项:
- 在MySQL中需要通过用户名@主机名的方式,来唯一标识一个用户。
- 主机名可以使用 % 通配。
- 这类SQL开发人员操作的比较少,主要是DBA( Database Administrator 数据库 管理员)使用。
4-2、权限控制
- 查询权限:
SHOW GRANTS FOR '用户名'@'主机名' ; - 授予权限:
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名'; - 撤销权限:
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
注意事项:
- 多个权限之间,使用逗号分隔
- 授权时, 数据库名和表名可以使用 * 进行通配,代表所有。
五、函数
5-1、字符串函数
5-2、数值函数
- mod 就是 x 除以 y 的余数
5-3、日期函数
5-4、流程函数
六、约束
6-1、表的数据写入约束
注意: 约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束。
6-2、外键约束(即数据关联的完整性保证)
- 添加外键:
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表 (主表列名) ; - 删除外键:
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称; - 删除/更新行为约束:
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 主表名 (主表字段名) ON UPDATE CASCADE ON DELETE CASCADE;
七、多表查询
7-1、多表查询基本语法
- 查询多张表,用 , 分隔即可: select * from emp , dept;
- 查询多表之间关联数据: select * from emp , dept where emp.dept_id = dept.id;
7-2、内连接
- 隐式内连接 :
SELECT 字段列表 FROM 表1 , 表2 WHERE 条件 ... ;
select e.name,d.name from emp e , dept d where e.dept_id = d.id;
- 显式内连接 :
SELECT 字段列表 FROM 表1 [ INNER ] JOIN 表2 ON 连接条件 ... ;
select e.name, d.name from emp e join dept d on e.dept_id = d.id;
备注:表的别名简写
①. tablea as 别名1 , tableb as 别名2 ; (正常语法)
②. tablea 别名1 , tableb 别名2 ; (简写语法)
7-3、外连接
7-3-1、左外链接
语法: SELECT 字段列表 FROM 表1 LEFT [ OUTER ] JOIN 表2 ON 条件 ... ;
左外连接相当于查询表1(左表)的所有数据,当然也包含表1和表2交集部分的数据。
7-3-2、右外链接
语法: SELECT 字段列表 FROM 表1 RIGHT [ OUTER ] JOIN 表2 ON 条件 ... ;
右外连接相当于查询表2(右表)的所有数据,当然也包含表1和表2交集部分的数据。
7-4、自连接
语法: SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件 ... ;
select a.name , b.name from emp a , emp b where a.managerid = b.id;
注意事项: 在自连接查询中,必须要为表起别名,要不然我们不清楚所指定的条件、返回的字段,到底 是哪一张表的字段。
7-5、联合查询
SELECT 字段列表 FROM 表A ...
UNION [ ALL ]
SELECT 字段列表 FROM 表B ....;
- 对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
- union all 会将全部的数据直接合并在一起,union 会对合并之后的数据去重。
7-6、子查询
// 子查询外部的语句可以是INSERT / UPDATE / DELETE / SELECT 的任何一个。
语法: SELECT * FROM t1 WHERE column1 = ( SELECT column1 FROM t2 );
7-6-1、标量子查询
定义: 子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询称为标量子查询。 常用的操作符:= <> > >= < <= ;
select * from emp where dept_id = (select id from dept where name = '销售部');
7-6-2、列子查询
select * from emp where salary > all ( select salary from emp where dept_id =
(select id from dept where name = '财务部') );
-- 查询 比 财务部 所有人(all)工资都高的员工信息
7-6-3、行子查询
定义: 子查询返回的结果是一行(可以是多列),这种子查询称为行子查询。
select * from emp where (salary,managerid) = (select salary, managerid from emp
where name = '张无忌');
7-6-4、表子查询
定义: 子查询返回的结果是多行多列,这种子查询称为表子查询。
select * from emp where (job,salary) in ( select job, salary from emp where name =
'鹿杖客' or name = '宋远桥' );
八、事务
定义: 事务就是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系 统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
8-1、控制事务
8-1-1、方法一(不推荐使用)
- 查看/设置事务提交方式
SELECT @@autocommit ;
SET @@autocommit = 0 ; // 0 表示手动提交,1 表示自动提交
- 提交事务
COMMIT;
- 回滚事务
ROLLBACK;
8-1-2、方法二(推荐使用)
- 开启事务
START TRANSACTION 或 BEGIN ;
- 提交事务
COMMIT;
- 回滚事务
ROLLBACK;
8-2、事务的四大特性
- 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
- 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
- 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立 环境下运行。
- 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
8-3、并发事务问题
- 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
- 不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。
- 幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据 已经存在,好像出现了 "幻影"。
8-4、 事务隔离级别
- 查看事务隔离级别
SELECT @@TRANSACTION_ISOLATION;
- 设置事务隔离级别
SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
注意:事务隔离级别越高,数据越安全,但是性能越低