目錄
一、MySQL 常用函數
1. 字符串函數
1.1 基本字符串操作
1.2 字符串截取與處理
1.3 字符串搜索與替換
2. 數值函數
2.1 基本數學運算
2.2 數學計算
2.3 隨機數與符號
3. 日期時間函數
3.1 獲取當前時間
3.2 日期時間計算
3.3 日期時間提取
3.4 日期時間格式化
4. 條件函數
4.1 流程控制函數
4.2 聚合函數
5. 窗口函數 (MySQL 8.0+)
6. JSON 函數 (MySQL 5.7+)
7. 系統信息函數
8. 加密函數
二、MySQL 約束
1. 主鍵約束 (PRIMARY KEY)
1.1 基本用法
1.2 修改表添加主鍵
1.3 自增主鍵
2. 外鍵約束 (FOREIGN KEY)
2.1 基本用法
2.2 級聯操作
2.3 修改表添加外鍵
3. 唯一約束 (UNIQUE)
3.1 基本用法
3.2 多列組合唯一
3.3 修改表添加唯一約束
4. 非空約束 (NOT NULL)
4.1 基本用法
4.2 修改表添加非空約束
5. 默認值約束 (DEFAULT)
5.1 基本用法
5.2 修改表添加默認值
6. 檢查約束 (CHECK)
6.1 基本用法
6.2 命名檢查約束
6.3 修改表添加檢查約束
7. 約束管理
7.1 查看約束
7.2 刪除約束
三、多表查詢
1. 內連接 (INNER JOIN)
2. 左外連接 (LEFT JOIN)
3. 右外連接 (RIGHT JOIN)
4. 全外連接 (FULL OUTER JOIN) - MySQL不支持,可用UNION模擬
5. 交叉連接 (CROSS JOIN)
6. 自連接 (SELF JOIN)
7. 自然連接 (NATURAL JOIN)
8. USING 子句
9. 子查詢
9.1 WHERE子句中的子查詢
(1)標量子查詢(返回單個值)
(2)列子查詢(返回單列多行)
(3)行子查詢(返回單行多列)
9.2 FROM子句中的子查詢(派生表)
9.3 SELECT子句中的子查詢(標量子查詢)
9.4 HAVING子句中的子查詢
9.5 EXISTS和NOT EXISTS子查詢
10. 集合操作
10.1 UNION 和 UNION ALL
10.2 INTERSECT (MySQL 8.0.31+)
10.3 EXCEPT/MINUS (MySQL 8.0.31+)
四、事務 (Transaction)
1. 事務的基本特性 (ACID)
2. 事務控制語句
3. 事務隔離級別
4. 事務并發問題
(1)臟讀 (Dirty Read)
(2)不可重復讀 (Non-repeatable Read)
(3)幻讀 (Phantom Read)
5. 保存點 (SAVEPOINT)
一、MySQL 常用函數
MySQL 提供了豐富的內置函數,可以用于數據處理、計算和轉換。這些函數主要分為以下幾類:
1. 字符串函數
1.1 基本字符串操作
?-- 連接字符串SELECT CONCAT('Hello', ' ', 'World'); -- 輸出: Hello WorldSELECT CONCAT_WS('-', '2023', '01', '01'); -- 用分隔符連接: 2023-01-01?-- 字符串長度SELECT LENGTH('MySQL'); -- 字節數: 5SELECT CHAR_LENGTH('MySQL'); -- 字符數: 5?-- 大小寫轉換SELECT UPPER('mysql'); -- MYSQLSELECT LOWER('MySQL'); -- mysql
1.2 字符串截取與處理
?-- 截取字符串SELECT SUBSTRING('MySQL', 2, 3); -- ySQ (從第2個字符開始,取3個)SELECT LEFT('MySQL', 2); -- MySELECT RIGHT('MySQL', 3); -- SQL?-- 去除空格SELECT TRIM(' MySQL '); -- 'MySQL'SELECT LTRIM(' MySQL'); -- 'MySQL'SELECT RTRIM('MySQL '); -- 'MySQL'?-- 填充字符串SELECT LPAD('5', 3, '0'); -- 005SELECT RPAD('Hi', 5, '!'); -- Hi!!!
1.3 字符串搜索與替換
?-- 查找位置SELECT INSTR('MySQL', 'SQL'); -- 3 (SQL在MySQL中的位置)SELECT LOCATE('SQL', 'MySQL'); -- 3?-- 替換字符串SELECT REPLACE('MySQL', 'SQL', 'Database'); -- MyDatabase?-- 正則表達式SELECT 'MySQL' REGEXP '^My'; -- 1 (匹配成功)SELECT REGEXP_REPLACE('abc123', '[0-9]', 'X'); -- abcXXX
2. 數值函數
2.1 基本數學運算
?-- 四舍五入SELECT ROUND(3.14159, 2); -- 3.14SELECT ROUND(123.456, -1); -- 120 (小數點左側舍入)?-- 取整SELECT CEIL(3.14); -- 4 (向上取整)SELECT FLOOR(3.14); -- 3 (向下取整)SELECT TRUNCATE(3.14159, 2); -- 3.14 (截斷)?-- 絕對值SELECT ABS(-10); -- 10
2.2 數學計算
?-- 冪運算SELECT POWER(2, 3); -- 8 (2的3次方)SELECT SQRT(16); -- 4 (平方根)?-- 對數SELECT LOG(2, 8); -- 3 (以2為底8的對數)SELECT LN(10); -- 自然對數SELECT LOG10(100); -- 2?-- 三角函數SELECT SIN(PI()/2); -- 1SELECT COS(0); -- 1SELECT TAN(PI()/4); -- 約等于1
2.3 隨機數與符號
?-- 隨機數SELECT RAND(); -- 0到1之間的隨機數SELECT FLOOR(1 + RAND() * 10); -- 1-10的隨機整數?-- 符號判斷SELECT SIGN(-10); -- -1SELECT SIGN(0); -- 0SELECT SIGN(10); -- 1
3. 日期時間函數
3.1 獲取當前時間
?SELECT NOW(); -- 當前日期和時間 (2023-01-01 12:34:56)SELECT CURDATE(); -- 當前日期 (2023-01-01)SELECT CURTIME(); -- 當前時間 (12:34:56)SELECT UNIX_TIMESTAMP(); -- 當前UNIX時間戳
3.2 日期時間計算
?-- 日期加減SELECT DATE_ADD(NOW(), INTERVAL 1 DAY); -- 加1天SELECT DATE_SUB(NOW(), INTERVAL 1 MONTH); -- 減1個月SELECT NOW() + INTERVAL 1 HOUR; -- 加1小時?-- 日期差SELECT DATEDIFF('2023-12-31', '2023-01-01'); -- 364 (天數差)SELECT TIMESTAMPDIFF(MONTH, '2023-01-01', '2023-12-31'); -- 11 (月數差)
3.3 日期時間提取
?-- 提取日期部分SELECT YEAR(NOW()); -- 2023SELECT MONTH(NOW()); -- 1-12SELECT DAY(NOW()); -- 1-31SELECT HOUR(NOW()); -- 0-23SELECT MINUTE(NOW()); -- 0-59SELECT SECOND(NOW()); -- 0-59?-- 星期和季度SELECT DAYNAME(NOW()); -- MondaySELECT DAYOFWEEK(NOW()); -- 1=周日, 2=周一,...,7=周六SELECT QUARTER(NOW()); -- 1-4
3.4 日期時間格式化
?-- 格式化日期SELECT DATE_FORMAT(NOW(), '%Y-%m-%d'); -- 2023-01-01SELECT DATE_FORMAT(NOW(), '%H:%i:%s'); -- 12:34:56SELECT DATE_FORMAT(NOW(), '%W, %M %e, %Y'); -- Sunday, January 1, 2023?-- 解析日期字符串SELECT STR_TO_DATE('01-01-2023', '%d-%m-%Y'); -- 2023-01-01
4. 條件函數
4.1 流程控制函數
?-- IF函數SELECT IF(1 > 0, 'True', 'False'); -- TrueSELECT IFNULL(NULL, 'Default'); -- DefaultSELECT NULLIF(10, 10); -- NULL (兩值相等返回NULL)?-- CASE WHENSELECT score,CASE WHEN score >= 90 THEN 'A'WHEN score >= 80 THEN 'B'WHEN score >= 70 THEN 'C'ELSE 'D'END AS gradeFROM students;
4.2 聚合函數
?-- 基本聚合SELECT COUNT(*) FROM users; -- 記錄數SELECT AVG(price) FROM products; -- 平均值SELECT SUM(quantity) FROM order_items; -- 總和SELECT MAX(salary) FROM employees; -- 最大值SELECT MIN(age) FROM customers; -- 最小值?-- 分組聚合SELECT department_id, AVG(salary)FROM employeesGROUP BY department_idHAVING AVG(salary) > 5000;
5. 窗口函數 (MySQL 8.0+)
?-- 排名函數SELECT name, salary,RANK() OVER (ORDER BY salary DESC) AS rank,DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank,ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_numFROM employees;?-- 分區計算SELECT department_id, name, salary,AVG(salary) OVER (PARTITION BY department_id) AS dept_avg_salaryFROM employees;?-- 累計計算SELECT order_date, amount,SUM(amount) OVER (ORDER BY order_date) AS running_totalFROM orders;
6. JSON 函數 (MySQL 5.7+)
?-- 創建JSONSELECT JSON_OBJECT('name', 'John', 'age', 30);SELECT JSON_ARRAY(1, 'a', TRUE, NULL);?-- 提取JSON值SELECT JSON_EXTRACT('{"name": "John", "age": 30}', '$.name'); -- "John"SELECT JSON_UNQUOTE(JSON_EXTRACT('{"name": "John"}', '$.name')); -- John?-- 修改JSONSELECT JSON_SET('{"name": "John"}', '$.age', 30); -- {"name": "John", "age": 30}SELECT JSON_REMOVE('{"name": "John", "age": 30}', '$.age'); -- {"name": "John"}
7. 系統信息函數
?-- 數據庫信息SELECT DATABASE(); -- 當前數據庫名SELECT USER(); -- 當前用戶SELECT VERSION(); -- MySQL版本?-- 連接信息SELECT CONNECTION_ID(); -- 連接IDSELECT LAST_INSERT_ID(); -- 最后插入的ID?-- 性能分析SELECT BENCHMARK(1000000, MD5('test')); -- 執行MD5 100萬次
8. 加密函數
?-- 哈希函數SELECT MD5('password'); -- 32字符MD5哈希SELECT SHA1('password'); -- 40字符SHA1哈希SELECT SHA2('password', 256); -- 64字符SHA256哈希?-- 加密解密SELECT AES_ENCRYPT('secret', 'key');SELECT AES_DECRYPT(encrypted_data, 'key');?-- 密碼函數SELECT PASSWORD('mypass'); -- 已廢棄,不推薦使用
二、MySQL 約束
約束是用于限制表中數據類型的規則,確保數據的準確性和可靠性。MySQL 支持多種約束類型,以下是簡要介紹:
1. 主鍵約束 (PRIMARY KEY)
1.1 基本用法
?-- 創建表時定義單列主鍵CREATE TABLE users (user_id INT PRIMARY KEY,username VARCHAR(50) NOT NULL);?-- 創建表時定義多列組合主鍵CREATE TABLE order_items (order_id INT,product_id INT,quantity INT,PRIMARY KEY (order_id, product_id));
1.2 修改表添加主鍵
?ALTER TABLE employees ADD PRIMARY KEY (emp_id);
1.3 自增主鍵
?CREATE TABLE products (product_id INT AUTO_INCREMENT PRIMARY KEY,product_name VARCHAR(100) NOT NULL);
2. 外鍵約束 (FOREIGN KEY)
2.1 基本用法
?CREATE TABLE orders (order_id INT PRIMARY KEY,customer_id INT,order_date DATE,FOREIGN KEY (customer_id) REFERENCES customers(customer_id));
2.2 級聯操作
?CREATE TABLE order_items (item_id INT PRIMARY KEY,order_id INT,product_id INT,FOREIGN KEY (order_id) REFERENCES orders(order_id)ON DELETE CASCADE ?-- 主表刪除時級聯刪除ON UPDATE CASCADE, -- 主表更新時級聯更新FOREIGN KEY (product_id) REFERENCES products(product_id)ON DELETE SET NULL -- 主表刪除時設為NULL);
2.3 修改表添加外鍵
?ALTER TABLE employeesADD CONSTRAINT fk_deptFOREIGN KEY (department_id) REFERENCES departments(dept_id);
3. 唯一約束 (UNIQUE)
3.1 基本用法
?CREATE TABLE employees (emp_id INT PRIMARY KEY,email VARCHAR(100) UNIQUE,phone VARCHAR(20),CONSTRAINT uc_phone UNIQUE (phone) -- 命名約束);
3.2 多列組合唯一
?CREATE TABLE class_registry (student_id INT,class_id INT,semester VARCHAR(10),UNIQUE (student_id, class_id, semester));
3.3 修改表添加唯一約束
?ALTER TABLE products ADD UNIQUE (product_code);
4. 非空約束 (NOT NULL)
4.1 基本用法
?CREATE TABLE customers (customer_id INT PRIMARY KEY,name VARCHAR(100) NOT NULL,email VARCHAR(100) NOT NULL UNIQUE);
4.2 修改表添加非空約束
?ALTER TABLE employees MODIFY COLUMN hire_date DATE NOT NULL;
5. 默認值約束 (DEFAULT)
5.1 基本用法
?CREATE TABLE orders (order_id INT PRIMARY KEY,order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,status VARCHAR(20) DEFAULT 'Pending',total_amount DECIMAL(10,2) DEFAULT 0.00);
5.2 修改表添加默認值
?ALTER TABLE products ALTER COLUMN stock SET DEFAULT 0;
6. 檢查約束 (CHECK)
6.1 基本用法
?CREATE TABLE employees (emp_id INT PRIMARY KEY,name VARCHAR(100) NOT NULL,salary DECIMAL(10,2) CHECK (salary > 0),age INT CHECK (age >= 18 AND age <= 65),gender VARCHAR(10) CHECK (gender IN ('Male', 'Female', 'Other')));
6.2 命名檢查約束
?CREATE TABLE products (product_id INT PRIMARY KEY,price DECIMAL(10,2),discount DECIMAL(10,2),CONSTRAINT chk_price CHECK (price > 0),CONSTRAINT chk_discount CHECK (discount >= 0 AND discount <= price));
6.3 修改表添加檢查約束
?ALTER TABLE employeesADD CONSTRAINT chk_salary CHECK (salary > 0);
7. 約束管理
7.1 查看約束
?-- 查看表的所有約束SELECT * FROM information_schema.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = 'your_database' AND TABLE_NAME = 'your_table';?-- 查看外鍵約束SELECT * FROM information_schema.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = 'your_database';
7.2 刪除約束
?-- 刪除主鍵ALTER TABLE users DROP PRIMARY KEY;?-- 刪除外鍵ALTER TABLE orders DROP FOREIGN KEY fk_customer;?-- 刪除唯一約束ALTER TABLE employees DROP INDEX uc_phone;?-- 刪除檢查約束 (MySQL 8.0.16+)ALTER TABLE employees DROP CHECK chk_salary;
三、多表查詢
1. 內連接 (INNER JOIN)
?-- 基本內連接SELECT e.emp_id, e.emp_name, d.dept_nameFROM employees eINNER JOIN departments d ON e.dept_id = d.dept_id;?-- 多表內連接SELECT o.order_id,c.customer_name,p.product_name,oi.quantityFROM orders oINNER JOIN customers c ON o.customer_id = c.customer_idINNER JOIN order_items oi ON o.order_id = oi.order_idINNER JOIN products p ON oi.product_id = p.product_id;
2. 左外連接 (LEFT JOIN)
?-- 保留左表所有記錄SELECT d.dept_name,e.emp_nameFROM departments dLEFT JOIN employees e ON d.dept_id = e.dept_id;
3. 右外連接 (RIGHT JOIN)
?-- 保留右表所有記錄SELECT e.emp_name,d.dept_nameFROM employees eRIGHT JOIN departments d ON e.dept_id = d.dept_id;
4. 全外連接 (FULL OUTER JOIN) - MySQL不支持,可用UNION模擬
?-- 使用UNION模擬全連接SELECT e.emp_name,d.dept_nameFROM employees eLEFT JOIN departments d ON e.dept_id = d.dept_idUNIONSELECT e.emp_name,d.dept_nameFROM employees eRIGHT JOIN departments d ON e.dept_id = d.dept_idWHERE e.dept_id IS NULL;
5. 交叉連接 (CROSS JOIN)
?-- 笛卡爾積SELECT e.emp_name,p.project_nameFROM employees eCROSS JOIN projects p;
6. 自連接 (SELF JOIN)
?-- 查找員工及其經理SELECT e1.emp_name AS employee,e2.emp_name AS managerFROM employees e1LEFT JOIN employees e2 ON e1.manager_id = e2.emp_id;?-- 查找同一部門的員工對SELECT a.emp_name AS employee1,b.emp_name AS employee2,a.dept_idFROM employees aJOIN employees b ON a.dept_id = b.dept_idWHERE a.emp_id < b.emp_id;
7. 自然連接 (NATURAL JOIN)
?-- 自動匹配相同名稱的列SELECT e.emp_name,d.dept_nameFROM employees eNATURAL JOIN departments d;
8. USING 子句
?-- 簡化連接條件SELECT e.emp_name,d.dept_nameFROM employees eJOIN departments d USING (dept_id);
9. 子查詢
9.1 WHERE子句中的子查詢
(1)標量子查詢(返回單個值)
?-- 查詢高于平均工資的員工SELECT emp_name, salaryFROM employeesWHERE salary > (SELECT AVG(salary) FROM employees);?-- 查詢最后入職的員工SELECT emp_name, hire_dateFROM employeesWHERE hire_date = (SELECT MAX(hire_date) FROM employees);
(2)列子查詢(返回單列多行)
?-- 使用IN操作符SELECT emp_name, dept_idFROM employeesWHERE dept_id IN (SELECT dept_id FROM departments WHERE location = 'New York');?-- 使用ANY/SOME操作符SELECT emp_name, salaryFROM employeesWHERE salary > ANY (SELECT salary FROM employees WHERE dept_id = 10);?-- 使用ALL操作符SELECT emp_name, salaryFROM employeesWHERE salary > ALL (SELECT salary FROM employees WHERE dept_id = 10);
(3)行子查詢(返回單行多列)
?-- 查詢與特定員工工資和部門相同的其他員工SELECT emp_name, salary, dept_idFROM employeesWHERE (salary, dept_id) = (SELECT salary, dept_id FROM employees WHERE emp_id = 100);
9.2 FROM子句中的子查詢(派生表)
?-- 計算每個部門的平均工資,然后查詢高于公司平均工資的部門SELECT d.dept_name, dept_avg.avg_salaryFROM departments dJOIN (SELECT dept_id, AVG(salary) AS avg_salaryFROM employeesGROUP BY dept_id) dept_avg ON d.dept_id = dept_avg.dept_idWHERE dept_avg.avg_salary > (SELECT AVG(salary) FROM employees);?-- 使用派生表進行分頁SELECT *FROM (SELECT emp_id, emp_name, salaryFROM employeesORDER BY salary DESCLIMIT 10) AS top_earners;
9.3 SELECT子句中的子查詢(標量子查詢)
?-- 查詢員工信息及其部門平均工資SELECT emp_id,emp_name,salary,(SELECT AVG(salary) FROM employees e2 WHERE e2.dept_id = e1.dept_id) AS dept_avg_salary,salary - (SELECT AVG(salary) FROM employees e2 WHERE e2.dept_id = e1.dept_id) AS diff_from_avgFROM employees e1;?-- 查詢產品信息及訂單數量SELECT p.product_id,p.product_name,(SELECT COUNT(*) FROM order_items oi WHERE oi.product_id = p.product_id) AS order_countFROM products p;
9.4 HAVING子句中的子查詢
?-- 查詢平均工資高于公司平均工資的部門SELECT dept_id, AVG(salary) AS avg_salaryFROM employeesGROUP BY dept_idHAVING AVG(salary) > (SELECT AVG(salary) FROM employees);?-- 查詢訂單數量超過客戶平均訂單數的客戶SELECT customer_id, COUNT(*) AS order_countFROM ordersGROUP BY customer_idHAVING COUNT(*) > (SELECT AVG(order_count) FROM (SELECT COUNT(*) AS order_count FROM orders GROUP BY customer_id) AS counts);
9.5 EXISTS和NOT EXISTS子查詢
?-- 查詢有訂單的客戶SELECT customer_nameFROM customers cWHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id);?-- 查詢沒有訂單的客戶SELECT customer_nameFROM customers cWHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id);?-- 查詢購買了所有產品的客戶SELECT customer_nameFROM customers cWHERE NOT EXISTS (SELECT product_idFROM products pWHERE NOT EXISTS (SELECT 1FROM orders oJOIN order_items oi ON o.order_id = oi.order_idWHERE o.customer_id = c.customer_idAND oi.product_id = p.product_id));
10. 集合操作
10.1 UNION 和 UNION ALL
?-- 合并結果集 (去重)SELECT product_id FROM current_productsUNIONSELECT product_id FROM discontinued_products;?-- 合并結果集 (保留重復)SELECT product_id FROM current_productsUNION ALLSELECT product_id FROM discontinued_products;
10.2 INTERSECT (MySQL 8.0.31+)
?-- 交集SELECT customer_id FROM premium_customersINTERSECTSELECT customer_id FROM active_customers;
10.3 EXCEPT/MINUS (MySQL 8.0.31+)
?-- 差集SELECT employee_id FROM all_employeesEXCEPTSELECT employee_id FROM current_employees;
四、事務 (Transaction)
1. 事務的基本特性 (ACID)
-
原子性 (Atomicity): 事務是不可分割的工作單位。
-
一致性 (Consistency): 事務執行前后數據庫保持一致狀態。
-
隔離性 (Isolation): 多個事務并發執行時互不干擾。
-
持久性 (Durability): 事務提交后對數據庫的改變是永久的。
2. 事務控制語句
?-- 開始事務START TRANSACTION;?-- 執行SQL語句INSERT INTO accounts (user_id, balance) VALUES (1, 1000);UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;UPDATE accounts SET balance = balance + 100 WHERE user_id = 2;?-- 提交事務COMMIT;?-- 回滾事務ROLLBACK;
3. 事務隔離級別
?-- 查看當前隔離級別SELECT @@transaction_isolation;?-- 設置隔離級別(會話級)SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;?-- 設置隔離級別(全局)SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;?-- 四種隔離級別SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;SET TRANSACTION ISOLATION LEVEL READ COMMITTED;SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- MySQL默認SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
四種隔離級別比較:
隔離級別 | 臟讀 | 不可重復讀 | 幻讀 | 性能 |
---|---|---|---|---|
READ UNCOMMITTED | 可能 | 可能 | 可能 | 最高 |
READ COMMITTED | 不可能 | 可能 | 可能 | 高 |
REPEATABLE READ(默認) | 不可能 | 不可能 | 可能 | 中 |
SERIALIZABLE | 不可能 | 不可能 | 不可能 | 低 |
4. 事務并發問題
(1)臟讀 (Dirty Read)
讀取到其他事務未提交的數據。
?-- 事務ASET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;START TRANSACTION;SELECT * FROM accounts WHERE user_id = 1; -- 可能讀取到事務B未提交的數據?-- 事務BSTART TRANSACTION;UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;-- 尚未提交
(2)不可重復讀 (Non-repeatable Read)
同一事務內多次讀取同一數據結果不同。
?-- 事務ASET TRANSACTION ISOLATION LEVEL READ COMMITTED;START TRANSACTION;SELECT * FROM accounts WHERE user_id = 1; -- 第一次讀取?-- 事務B提交了更新UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;COMMIT;?SELECT * FROM accounts WHERE user_id = 1; -- 第二次讀取結果不同
(3)幻讀 (Phantom Read)
同一事務內多次查詢返回的結果集不同。
?-- 事務ASET TRANSACTION ISOLATION LEVEL REPEATABLE READ;START TRANSACTION;SELECT * FROM accounts WHERE balance > 1000; -- 返回10條記錄?-- 事務B插入新記錄并提交INSERT INTO accounts VALUES (11, '新用戶', 1500);COMMIT;?SELECT * FROM accounts WHERE balance > 1000; -- 返回11條記錄
5. 保存點 (SAVEPOINT)
?START TRANSACTION;?INSERT INTO orders (order_id, user_id) VALUES (1, 1);SAVEPOINT savepoint1;?UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;-- 如果出現問題可以回滾到保存點ROLLBACK TO savepoint1;?COMMIT;