基本
一、常見概念
- DD:資料庫,存盤資料的容器
- DBMS:資料庫管理系統,又稱為資料庫軟體或資料庫產品,用于創建或管理 DB
- SQL:結構化查詢語言,用于和資料庫通信的語言
二、MySQL語法規范
- 不區分大小寫,簡答關鍵字大寫
- 每條命令最好用分號結尾
- 每條命令根據需要,可以縮進或者換行
- 注釋格式
單行注釋:#注釋文字
單行注釋:--注釋文字
多行注釋:/*注釋文字*/
三、服務啟動/登錄
- MySQL服務啟動與停止
啟動服務:net start 服務名
停止服務:net stop 服務名
- 服務的登錄和退出
退出:exit
登錄:mysql [-h 主機名 -p埠號] -u 用戶名 -p密碼
/*埠號與p之間無空格*/
四、常見命令
SHOW DATABASES; # 查看所有資料庫
USE 庫名 # 打開指定庫
SHOW TABLES; # 查看當前庫所有表
SHOW TABLES FROM 庫名; # 查看指定庫所有表
DESC 表名; # 查看表結構
SELECT VERSION(); # 查看服務器版本
SHOW ENGINES; # 查看存盤引擎
SELECT @@tx_isolation; # 查看隔離界別(8.0之前)
SELECT @@transaction_isolation; # 隔離級別(8.0之后)
SHOW CREATE TABLE 表名 # 查看表創建程序
SHOW CREATE VIEW 視圖名 # 查看視圖創建程序
SHOW PROCEDURE 存盤程序名 # 查看存盤程序創建程序
DQL語言
含義:資料查詢語言 Data Query Language
一、基礎查詢
-
SELECT
特點
- 查詢串列可以是:欄位、常量值、運算式、函式
- 查詢結果是一個虛擬表格
- 查詢欄位
SELECT 欄位 FROM 表; # 查詢單個欄位
SELECT 欄位1, 欄位2 FROM 表; # 查詢多個欄位
SELECT * FROM 表; # 查詢所有欄位
/* 注:`XX`(著重號,非單引號)代表XX為欄位名 */
- 查詢常量值、運算式、函式
SELECT 常量值/運算式/函式;
/* 例子 */
SELECT 100;
SELECT 100%3;
SELECT VERSION();
- 起別名
(1) 便于理解
(2) 查詢欄位若有重名可以用別名區分
SELECT 欄位 AS 別名 FROM 表; # 用AS
SELECT 欄位 別名 FROM 表; # 用空格
/* 注:別名含有特殊符號或關鍵字時,添加雙引號或單引號 */
- 結果去重
欄位前加 DISTINCT 即可結果去重
SELECT DISTINCT 欄位 FROM 表;
- +號作用
(1) 兩個運算元都為數值型做加法運算
(2) 其中一個為 NULL 則結果為 NULL
(3) 其中一個為字符型,則視圖轉換為數值型
SELECT '12'+1; # 轉換成功做加法運算
SELECT 'A'+1; # 轉換失敗,將字符型轉換成0
二、條件查詢
- WHERE 語法
SELECT 查詢串列 FORM 表 WHERE 篩選條件
- 分類
-
按條件運算式篩選
條件運算子:> < = != <> >= <= -
按運算式篩選
邏輯運算子:&& || ! and or not -
模糊查詢
LIKE
/*
一般搭配通配符使用,前面可加NOT
通配符:
% 代表任意多個字符(包括0個)
- 代表任意單個字符
注:若查詢名字中包含通配符的欄位需要用 \ 轉義
ESCAPE可自定義轉義字符
*/
BETWEEN AND
/* BETWEEN A AND B 包含 A 和 B */
IN
/* IN(值1, 值2, ...) 串列的值必須一致或兼容 */
IS NULL/IS NOT NULL
/* = 和 <> 不能用于判斷NULL值,需要用IS NULL/IS NOT NULL */
/* 注:<=> 為安全等于,可以判斷NULL和普通數值 */
三、排序查詢
- ORDER BY 語法
SELECT 欄位 FROM 表 [WHERE 條件]
ORDER BY 排序串列 ASC|DESC
/* ASC 升序 DESC 降序 不寫默認升序 */
- 特點
- 排序串列可以是運算式或函式
- 排序串列可設定多個,按串列先后順序排序
- 排序串列可寫別名
- ODER BY 陳述句在其他陳述句后面 LIMIT 陳述句前面
四、常見函式
- 字符函式
| 函式 | 用法及作用 |
|---|---|
| LENGTH() | 獲取引數的位元組個數 |
| CONCAT() | 拼接字串 |
| UPPER() LOWER() |
UPPER() 將引數轉為大寫 LOWER() 將引數轉為小寫 |
| SUBSTR() SUBSTRING() |
SUBSTR(str, pos) 截取 pos 以及之后的所有字符 SUBSTR(str, pos, len) 截取 pos 處開始長度為 len 的字符 |
| INSTR() | INSERT(str, substr) 回傳 substr 在 str 中第一次的索引,若無索引回傳0 |
| TRIM() | TRIM(str) 去掉 str 兩端空格 TRIM(str1 FROM str2) 去掉 str2 兩端的 str1 字符 |
| LPAD() RPAD() |
LPAD / RPAD(str, len, padstr) 在 str 左端/右端填充 padstr 字符,直到 str 長度變為 len,若 str 本身超過 len 長度,則從左往右截取長度為 len 的字串 |
| REPLACE() | REPLACE(str, from_str, to_str) 將 str 中所有 from_str 替換為 to_str |
- 數學函式
| 函式 | 用法及作用 |
|---|---|
| ROUND() | ROUND(X) 四舍五入 ROUND(X, D) X保留D位小數 |
| CELL() | CELL(X) 回傳大于等于X的最小整數(向上取整) |
| FLOOR() | FLOOR(X) 回傳小于等于X的最大整數(向下取整) |
| MOD() | MOD(m, n) 取余 m%n |
- 日期函式
| 函式 | 用法及作用 |
|---|---|
| NOW() | 回傳當前系統日期+時間 |
| CURDATE() | 回傳當前系統日期 |
| CURTIME() | 回傳當前系統時間 |
| YEAR() MONTH() DAY() HOUR() MINUTE() SECOND() |
YEAR(NOW()) YEAR('2020-1-1') 回傳年/月/日/時/分/秒 MONTHNAME() 回傳月的英文 |
| STR_TO_DATE() | STR_TO_DATE(str, format) 將指定日期格式的字符轉換標準格式 STR_TO_DATE('1-1-2020', '%m-%d-%Y'); |
| DATEDIFF() | DATEDIFF(startdate, enddate) 回傳兩個日期之間相差天數 如:DATEDIFF('2008-12-29', '2008-12-30')結果為-1 |
| 格式符 | 功能 |
|---|---|
| %Y | 四位年份 |
| %y | 2位年份 |
| %m | 月份(01, 02 ... 11, 12) |
| %c | 月份(1, 2, ... 11, 12) |
| %d | 日(01, 02, ...) |
| %H | 小時(24小時制) |
| %h | 小時(12小時制) |
| %i | 分鐘(00, 01 ... 59) |
| %s | 秒(00, 01, ... 59) |
- 其他函式
| 函式 | 用法及作用 |
|---|---|
| VERSION() | 回傳當前版本 |
| USER() | 回傳當前用戶 |
| ISNULL() | IFNULL(XXX, 值) 判斷欄位或運算式是否為NULL,若為NULL回傳指定值,否則回傳原本值 |
| ISNULL() | 判斷欄位或運算式是否為NULL,NULL回傳1,否則回傳0 |
五、分組函式
- 分組函式(統計函式)
| 函式 | 用法及作用 |
|---|---|
| SUM() | 求和 |
| AVG() | 平均值 |
| MAX() | 最大值 |
| MIN() | 最小值 |
| COUNT() | 計算非空值個數 COUNT(*)/COUNT(任意常量) 統計行數 效率: MYSISAM 存盤引擎,COUNT(*)的效率高 INNODB存盤引擎,COUNT(*)和COUNT(1)基本相同,但比COUNT(欄位)效率高 |
六、分組查詢
- GROUP BY 語法
SELECT 查詢串列 FROM 表
GROUP BY 分組串列
[HAVING 篩選條件]
/* HAVING 可用于分組后資料篩選 */
- 特點
-
分組前篩選用 WHERE 放 GROUP BY 前面
分組后篩選用 HAVING 放 GROUP BY 后面 -
支持單個欄位分組,多個欄位分組(逗號隔開),運算式分組
七、連接查詢
-
連接查詢又稱多表查詢
-
笛卡爾乘積現象:表1 m 行 表2 n 行,結果 m*n 行
發生原因:沒有有效的連接條件 -
連接查詢分類
按年代分類 按功能分類 sql92 標準:內連接 內連接:
等值連接
非等值連接
自連接sql99 標準:
MySQL支持 內連接、外連接(左外 右外)、交叉連接外連接:
左外連接
右外連接
全外連接交叉連接(笛卡爾積)
SQL92 標準
- 等值連接
- 特點
(1) 多表等值連接結果為多表的交集部分
(2) n表連接至少需要n-1個連接條件
(3) 一般需要為表起別名
(4) 可以使用篩選、排序、分組等
(5) 多表順序無要求
案例:查詢員工名、工種號、工種名
SELECT e.job_id, j.job_id, j.job_title
FROM employees e, jobs j
WHERE e.job_id = j.job_id;
- 非等值連接
案例:查詢員工的工資和工資級別
SELECT salary, grade_level
FROM employees e, job_grades g
WHERE salary BETWEEN g.lowest AND g.highest;
- 自連接
- 特點:一張表當作多張表使用(用別名)
案例:查詢員工及其領導名字
SELECT e.name 員工, m.name 領導
FROM employees e, employees m
WHERE e.`manager_id` IS NOT NULL
AND e.`manager_id` = m.`employee_id`
SQL99 標準
- SQL99 語法
SELECT 查詢串列
FROM 表1 別名 [連接型別]
JOIN 表2 別名
ON 連接條件
[WHERE 篩選條件]
- 連接型別
| 分類 | 連接型別 |
|---|---|
| 內連接 | INNER |
| 外連接 | 左外:LEFT [OUTER] 右外:RIGHT [OUTER] 全外:FULL [OUTER] |
| 交叉連接 | CROSS |
- 內連接
- 特點:
(1) INNER 可以省略
(2) JOIN 連接和 SQL92 標準中連接效果一樣
(3) 連接條件放 ON 后面
(4) 除連接寫法不同外,其他同 SQL92
案例:查詢員工及其領導名字(自連接)
SELECT e.name 員工, m.name 領導
FROM employees e, employees m
WHERE e.`manager_id` IS NOT NULL
AND e.`manager_id` = m.`employee_id`
- 外連接
應用場景:查詢一個表中有,另一個表中無的記錄(相對補集)
- 特點:
(1) 外連接分主從表
(2) 外連接的查詢結果為主表的所有記錄
若從表中有與主表相匹配的,則顯示匹配值,否則顯示NULL
(3) 左外連接:LEFT JOIN 左邊為主表
右外連接:RIGHT JOIN 右邊為主表
- 交叉連接
查詢結果即笛卡爾乘積
八、子查詢
-
含義
出現在其他陳述句中的 SELECT 陳述句,稱為子查詢或內查詢
外部的查詢陳述句,稱為主查詢或外查詢 -
分類
按結果集的行列數
| 分類 | 結果集 |
|---|---|
| 標量子查詢 | 一行一列 |
| 列子查詢 | 一行多列 |
| 行子查詢 | 一行多列 |
| 表子查詢 | 多行多列 |
按子查詢出現位置
| 出現位置 | 支持型別 |
|---|---|
| SELECT 后面 | 標量子查詢 |
| FROM 后面 | 表子查詢 |
| WHERE 或 HAVING 后面 | 標量子查詢(單行) 列子查詢(多行) |
| EXISTS 后面(相關子查詢) | 表子查詢 |
- 子查詢優先于主查詢
- 子查詢放在小括號內
- 子查詢一般放在條件的右側
- 標量子查詢,一般搭配單行運算子使用 > < = 等
- 列子查詢,一般搭配多行運算子使用 IN ANY/SOME ALL
| 多行比較運算子 | 作用 |
|---|---|
| IN / NOT IN | 等于(不等于)串列中的任意一個值 |
| ANY / SOME | 和子查詢回傳的某一個值比較 |
| ALL | 和子查詢回傳的所有值比較 |
- WHERE 或 HAVING 后面
- 標量子查詢(單行子查詢)
案例:查詢比 Abel 工資高的員工
SELECT * FROM employees
WHERE salary > (
SELECT salary
FROM employees
WHERE last_name='Abel'
);
- 列子查詢(多行子查詢)
案例:回傳 location_id 為1400或1700的部門的員工
SELECT name FROM employees
WHERE department_id IN (
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400, 1700)
);
- 行子查詢(多列子查詢)
案例:查詢 id 最小且工資最高的員工
SELECT * FROM employees
WHERE (employee_id, salary) = (
SELECT MIN(employee_id), MAX(salary)
FROM employees
);
- SELECT 后面
- 標量子查詢
案例:查詢每個部門資訊及其員工個數
SELECT d.*, (
SELECT COUNT(*)
FROM employees e
WHERE e.department_id = d.department_id
)
FROM departments d;
- FROM 后面
- 表子查詢:將查詢結果作為一張表,必須起別名
案例:查詢每個部門平均工資的工資等級
SELECT ag_dep.*, g.grade_level
FROM (
SELECT AVG(salary) ag, department_id
FROM employees
GROUP BY department_id
) ag_dep # 此處必須為表起別名
INNER JOIN job_grades g
ON ag_dep.ag BETWEEN g.lowest AND g.highest;
- EXISTS 后面
- 結果不為空 回傳 1 結果為空 回傳 0
案例:查詢有員工的部門
SELECT department_name
FROM departments d
WHERE EXISTS(
SELECT *
FROM employees e
WHERE d.department_id = e.department_id
);
/* 注:EXISTS 通常可用 IN 替代 */
九、分頁查詢
應用場景:當顯示資料一頁顯示不全,需要分頁提交sql請求
- LIMIT 語法
SELECT 查詢串列 FROM 表
...
LIMIT offset, size;
/* 注:offset: 起始索引(從0開始) size: 每頁條目數 */
- 特點
- LIMIT 陳述句放在所有陳述句的后面
- 要顯示的頁數 page,每頁條目數 size
offset = (page-1)*size
十、聯合查詢
應用場景:查詢結果來自多個表,查詢資訊一致
- UNION 語法
查詢陳述句1
UNION
查詢陳述句2
UNION
...
/* 默認去重,使用 UNION ALL 顯示重復項 */
- 特點
- 要求查詢陳述句結果列數一致
- 要求查詢陳述句的每一列型別和順序一致
- UNION 默認去重,使用 UNION ALL 可包含重復項
DML 語言
含義:資料操作語言 Data Manipularion Language
一、插入陳述句
- INSERT 語法
語法一:
INSERT INTO 表[(欄位1, ...)] VALUES(值1, ...);
(1) 插入的值型別與欄位的型別一致或兼容
(2) 不可為NULL的列必須插入值
(3) 列的順序可以調換
(4) 列數和值數必須一致
(5) 可以省略欄位,默認為所有列,欄位順序和表中順序一致
語法二:
INSERT INTO 表 SET 欄位1 = 值1, …, 欄位n = 值n;
兩種方式對比:
- 語法一支持多行插入,語法二不支持
VALUES(...), (...), (...) - 語法一支持子查詢,可插入查詢結果,語法二不支持
INSERT INTO 表(欄位, ...) SELECT ...;
二、修改陳述句
- 修改單表記錄
UPDATE 表 SET 欄位1 = 新值, 欄位2 = 新值, ...
[WHERE 篩選條件]
- 修改多表記錄
/* SQL99 */
UPDATE 表1 別名
連接型別 JOIN 表2 別名
ON 連接條件
SET 欄位 = 新值, ...
[WHERE 篩選條件]
三、洗掉陳述句
- DELETE 語法
DELETE FROM 表 [WHERE 篩選條件]
/* 多表洗掉類似于 UPDATE */
- TRUNCATE 語法
TRUNCATE TABLE 表; # 清空表中資料
- DELETE 與 TRUNCATE 對比
- DELETE 可以加 WHERE 條件,TRUNCATE 不能加
- TRUNCATE 洗掉效率略高于 DELETE
- 若要洗掉的表中有自增長列,DELETE 洗掉后再插入資料,自增長列的值從斷點開始;TRUNCATE 洗掉后,再插入資料,自增長從1開始
- DELETE 有回傳值(有幾行受影響),TRUNCATE 無回傳值
- DELETE 洗掉在事務中能回滾,TRUNCATE 洗掉不能回滾
DDL 語言
含義:資料定義語言 Data Definition Language
一、庫的管理
- 庫的創建
CREATE DATABASE 庫;
CREATE DATABASE IF NOT EXISTS 庫; # 防止重復創建報錯
- 庫的修改
/* 一般庫不進行修改 */
ALTER DATABASE 庫 CHARACTER SET 字符集; # 修改字符集
- 庫的洗掉
DROP DATABASE 庫;
DROP DATABASE IF EXISTS 庫; # 防止不存在時洗掉報錯
二、表的管理
- 表的創建
CREATE TABLE 表(
欄位 欄位型別 [長度 約束],
…
);
- 表的修改
/* 修改表名 */
ALTER TABLE 表 RENAME TO 新表名;
/* 修改欄位名 (COLUMN 可以省略,同時可更改欄位型別)*/
ALTER TABLE 表 CHANGE COLUMN 欄位 新欄位 欄位型別;
/* 修改欄位名 */
ALTER TABLE 表 MODIFY COLUMN 欄位 新型別 [約束];
/* 添加欄位 */
ALTER TABLE 表 ADD COLUMN 欄位 型別;
/* 洗掉欄位 */
ALTER TABLE 表 DROP COLUMN 欄位;
- 表的洗掉
/* 表的洗掉 */
DROP TABLE 表;
DROP TABLE IF EXISTS 表;
- 表的復制
/* 復制表的結構 */
CREATE TABLE 表 LIKE 復制的表;
/* 復制表的部分結構 */
CREATE TABLE 表
SELECT 欄位1, 欄位2, …
FROM 復制的表
WHERE 不成立的條件(如0)
/* 復制表的結構和資料 */
CREATE TABLE 表
SELECT * # 可以復制全部或部分資料
FROM 復制的表
三、常見資料型別
- 數值型
整型
| 整數型別 | 位元組 | 范圍 |
|---|---|---|
| TINYINT | 1 | 有符號:-128~127 無符號:0~255 |
| SMALLINT | 2 | 有符號:-32768~32767 無符號:0~65535 |
| MEDIUMINT | 3 | 有符號:-8388608~8388607 無符號:0~1677215 |
| INT / INTEGER | 4 | 有符號:-8388608~8388607 無符號:0~1677215 |
| BIGINT | 8 | 很大 |
- 特點:
(1) 型別后加 UNSIGNED 可設定為無符號
(2) 若不設定長度,則使用默認長度
(3) 長度代表顯示的最大寬度,若不夠使用0左填充,使用 ZEROFILL 可以顯示填充的0(使用了 ZEROFILL 會變為無符號)
小數
| 浮點數型別 | 位元組 | 范圍 |
|---|---|---|
| FLOAT(M, D) | 4 | 很大 |
| DOUBLE(M, D) | 8 | 很大 精度比 FLOAT 高 |
| 浮點數型別 | 位元組 | 范圍 |
|---|---|---|
| DEC(M, D) DECIMAL(M,D) |
M+2 | 最大取值范圍同 DOUBLE,有效取值范圍由M和D決定 |
- 特點:
(1) M:整數位數+小數位數 D:小數位數
(2) (M, D) 可省略, DECIMAL 的 M 默認為10,D 默認為0
(3) 定點型精確度較高,插入資料精度要求高則優先定點型
- 字符型
較短字串
| 字串型別 | 最多位元組數 | 描述及存盤需求 |
|---|---|---|
| CHAR(M) | M | M 為0~255之間整數 |
| VARCHAR(M) | M | M為0~65535之間整數 |
-
特點:
(1) M 代表最大字符數(非位元組數)
(2) CHAR 為固定長度字串 效率高,VARCHAR 可變長度字串 效率低
(3) CHAR 的 M 可省略,默認為1,VARCHAR 的 M 不可省略 -
其他:
(1) TEXT 用于較長文本
(2) BLOB 用于較大二進制(如圖片)
(3) BINARY 和 VARBINARY 用于較短二進制
(4) ENUM 用于保存列舉
(5) SET 用于保存集合
- 日期型
| 日期和時間型別 | 位元組 | 范圍 |
|---|---|---|
| DATE | 4 | |
| DATETIME | 8 | |
| TIMESTAMP | 4 | 19700101080001-2038年某個時間 |
| TIME | 3 | |
| YEAR | 1 |
- 特點:
TIMESTAMP 和實際時區有關,更能反應實際的日期,DATETIME 則只能反應出插入時的當地時區,TIMESTAMP 受MySQL 版本和 SQLMode 的影響很大
四、常見約束
約束:一種限制,用于限制表中的資料,為了保證表中資料的準確性和可靠性
- 約束分類
| 約束 | 作用 |
|---|---|
| NOT NULL | 非空,該欄位不能為空 |
| DEFAULT | 默認,該欄位值有默認值 |
| PRIMARY KEY | 主鍵,該欄位值有唯一性且非空 |
| FOREIGN KEY | 外鍵,用于限制兩個表的關系,用于保證該欄位的值必須來自主表的關聯列的值 |
| UNIQUE | 唯一鍵,該欄位值有唯一性,可為空 |
| CHECK | 檢查,mysql 不支持 |
-
外鍵
(1) 要求在從表上設定外鍵
(2) 主表的關聯列必須是一個key(主鍵或唯一)
(3) 插入資料時,先插入主表再插入從表,洗掉時先洗掉從表再洗掉主表 -
主鍵與唯一鍵
| 唯一性 | 是否允許為空 | 一個表中數量 | |
|---|---|---|---|
| 主鍵 | √ | 否 | 至多1個 |
| 唯一鍵 | √ | 是 | 可以多個 |
- 標識列
- 又稱為又稱為自增長列,可以不用手動插入值,系統提供默認的序列值
設定標識列:AUTO_INCREMENT
更改標識列步長:SET auto_increment_increment = 值
- 特點
(1) 標識列必須和Key一起使用
(2) 一個表中最多一個標識列
(3) 標識列的型別只能是數值型
(4) 可設定步長,手動插入值設定起始值
- 約束添加分類
列級約束
在創建或求改表時型別的后面添加,六個約束語法上都支持,但外鍵約束無效果
表級約束
在所有欄位最下面,非空和默認不支持表級約束
[CONSTRAINT 約束名] 約束型別(欄位);
/* 不設定約束名時默認為欄位名,主鍵設定約束名無效果 */
/* 添加外鍵 */
ALTER TABLE 從表 ADD CONSTRAINT 外鍵名
FOREIGN KEY(欄位) REFERENCES 主表(欄位);
CREATE TABLE 表名(
欄位名 欄位型別 列級約束,
欄位名 欄位型別 列級約束,
表級約束
);
- 約束的修改與洗掉
修改 / 添加
/* 列級約束 */
ALTER TABLE 表 MODIFY COLUMN 欄位 型別 約束;
/* 表級約束 */
ALTER TABLE 表 ADD [CONSTRAINT 約束名] 約束(欄位);
洗掉
/* 洗掉非空 */
ALTER TABLE 表 MODIFY COLUMN 欄位 型別 NULL;
/* 洗掉默認 */
ALTER TABLE 表 MODIFY COLUMN 欄位 型別;
/* 洗掉主鍵 */
ALTER TABLE 表 DROP PRIMARY KEY;
/* 洗掉唯一鍵 */
ALTER TABLE 表 DROP INDEX 欄位;
/* 洗掉外鍵 */
ALTER TABLE 表 DROP FOREIGN KEY 外鍵名;
- 級聯洗掉與置空
級聯洗掉:
在添加外鍵陳述句后添加ON DELETE CASCADE設定級聯洗掉
洗掉主表記錄的同時洗掉從表相關聯記錄
級聯置空:
在添加外鍵陳述句后添加ON DELETE SET NULL設定級聯置空
洗掉主表記錄的同時將從表相關聯記錄的值置為 NULL
TCL 語言
含義:事務控制語言 Transaction Control Language
一、事務
- 事務概念
- 事務:事務由單獨單元的一個或多個SQL陳述句組成,在這個單元中,每個MySQL陳述句是相互依賴的
- 存盤引擎
- 存盤引擎:mysql中用的最多的存盤引擎有:innodb, myisam, memory等,其中innodb支持事務,其他不支持
- 事務特性(ACID)
- 原子性(Atomicity):一個事務不可再分割,要么執行要么都不執行
- 一致性(Consistency):一個事務執行會使資料從一個一致狀態切換到另一個一致狀態
- 隔離性(Isolation):一個事務的執一個事務一旦提交,則會永久改變資料庫行不受到其他事務的干擾
- 持久性(Durability):一個事務一旦提交,則會永久改變資料庫
二、事務處理
- 事務創建
隱式事務
- 事務沒有明顯的開啟和結束的標記,自動提交 如:insert update delete陳述句
顯式事務
- 前提必須先設定自動提交功能為禁用
SET autocommit = 0
/* 步驟1:開啟事務 */
SET autocommit = 0;
START TRANSACTION; # 此陳述句可省略
/* 步驟2:撰寫事務中的 SQL 陳述句
如 SELECT INSERT UPDATE DELETE etc. */
/* 步驟3:結束事務(提交或回滾) */
COMMIT; # 提交事務
ROLLBACK; # 回滾事務
SAVEPOINT的使用:
事務中可設定保存點用于回滾
SAVEPOINT a; # 設定保存點 a
ROLLBACK TO a; # 回滾到保存點 a
- 并發問題
- 同時運行的多個事務,當這些事務訪問資料庫中相同的資料時,如果沒有采取必要的隔離機制,就會導致各種并發問題:
(1) 臟讀
(2) 不可重復讀
(3) 幻讀
- 事務隔離級別
| 隔離級別 | 描述 |
|---|---|
| READ UNCOMMMITTED (讀未提交資料) |
允許事務讀取違背其他事務提交的變更,臟讀、不可重復讀和幻讀問題都會出現 |
| READ COMMITED (讀已提交資料) |
只允許事務讀取已被其他事務提交的變更,可以避免臟讀,但不可重復讀和幻讀問題仍然可能出現 |
| REPEATABLE READ (可重復讀) |
確保事務可以多次從一個欄位中讀取相同的值,在這個事務持續期間,禁止其他事務對這個欄位進行更新,可以避免臟讀和不可重復讀,但幻讀問題仍然存在 |
| SERIALIZABLE (串行化) |
確保事務可以從一個表中讀取相同的行,在這個事務持續期間,禁止其他事務對該表執行插入、更新和洗掉操作,所有并發問題都可以避免,但性能十分低下 |
| 臟讀 | 不可重復讀 | 幻讀 | |
|---|---|---|---|
| READ UNCOMMITTED | √ | √ | √ |
| READ COMMITTED | × | √ | √ |
| REPEATABLE READ | × | × | √ |
| SERIALIZABLE | × | × | × |
設定當前 mysql 連接的隔離級別
SET TRANSACTION ISOLATION LEVEL 隔離級別;
設定資料庫系統的全域隔離級別
SET GLOBAL TRANSACTION ISOLATION LEVEL 隔離級別;
- 注意
(1) Mysql 默認的事務隔離級別為:REPEATABLE READ(可重復讀)
(2) 每啟動一個 mysql 程式,就會獲得一個單獨的資料庫連接,每個資料庫連接都有一個全域變數 @@transaction_isolation 表示當前的事務隔離級別
視圖
含義:虛擬表(只保存 sql 邏輯),和普通表一樣使用,mysql5.1 版本后的新特性,是通過表動態生成的資料
- 應用場景
(1) 多個地方用到同樣的查詢結果
(2) 該查詢結果使用的sql陳述句較復雜
一、VIEW 語法
/* 創建方式一 */
CREATE VIEW 視圖名 AS 查詢陳述句;
/* 創建方式二 */
ALTER VIEW 視圖名 AS 查詢陳述句;
/* 修改視圖 */
CREATE OR REPLACE VIEW 視圖名 AS 查詢陳述句;
/* 洗掉視圖 */
DROP VIEW 視圖名, 視圖名, …;
/* 查看視圖 */
DESC 視圖名; # 查看結構
SHOW CREATE VIEW 視圖名; # 查看創建程序
/* 注:視圖創建后和表使用方式相同 */
變數
一、變數分類
系統變數:全域變數 會話變數
自定義變數:用戶變數 區域變數
二、系統變數
由系統提供,屬于服務器層面
-
查看所有系統變數
SHOW GLOBAL VARIABLES;
SHOW [SESSION] VARIABLES; -
查看滿足條件的系統變數
可使用LIKE進行篩選 -
查看指定的某個系統變數的值
會話
SELECT @@[SESSION.]系統變數名;
全域
SELEC @@GLOBAL.系統變數; -
為某個系統變數賦值
SET GLOBAL/[SESSION]系統變數=值;
SET @@GLOBAL/[SESSION].系統變數=值;
注:全域級別需要加GLOBAL,會話級別加SESSION,兩者都不加默認會話級別
會話變數:
僅僅作用于當前會話(連接)
全域變數:
作用于所有會話,服務器每次啟動時將為所有全域變數賦初始值
三、自定義變數
- 用戶變數
作用于當前會話(連接),同會話變數作用域
/* 宣告并初始化 */
SET @用戶變數名 = 值
SET @用戶變數名 := 值
SELECT @用戶變數名 := 值
/* 賦值(更新變數值) */
SELECT 欄位 INTO 變數名 FROM 表
/* 也可用宣告初始化方式賦值 */
- 區域變數
僅僅在定義它的 begin end 中有效,應用在 begin end 第一句話
/* 宣告 */
DECLARE 變數名 型別;
DECLARE 變數名 型別 DEFALT 值;
/* 賦值 */
SELECT 欄位 INTO 變數名 FROM 表;
SET 變數名 = 值
SET 變數名 := 值
SELECT 變數名 := 值
存盤程序與函式
一、存盤程序
含義:一組預先編譯好的SQL陳述句的集合
- 作用
(1) 提高代碼重用性
(2) 簡化操作
(3) 減少了編譯次數并且減少了和資料庫服務器的連接次數,調高效率
- PROCEDURE 語法
/* 創建存盤程序 */
CREATE PROCEDURE 存盤程序名(引數串列)
BEGIN
存盤程序體
END
/* 呼叫存盤程序 */
CALL 存盤程序名(實參串列);
/* 洗掉存盤程序 */
DROP PROCEDURE 存盤程序名;
/* 查看存盤程序資訊 */
SHOW CREATE PROCEDURE 存盤程序名;
- 引數串列
引數引數串列包含三部分 引數模式 引數名 引數型別
| 引數模式 | 描述 |
|---|---|
| IN | 該引數可以作為輸入(需要傳入值) |
| OUT | 該引數可以作為輸出(可以作為回傳值) (OUT 變數名 型別) |
| INOUT | 該引數既可作為輸入,又可作為輸出 (INOUT 變數名 型別) |
- 注意
(1) 若存盤程序體僅有一句話,BEGIN END可以省略
(2) 存盤程序體中的每條SQL陳述句結尾必須加分號
(3) 可以使用DELIMITER 結束標記重新設定存盤程序結尾的結束標記
二、函式
- FUNCTION 語法
/* 創建函式 */
CREATE FUNCTION 函式名(引數串列) RETURNS 回傳型別
BEGIN
函式體
END
/* 呼叫函式 */
SELECT 函式名(引數串列)
/* 洗掉函式 */
DROP FUNCTION 函式名;
/* 查看函式資訊 */
SHOW CREATE FUNCTION 函式名;
- 函式與存盤程序對比
- 存盤程序:可以有0個回傳,也可以多個回傳,適合做批量插入,批量更新
- 函式:有且僅有一個回傳,適合做處理資料后回傳一個結果
流程控制結構
一、分支結構
- IF 函式
功能:簡單的雙分支
語法:IF(運算式1, 運算式2, 運算式3)
若運算式1成立則回傳運算式2,否則回傳運算式3
- IF 結構
功能:實作多重分支
語法:
IF 條件1 THEN 陳述句1;
ELSEIF 條件2 THEN 陳述句2;
...
ELSE 陳述句n;
END IF;
- 特點:只能在 BEGIN END 中使用
- CASE 結構
功能:類似java的switch陳述句,實作等值判斷;類似java的多重if陳述句,實作區間判斷
語法:
CASE 變數/運算式/欄位
WHEN 判斷的值 THEN 回傳值1 或 陳述句
…
ELSE 回傳值n 或 陳述句
END CASE;
- 特點
(1) 可以作為運算式,嵌套其他陳述句使用,可以放任何地方
(2) 可以作為獨立陳述句使用,只能放在BEGIN END中
(3) ELSE可省略
二、回圈結構
分類:
WHILE LOOP REPEAT
回圈控制:ITERATE(類似continue)LEAVE(類似于break)
- 回圈結構語法
/* WHILE 先判斷后執行 */
[標簽:] WHILE 回圈條件 DO
回圈體;
END WHILE [標簽];
/* LOOP 死回圈 */
[標簽:] LOOP
回圈體;
END LOOP[標簽];
/* REPEAT 先執行后判斷 */
[標簽:]REPEAT
回圈體;
UNTIL 結束回圈條件
END REPEAT [標簽];
/* 以上回圈都需要在 BEGIN END 中 */
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/275368.html
標籤:MySQL
上一篇:SQL必知必會,帶你系統學習
下一篇:表相關
