2020年6月 Mark
Tool: SQLyog OR Navicat
本文参考视频教程:“尚硅谷MySQL核心技术”,整理笔记如下。
本文主要目的快速地抓取MySQL基础的主要知识点,全文都是手打的,没有复制粘贴,记录可能有不恰当之处
其中,MyISAM不支持事务,需要设置数据库类型为InnoDB(支持事务控制)
MyISAM增删操作时,只有表锁,会锁住整个表格;而InnoDB可以采用行级锁。
前者以类似于数组方式存储数据,访问速度很快;后者InnoDB以B+树存储。
语法 --不区分大小写,’’、""通用,数据库索引从1开始。
# 语法执行顺序,实际where在select之前执行。
SELECT __查询列表
FROM __表1
JOIN __表2 ON __连接条件 # [INNER] LEFT RIGHT FULL CROSS [OUTER]
WHERE __筛选条件
GROUP BY __分组字段
HAVING __分组后的字段
ORDER BY __排序字段 # [DESC/ASC]
LIMIT __ ;
SELECT VERSION();
SELECT IFNULL(fieldName,0) AS 结果; //手动将NULL值视为0
SELECT 10*3; //30
SELECT CONCAT(field1,",",field2) AS cont;
支持!=,但是<>更加规范。(包容性)
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!
ORDER BY
`salary` [ASC|DESC];
LENGTH(`name`);
CONCAT LENHTH IFNULL
… 组函数/分组函数/统计函数/聚合函数
-- 中文: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('张公子爱上了周芷若','周芷若','赵敏');
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
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'); //相差天数
SELECT
VERSION();
USER();
DATABASE(); //SHOW databases;
PASSWORD("王世超"); # 密文形式
MD5();
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`;
… 组函数/分组函数/统计函数/聚合函数
SUM(salary);
AVG();
MIN();
MAX();
COUNT(Field); //统计非空数
COUNT(*); //统计行数 COUNT(1)
以上分组函数,都是忽略NULL值
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;
笛卡尔集错误,解决:通过添加连接条件
多个表的查询
<年代>
sql92
sql99 【推荐使用】
<类型>
连接的两种写法,
一种是 FROM + , + WHERE (sql92写法)
一种是 FROM + JOIN + ON
HAVING
或称,外查询
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 工资;
LIMIT offset, size; # 这里的索引从0开始。其他的是从1开始。
LIMIT (page-1)*size, size; # 分页查询
SELECT
UNION # UNION ALL 可包含重复项目
SELECT
DQL 语言 ENDING
INSERT
UPDATA
DELETE
# 方式一 支持插入多行、支持子查询
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';
单表、多表修改
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='张无忌';
单表、多表删除(行)
# 单表删除(行)
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支持回滚。
综合案例
增删改
库、表管理
CREATE
ALTER
DROP
创建、修改、删除
CREATE DATABASE IF NOT EXISTS myDB;
# RENAME DATABASE myDB TO newtable; # 不建议,容易引发数据丢失
ALTER DATABASE myDB CHARACTER SET gbk;
DROP DATABASE IF EXISTS myDB;
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;
DESC mytable;
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;
事务控制语言
事务:一组sql语句构成一个执行单元,全执行或者全不执行。
支持回滚。 错误/中断时回滚。
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;
简化语句、提高重用性、安全性
mysql5.1新特性,虚拟表(动态生成的数据)
create view 视图名 as -- 视图
select ...; -- 查询语句
desc 视图名;
show create view 视图名;
视图,一般只能“查”,不能增删改,不占用物理空间。
不允许视图更新的情况
join 常量视图 用到了不可更新视图 where后子查询用到from表 – 详再查
系统变量
自定义用户变量
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 @name:='join';
select @name:='join';
select count(*) into @count from students;
begin
declare 变量名 类型 [default 值];
set 变量名:=值;
end
delimiter $
create procedure func()
begin
sql language;
end $
call func()$
drop procedure func; --删除过程
参数列表: IN name vat(10);
IN OUT INOUT
delimiter $ -- 定义结束符
create function 函数名(参数列表) returns 返回类型
begin
函数体
end
select 函数名(参数列表)
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