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
<set name gbk;>
delimiter $ -- 定義結束符 <todo>
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