2020年6月 Mark
Tool: SQLyog OR Navicat
本文参考视频教程:“尚硅谷MySQL核心技术”,整理笔记如下。
本文主要目的快速地抓取MySQL基础的主要知识点,全文都是手打的,没有复制粘贴,记录可能有不恰当之处
文章目录
DQL 查询
DML 操作 增删改
DDL 定义
TCL 事务控制语言
其中,MyISAM不支持事务,需要设置数据库类型为InnoDB(支持事务控制)
MyISAM增删操作时,只有表锁,会锁住整个表格;而InnoDB可以采用行级锁。
前者以类似于数组方式存储数据,访问速度很快;后者InnoDB以B+树存储。
DQL 查询篇 (一)
语法 --不区分大小写,’’、""通用,数据库索引从1开始。
$.语句顺序
# 语法执行顺序,实际where在select之前执行。
SELECT __查询列表
FROM __表1
JOIN __表2 ON __连接条件 # [INNER] LEFT RIGHT FULL CROSS [OUTER]
WHERE __筛选条件
GROUP BY __分组字段
HAVING __分组后的字段
ORDER BY __排序字段 # [DESC/ASC]
LIMIT __ ;
1.基础查询 SELECT
SELECT VERSION();
SELECT IFNULL(fieldName,0) AS 结果; //手动将NULL值视为0
SELECT 10*3; //30
SELECT CONCAT(field1,",",field2) AS cont;
支持!=,但是<>更加规范。(包容性)
2.条件查询 WHERE
BETWEEN AND, IN --提高语句的简洁度
SELECT DISTINCT * from table; # 去重
WHERE `name` like '__n_l%'; # 单字符 多字符 # 通配符
WHERE `name` like '_$%' ESCAPE '$'; # 转义 \_ \$
WHERE `id` BETWEEN 10 AND 20; # 闭区间 [10,20] 相当于>= <=
WHERE `job` IN ('A','B','C'); # 相当于 "="
IS NULL; IS NOT NULL; =200; 安全等于 <=>
and&& or|| not!
3.排序查询 ORDER BY
ORDER BY
`salary` [ASC|DESC];
LENGTH(`name`);
函数篇:单行函数
CONCAT LENHTH IFNULL
… 组函数/分组函数/统计函数/聚合函数
1.字符函数 CONCAT SUBSTR
-- 中文:utf8三字节 gbk二字节
SELECT
LENGTH('john');
UPPER('john');
CONCAT('VON','_','JOHN');
SUBSTR('李莫愁爱上了陆展元',7); # 数据库索引,从1开始
SUBSTR('李莫愁爱上了陆展元',1,3);
INSTR('杨不悔爱上了殷六侠', '不') AS output; # 返回索引2
TRIM(" 123 "); #123
TRIM("a" FROM "aaaa123aaaaaa"); #123
LPAD('印刷术',5,'*'); # **印刷术 RPAD
REPLACE('张公子爱上了周芷若','周芷若','赵敏');
2.数学函数 ROUND
SELECT
ROUND(1.657, 2); # 1.66 # 四舍五入不管正负号
CEIL(1.02); # 2
FLOOR(9.99); # 9
TRUNCATE(1.699,1); # 1.6
MOD(10,-3); # 1 (取决于被除数) # MOD(a,b)和JAVA一样 # 内部计算式:a - a/b*b
MOD(a,b)和JAVA一样 # 内部计算式:a - a/b*b
3.日期函数 NOW
SELECT
NOW();
CURDATE(); //2020-6-26
CURTIME(); //10:46:56
YEAR(NOW()); //2020 MONTH MONTHNAME DAY HOUR MINIUTE SECOND
//- STR_TO_DATE('2020-06-26','%Y-%m-%d') AS out;
//- STR_TO_DATE('4-3 2020', '%c%d %Y');
//- DATE_FORMAT(NOW(), '%Y日%m月%d日');
DATEDIFF(NOW(), '1995-1-1'); //相差天数
4.其他函数(简单) VERSION
SELECT
VERSION();
USER();
DATABASE(); //SHOW databases;
PASSWORD("王世超"); # 密文形式
MD5();
函数篇:进阶、分组函数
1.流程控制 IF CASE
IF(10>5, '大','小');
IF(pct IS NULLA, '没奖金','有奖金') AS 备注;
//嵌入select [] from的中间
CASE [字段名/变量/表达式]
WHEN [常量/条件表达式] THEN …
ELSE 值N
END AS new_id
SELECT borndate,
CASE
WHEN SUBSTR(borndate, 1, 4) BETWEEN 1988 AND 1992
THEN SUBSTR(borndate, 1, 4)
# ELSE 值N
END AS year_
FROM `beauty`;
2.分组函数 SUM COUNT
… 组函数/分组函数/统计函数/聚合函数
SUM(salary);
AVG();
MIN();
MAX();
COUNT(Field); //统计非空数
COUNT(*); //统计行数 COUNT(1)
以上分组函数,都是忽略NULL值
3.分组查询 GROUP BY HAVING
WHERE + HAVING
# 分组算平均
SELECT AVG(salary), job_id
FROM employees
GROUP BY job_id;
# 二次查询
SELECT COUNT(*), job_id
FROM employees
GROUP BY job_id # 按组COUNT(*)
HAVAING COUNT(*)>2;
多表查询
1.多表查询/连接查询
笛卡尔集错误,解决:通过添加连接条件
多个表的查询
<年代>
sql92
sql99 【推荐使用】
<类型>
- 内连接
- 等值连接
- 非等值连接
- 自连接 (INNER) JOIN
- 外连接
- 左外连接 LEFT JOIN
- 右外 RIGHT JOIN
- 全外 FULL JOIN
- == 内+左外+右外
- 交叉连接 CROSS JOIN
- 类似于笛卡尔乘积
连接的两种写法,
一种是 FROM + , + WHERE (sql92写法)
一种是 FROM + JOIN + ON
HAVING
2.子查询 (SELECT)
或称,外查询
IN
ANY / SOME
ALL
EXISTS
# 查询员工的员工号、姓名、工资,这些员工的工资大于部门平均工资
select E.employee_id, E.last_name 姓氏, E.salary 工资, E.department_id
from employees E
join (
select round(avg(salary),2) ags, department_id
from employees
group by department_id
) P
on E.department_id = P.department_id
where salary > ags
order by 工资;
3.分页查询 LIMIT
LIMIT offset, size; # 这里的索引从0开始。其他的是从1开始。
LIMIT (page-1)*size, size; # 分页查询
4.联合查询 UNION
SELECT
UNION # UNION ALL 可包含重复项目
SELECT
- 适用场景
- 对多个表进行查询
- 多表的查询列数要一致、顺序最好一致
- 默认去重 # UNION ALL 可以取消去重
DQL 语言 ENDING
DML 操作篇 (二)
INSERT
UPDATA
DELETE
1.增加 INSERT
# 方式一 支持插入多行、支持子查询
INSERT INTO table(id,name,sex,date,photo)
VALUES(12,'Mike','man','1996-6-9',NULL),
VALUES(13,'Mike2','female','1997-6-9',NULL);
INSERT INTO table(id,name,sex)
SELECT id,name,"man"
FROM boys WHERE id<3;
-- SELECT UNION SELECT;
# 方式二
INSERT INTO beauty
SET id=19, NAME='Jack';
2.修改 UPDATE
单表、多表修改
UPDATE table0
SET
WHERE
# 多表修改
UPDATE boys bo # 修改张无忌女友的手机号为144
INNER JOIN beauty b
ON bo.id = b.boyfriend_id
SET b.phone = '144'
WHERE bo.boyName='张无忌';
3.删除 DELETE/TRUNCATE
单表、多表删除(行)
# 单表删除(行)
DELETE FROM beauty # 删除尾号为9的电话号码
WHERE phone LIKE "%9";
# 多表
DELETE b # 删除b表中张无忌的女朋友信息
FROM beauty b
JOIN boys bo
ON b.boyfriend_id = bo.id
WHERE b.boyName = "张无忌";
# 整表删除,不能加WHERE
TRUNCATE TABEL boys;
区别5:TRUNCATE删除后,自增长列增加数据时从0开始。
DELETE有返回值。
DELETE支持回滚。
综合案例
增删改
DDL 定义篇 (三)
库、表管理
CREATE
ALTER
DROP
1.库的管理
创建、修改、删除
CREATE DATABASE IF NOT EXISTS myDB;
# RENAME DATABASE myDB TO newtable; # 不建议,容易引发数据丢失
ALTER DATABASE myDB CHARACTER SET gbk;
DROP DATABASE IF EXISTS myDB;
2. 表的管理
CREATE TABLE mytable(
id INT, # 编号
name VARCHAR(20),
price DOUBLE
);
ALTER TABLE mytable
操作 COLUMN 列名 【列类型 约束】
# 删除
DESC mytable;
DROP TABLE IF EXISTS mytable;
SHOW TABLES;
# 复制
CREATE TABLE copyTable1 LIKE mytable;
CREATE TABLE copyTable2
SELECT * FROM mytable
WHERE id<10;
- 修改 COLUMN
- 列名 CHANGE
- 列的类型、约束 MODIFY
- 新列 ADD
- 删除列 DROP
- 表名 RENAME TO
DESC mytable;
3.数据类型
- 数值型
- 整型
- 定点数 Decimal (精度较高)
- 浮点数 Float、Double
- 字符型
- char、varchar
- binary、varbinary
- Enum(‘a’,‘b’,‘c’)、Set(‘a’,‘b’,‘c’,‘d’) # 建表字段类型
- TEXT、blob(较长的二进制)
- 日期型
- DATETIME
- TIMESTAMP
4.常见约束
- 约束
NOT NULL
DEFAULT
PRIMARY KEY 主键,不可重复、非空
UNIQUE
CHECK 检查,mysql不支持
FORING KEY 限制两个表的关系,从表中添加限制
- 场景
创建表
修改表
CREATE TABLE tablename(
字段名 字段类型 列级约束,
字段名 字段类型,
表级约束
)
表级约束
CONSTRAINT PRIMARY KEY(ID), # 主键
主键 V.S. 唯一键
- 标识列
自增长列
TRUNCATE TABLE tablename;
CREATE TABLE tablename(id INT PRIMARY KEY AUTO_INCREAMENT);
- 外键:删除主表的记录
级联删除:
alter table tab1 add constaint f1 foreign key(id) references major(id) on delete cascade;
级联置空:
alter table tab1 add constaint f1 foreign key(id) references major(id) on delete set null;
TCL 事务篇 (四)
事务控制语言
事务:一组sql语句构成一个执行单元,全执行或者全不执行。
支持回滚。 错误/中断时回滚。
事务控制语言
- 事务的ACID属性
atomicity 原子性 一个事务不可再分割
consistency 一致性 一致状态到一致状态
isolation 隔离性 事务互不干扰,需要设置隔离级别
durability 持久性 提交后,永久地持久化到本地
- 事务的创建
隐式 insert update delete
显式 有明显的开始和结束
-
set autocommit=0; start transaction;
-
select insert update delete 等事务语句
– savepoint a; 设置回滚点 -
commit;
– rollback to a; 回滚事务
e.g.
~~
- 并发事务/问题
脏读 读取了还没提交的数据 “更新”
不可重复读 多次读取,结果不一样
幻读 插入的前后读 “插入”
- 事务的隔离级别
– isolation level
read uncommited 读未提交
read commited oracle默认 读已提交
repeatable read mysql默认 可重复读 //不能解决幻读问题
serializable 串行化 //无并发问题,但是效率低
select @@tx_isolation;
set transaction isolation level read commited;
—
9.视图
简化语句、提高重用性、安全性
- 视图
mysql5.1新特性,虚拟表(动态生成的数据)
create view 视图名 as -- 视图
select ...; -- 查询语句
desc 视图名;
show create view 视图名;
视图,一般只能“查”,不能增删改,不占用物理空间。
不允许视图更新的情况
join 常量视图 用到了不可更新视图 where后子查询用到from表 – 详再查
10.变量
系统变量
自定义用户变量
- 系统变量/会话
show global variables;
show global variables like '%char%';
select @@global.系统变量名=值;
set @@global.autocommit=0;
show variables; //session可不加
select @@tx_isolation;
set @@session.tx_isolation='read-uncommited';
- 自定义变量 (不用限定类型) set
当前会话有效
set @name:='join';
select @name:='join';
select count(*) into @count from students;
- 局部变量 (需要限定类型)
begin
declare 变量名 类型 [default 值];
set 变量名:=值;
end
11.存储过程和函数
- 存储过程
delimiter $
create procedure func()
begin
sql language;
end $
call func()$
drop procedure func; --删除过程
参数列表: IN name vat(10);
IN OUT INOUT
<set name gbk;>
- 函数
delimiter $ -- 定义结束符 <todo>
create function 函数名(参数列表) returns 返回类型
begin
函数体
end
select 函数名(参数列表)
12.流程控制结构
- 条件语句
delimiter $ -- 定义结束符 默认是;分号
begin
case
when 条件1 then select 语句;
when 条件2 then select 语句2;
else select 语句3;
end case;
end $
delimiter $ -
begin
if 条件1 then 语句1;
elseif 条件2 then 语句2;
else 语句n;
end if;
end $
- 循环结构
while loop repeat
iterate leave -- 相当于 continue break
<while>
while 循环条件 do
循环体
end while 标签;
loop / end loop -- 没有条件的死循环
repeat / until / end repeat
end 2020-7-22