一、引言
MySQL 作為一款廣泛使用的開源關系型數據庫管理系統,在數據存儲和管理領域占據著重要地位。MySQL 8.4 版本在性能、功能和安全性等方面都有了顯著的提升。本文將全面介紹 MySQL 8.4 中 SQL 的各種知識點,并結合實戰場景進行詳細講解,幫助讀者更好地掌握和應用 MySQL。
二、數據庫操作
2.1 創建數據庫
創建數據庫時,可以指定字符集和排序規則以滿足不同的需求。
-- 創建名為 mydb 的數據庫,指定字符集為 utf8mb4,排序規則為 utf8mb4_unicode_ci
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
實戰場景:在開發一個多語言的網站時,需要存儲不同語言的文本信息,使用?utf8mb4
?字符集可以支持更廣泛的字符編碼。
2.2 查看數據庫
使用?SHOW DATABASES
?語句可以查看當前 MySQL 服務器中所有的數據庫。
SHOW DATABASES;
2.3 選擇數據庫
使用?USE
?語句選擇要操作的數據庫。
USE mydb;
2.4 刪除數據庫
刪除數據庫會永久刪除數據庫及其包含的所有數據,操作需謹慎。
DROP DATABASE mydb;
實戰場景:當項目不再需要某個數據庫時,可以使用該語句刪除數據庫以釋放磁盤空間。
2.5 修改數據庫屬性
可以使用?ALTER DATABASE
?語句修改數據庫的字符集和排序規則。
ALTER DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
三、表操作
3.1 創建表
創建表時需要定義列名、數據類型和約束條件。
-- 創建名為 users 的表
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL UNIQUE,email VARCHAR(100) NOT NULL UNIQUE,password VARCHAR(255) NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
實戰場景:在開發一個用戶管理系統時,使用該表存儲用戶的基本信息。
3.2 查看表結構
使用?DESCRIBE
?或?SHOW COLUMNS FROM
?語句查看表的結構。
DESCRIBE users;
-- 或者
SHOW COLUMNS FROM users;
3.3 修改表
可以使用?ALTER TABLE
?語句對表進行各種修改操作,如添加列、修改列的數據類型、刪除列等。
-- 添加列
ALTER TABLE users ADD COLUMN last_login TIMESTAMP;-- 修改列的數據類型
ALTER TABLE users MODIFY COLUMN password VARCHAR(512);-- 刪除列
ALTER TABLE users DROP COLUMN last_login;
實戰場景:隨著業務的發展,需要在用戶表中添加一個新的字段來記錄用戶的最后登錄時間,使用?ALTER TABLE
?語句可以方便地實現。
3.4 刪除表
刪除表會刪除表及其包含的所有數據,操作需謹慎。
DROP TABLE users;
3.5 重命名表
使用?RENAME TABLE
?語句可以重命名表。
RENAME TABLE users TO new_users;
四、數據操作
4.1 插入數據
可以使用?INSERT INTO
?語句向表中插入單條或多條數據。
-- 插入單條數據
INSERT INTO users (username, email, password) VALUES ('john_doe', 'john@example.com', 'hashed_password');-- 插入多條數據
INSERT INTO users (username, email, password) VALUES
('jane_smith', 'jane@example.com', 'hashed_password2'),
('bob_johnson', 'bob@example.com', 'hashed_password3');
實戰場景:在用戶注冊時,將用戶的信息插入到用戶表中。
4.2 更新數據
使用?UPDATE
?語句更新表中的數據。
UPDATE users SET password = 'new_hashed_password' WHERE username = 'john_doe';
實戰場景:當用戶修改密碼時,使用該語句更新用戶表中的密碼字段。
4.3 刪除數據
使用?DELETE FROM
?語句刪除表中的數據。
DELETE FROM users WHERE username = 'bob_johnson';
實戰場景:當用戶注銷賬戶時,使用該語句從用戶表中刪除該用戶的信息。
4.4 查詢數據
使用?SELECT
?語句查詢表中的數據,可以使用?WHERE
?子句進行條件過濾,ORDER BY
?進行排序,LIMIT
?進行分頁等。
-- 查詢所有用戶的信息
SELECT * FROM users;-- 查詢用戶名以 'j' 開頭的用戶信息
SELECT * FROM users WHERE username LIKE 'j%';-- 查詢所有用戶信息,按創建時間降序排列
SELECT * FROM users ORDER BY created_at DESC;-- 查詢前 10 條用戶信息
SELECT * FROM users LIMIT 10;
實戰場景:在用戶列表頁面,需要顯示所有用戶的信息,并且可以根據用戶輸入的關鍵字進行篩選和排序。
五、條件查詢
5.1 比較運算符
使用比較運算符(如?=
,?>
,?<
,?>=
,?<=
,?<>
)進行條件過濾。
-- 查詢年齡大于 20 的用戶信息
SELECT * FROM users WHERE age > 20;
5.2 邏輯運算符
使用邏輯運算符(如?AND
,?OR
,?NOT
)組合多個條件。
-- 查詢年齡大于 20 且性別為男的用戶信息
SELECT * FROM users WHERE age > 20 AND gender = 'male';
5.3 范圍運算符
使用范圍運算符(如?BETWEEN
,?IN
)進行范圍查詢。
-- 查詢年齡在 20 到 30 之間的用戶信息
SELECT * FROM users WHERE age BETWEEN 20 AND 30;-- 查詢用戶名是 'john_doe' 或 'jane_smith' 的用戶信息
SELECT * FROM users WHERE username IN ('john_doe', 'jane_smith');
5.4 模糊查詢運算符
使用模糊查詢運算符(如?LIKE
)進行模糊查詢,%
?表示任意多個字符,_
?表示任意單個字符。
-- 查詢郵箱以 'example.com' 結尾的用戶信息
SELECT * FROM users WHERE email LIKE '%example.com';
六、排序和分頁
6.1 排序
使用?ORDER BY
?語句對查詢結果進行排序,可以按單個列或多個列進行排序,默認是升序(ASC
),也可以指定降序(DESC
)。
-- 按用戶的創建時間降序排列
SELECT * FROM users ORDER BY created_at DESC;-- 先按年齡升序排列,年齡相同的再按用戶名升序排列
SELECT * FROM users ORDER BY age ASC, username ASC;
實戰場景:在商品列表頁面,需要按商品的價格降序排列,以便用戶快速找到價格較高的商品。
6.2 分頁
使用?LIMIT
?語句進行分頁,LIMIT offset, count
?中,offset
?表示從第幾行開始取數據(從 0 開始計數),count
?表示取多少行數據。
-- 顯示第 2 頁(每頁顯示 10 條記錄)的用戶信息
SELECT * FROM users LIMIT 10, 10;
實戰場景:在新聞列表頁面,為了提高頁面加載速度,通常會采用分頁的方式顯示新聞,每次只加載 10 條新聞。
七、聚合函數
7.1 常用聚合函數
SUM()
:計算列的總和。AVG()
:計算列的平均值。COUNT()
:計算行數。MAX()
:獲取列的最大值。MIN()
:獲取列的最小值。
-- 計算所有用戶的年齡總和
SELECT SUM(age) FROM users;-- 計算所有用戶的平均年齡
SELECT AVG(age) FROM users;-- 統計用戶的數量
SELECT COUNT(*) FROM users;-- 獲取用戶的最大年齡
SELECT MAX(age) FROM users;-- 獲取用戶的最小年齡
SELECT MIN(age) FROM users;
實戰場景:在統計報表中,需要計算某一時間段內的銷售總額、平均銷售額等數據。
7.2 GROUP BY 子句
使用?GROUP BY
?子句將查詢結果按指定的列進行分組,通常與聚合函數一起使用。
-- 按性別分組,統計每個性別的用戶數量
SELECT gender, COUNT(*) FROM users GROUP BY gender;
7.3 HAVING 子句
使用?HAVING
?子句過濾分組后的結果,與?WHERE
?子句類似,但?WHERE
?用于過濾行,HAVING
?用于過濾分組。
-- 按性別分組,統計每個性別的用戶數量,只顯示用戶數量大于 10 的分組
SELECT gender, COUNT(*) FROM users GROUP BY gender HAVING COUNT(*) > 10;
八、連接查詢
8.1 內連接(INNER JOIN)
內連接只返回兩個表中匹配的記錄。
-- 創建訂單表
CREATE TABLE orders (order_id INT AUTO_INCREMENT PRIMARY KEY,user_id INT,order_amount DECIMAL(10, 2) NOT NULL,FOREIGN KEY (user_id) REFERENCES users(id)
);-- 查詢用戶及其訂單信息
SELECT users.username, orders.order_amount
FROM users
INNER JOIN orders ON users.id = orders.user_id;
實戰場景:在電商系統中,需要查詢每個用戶的訂單信息,使用內連接可以將用戶表和訂單表進行關聯。
8.2 左連接(LEFT JOIN)
左連接返回左表中的所有記錄,以及右表中匹配的記錄。如果右表中沒有匹配的記錄,對應列的值為?NULL
。?
-- 查詢所有用戶及其訂單信息(包括沒有訂單的用戶)
SELECT users.username, orders.order_amount
FROM users
LEFT JOIN orders ON users.id = orders.user_id;
實戰場景:在用戶管理系統中,需要查詢所有用戶的訂單信息,包括沒有訂單的用戶,使用左連接可以滿足需求。
8.3 右連接(RIGHT JOIN)
右連接返回右表中的所有記錄,以及左表中匹配的記錄。如果左表中沒有匹配的記錄,對應列的值為?NULL
。
-- 查詢所有訂單及其對應的用戶信息(包括沒有關聯用戶的訂單)
SELECT users.username, orders.order_amount
FROM users
RIGHT JOIN orders ON users.id = orders.user_id;
8.4 全連接(FULL JOIN)
MySQL 8.4 中沒有直接的?FULL JOIN
?語法,可以通過?UNION
?組合左連接和右連接來實現。
-- 實現全連接
SELECT users.username, orders.order_amount
FROM users
LEFT JOIN orders ON users.id = orders.user_id
UNION
SELECT users.username, orders.order_amount
FROM users
RIGHT JOIN orders ON users.id = orders.user_id;
8.5 自連接
自連接是表與自身進行連接,常用于處理具有層次結構的數據。
-- 假設用戶表中有 parent_id 字段表示上級用戶
SELECT u1.username AS user, u2.username AS parent_user
FROM users u1
LEFT JOIN users u2 ON u1.parent_id = u2.id;
實戰場景:在組織架構管理系統中,需要查詢每個員工的上級領導信息,使用自連接可以實現。
九、子查詢
9.1 標量子查詢
標量子查詢返回單個值。
-- 查詢年齡大于平均年齡的用戶信息
SELECT * FROM users WHERE age > (SELECT AVG(age) FROM users);
9.2 行子查詢
行子查詢返回一行數據。
-- 查詢與指定用戶年齡和性別相同的用戶信息
SELECT * FROM users WHERE (age, gender) = (SELECT age, gender FROM users WHERE id = 1);
9.3 列子查詢
列子查詢返回一列數據。
-- 查詢所有訂單金額大于平均訂單金額的訂單所屬的用戶信息
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE order_amount > (SELECT AVG(order_amount) FROM orders));
9.4 表子查詢
表子查詢返回一個表。
-- 查詢每個月的訂單數量和總金額
SELECT month, COUNT(*) AS order_count, SUM(order_amount) AS total_amount
FROM (SELECT MONTH(order_date) AS month, order_amountFROM orders
) subquery
GROUP BY month;
十、事務處理
10.1 事務的特性
事務遵循 ACID 原則,即原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持久性(Durability)。
10.2 事務控制語句
11.2 創建索引
START TRANSACTION
:開始一個事務。COMMIT
:提交事務,將事務中的所有操作永久保存到數據庫。ROLLBACK
:回滾事務,撤銷事務中的所有操作。SAVEPOINT
:在事務中設置保存點。ROLLBACK TO SAVEPOINT
:回滾到指定的保存點。-- 開始事務 START TRANSACTION;-- 設置保存點 SAVEPOINT sp1;-- 執行一系列操作 UPDATE users SET balance = balance - 100 WHERE id = 1; UPDATE accounts SET amount = amount + 100 WHERE user_id = 1;-- 如果出現錯誤,回滾到保存點 IF (出現錯誤條件) THENROLLBACK TO SAVEPOINT sp1; ELSECOMMIT; END IF;
實戰場景:在銀行轉賬系統中,需要保證轉賬操作的原子性,使用事務可以確保轉賬過程中不會出現數據不一致的情況。
10.3 事務隔離級別
MySQL 支持四種事務隔離級別,分別是?
READ UNCOMMITTED
、READ COMMITTED
、REPEATABLE READ
(默認)和?SERIALIZABLE
。不同的隔離級別在并發性能和數據一致性上有不同的表現。-- 設置事務隔離級別為 READ COMMITTED SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
十一、索引操作
11.1 索引類型
- 普通索引:用于提高查詢效率。
- 唯一索引:保證列中的值唯一。
- 主鍵索引:是一種特殊的唯一索引,用于唯一標識表中的每一行。
- 全文索引:用于全文搜索。
-- 創建普通索引 CREATE INDEX idx_username ON users (username);-- 創建唯一索引 CREATE UNIQUE INDEX idx_email ON users (email);-- 創建全文索引 CREATE FULLTEXT INDEX idx_fulltext_content ON articles (content);
實戰場景:在用戶表中,經常根據用戶名進行查詢,為用戶名列創建普通索引可以提高查詢效率。
11.3 刪除索引
DROP INDEX idx_username ON users;
11.4 查看索引
SHOW INDEX FROM users;
十二、視圖
12.1 創建視圖
視圖是虛擬的表,基于一個或多個表的查詢結果。
-- 創建一個視圖,顯示用戶的用戶名和訂單總金額 CREATE VIEW user_order_summary AS SELECT users.username, SUM(orders.order_amount) AS total_amount FROM users LEFT JOIN orders ON users.id = orders.user_id GROUP BY users.id;
實戰場景:在數據分析系統中,經常需要查詢用戶的訂單總金額,創建視圖可以簡化查詢操作。
12.2 查詢視圖
可以像查詢普通表一樣查詢視圖。
SELECT * FROM user_order_summary;
12.3 修改視圖
ALTER VIEW user_order_summary AS SELECT users.username, SUM(orders.order_amount) AS total_amount FROM users INNER JOIN orders ON users.id = orders.user_id GROUP BY users.id;
12.4 刪除視圖
DROP VIEW user_order_summary;
十三、存儲過程和函數
13.1 存儲過程
?存儲過程是一組預編譯的 SQL 語句,存儲在數據庫中,可以通過名稱調用。
-- 創建一個存儲過程,用于更新用戶的余額 DELIMITER // CREATE PROCEDURE UpdateUserBalance(IN user_id INT, IN amount DECIMAL(10, 2)) BEGINUPDATE users SET balance = balance + amount WHERE id = user_id;SELECT balance FROM users WHERE id = user_id; END // DELIMITER ;-- 調用存儲過程 CALL UpdateUserBalance(1, 100);
實戰場景:在金融系統中,經常需要進行賬戶余額的更新操作,使用存儲過程可以提高代碼的復用性和安全性。
13.2 函數
函數與存儲過程類似,但函數必須有返回值,并且可以在 SQL 語句中像普通函數一樣調用。
-- 創建一個函數,用于計算兩個數的和
DELIMITER //
CREATE FUNCTION AddNumbers(num1 INT, num2 INT)
RETURNS INT
DETERMINISTIC
BEGINDECLARE result INT;SET result = num1 + num2;RETURN result;
END //
DELIMITER ;-- 調用函數
SELECT AddNumbers(5, 3);
實戰場景
在一個電商系統中,需要根據商品的單價和數量計算商品的總價。可以創建一個函數來實現這個功能。
-- 創建計算商品總價的函數
DELIMITER //
CREATE FUNCTION CalculateTotalPrice(unit_price DECIMAL(10, 2), quantity INT)
RETURNS DECIMAL(10, 2)
DETERMINISTIC
BEGINDECLARE total_price DECIMAL(10, 2);SET total_price = unit_price * quantity;RETURN total_price;
END //
DELIMITER ;-- 假設存在 products 表,包含 unit_price 和 quantity 列
SELECT product_id, CalculateTotalPrice(unit_price, quantity) AS total_price
FROM products;
13.3 存儲過程和函數的管理
- 查看存儲過程和函數:可以使用?
SHOW PROCEDURE STATUS
?和?SHOW FUNCTION STATUS
?語句查看數據庫中所有的存儲過程和函數。
SHOW PROCEDURE STATUS WHERE Db = 'your_database_name';
SHOW FUNCTION STATUS WHERE Db = 'your_database_name';
- 查看存儲過程和函數的定義:使用?
SHOW CREATE PROCEDURE
?和?SHOW CREATE FUNCTION
?語句查看存儲過程和函數的具體定義。SHOW CREATE PROCEDURE UpdateUserBalance; SHOW CREATE FUNCTION AddNumbers;
- 刪除存儲過程和函數:使用?
DROP PROCEDURE
?和?DROP FUNCTION
?語句刪除存儲過程和函數。DROP PROCEDURE IF EXISTS UpdateUserBalance; DROP FUNCTION IF EXISTS AddNumbers;
十四、觸發器
14.1 觸發器的概念
觸發器是與表相關聯的特殊存儲過程,當表上發生特定事件(如?
INSERT
、UPDATE
、DELETE
)時自動執行。14.2 創建觸發器
-- 創建一個觸發器,在插入新用戶時記錄日志
DELIMITER //
CREATE TRIGGER LogNewUserInsert
AFTER INSERT ON users
FOR EACH ROW
BEGININSERT INTO user_logs (action, user_id, log_time)VALUES ('INSERT', NEW.id, NOW());
END //
DELIMITER ;
代碼解釋
AFTER INSERT ON users
?表示在?users
?表插入新記錄后觸發。FOR EACH ROW
?表示對每一行受影響的記錄都執行觸發器中的 SQL 語句。NEW
?關鍵字用于引用插入的新記錄,這里通過?NEW.id
?獲取新用戶的 ID。
14.3 觸發器的類型
- BEFORE 觸發器:在事件執行之前執行,可用于數據驗證和修改。
-- 創建一個 BEFORE INSERT 觸發器,驗證用戶年齡是否合法
DELIMITER //
CREATE TRIGGER ValidateUserAge
BEFORE INSERT ON users
FOR EACH ROW
BEGINIF NEW.age < 0 THENSIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '年齡不能為負數';END IF;
END //
DELIMITER ;
- AFTER 觸發器:在事件執行之后執行,可用于記錄日志、更新關聯數據等。前面的?
LogNewUserInsert
?就是一個?AFTER
?觸發器的例子。
14.4 刪除觸發器
DROP TRIGGER IF EXISTS LogNewUserInsert;
實戰場景
在一個庫存管理系統中,當有商品出庫時,需要自動更新庫存數量。可以創建一個觸發器來實現這個功能。
-- 創建商品表和出庫記錄表
CREATE TABLE products (product_id INT AUTO_INCREMENT PRIMARY KEY,product_name VARCHAR(100),stock INT
);CREATE TABLE product_outbound (outbound_id INT AUTO_INCREMENT PRIMARY KEY,product_id INT,quantity INT,outbound_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,FOREIGN KEY (product_id) REFERENCES products(product_id)
);-- 創建觸發器,在商品出庫時更新庫存數量
DELIMITER //
CREATE TRIGGER UpdateStockOnOutbound
AFTER INSERT ON product_outbound
FOR EACH ROW
BEGINUPDATE productsSET stock = stock - NEW.quantityWHERE product_id = NEW.product_id;
END //
DELIMITER ;
十五、窗口函數
15.1 窗口函數的概念
窗口函數是對一組行進行計算,并為每行返回一個結果。它不會像聚合函數那樣將多行數據合并為一行,而是在每行數據旁邊返回計算結果。
15.2 窗口函數的語法
function_name(expression) OVER (window_specification)
其中?function_name
?是具體的窗口函數(如?SUM
、AVG
、RANK
?等),expression
?是要計算的表達式,window_specification
?定義了窗口的范圍和排序規則。
15.3 常見窗口函數及示例
RANK()
:為每行數據分配一個排名,如果有相同的值,排名會重復,下一個排名會跳過相應的數量。-- 假設存在 sales 表,包含 product_id 和 sales_amount 列 SELECT product_id,sales_amount,RANK() OVER (ORDER BY sales_amount DESC) AS sales_rank FROM sales;
DENSE_RANK()
:與?RANK()
?類似,但排名不會跳過,即使有相同的值。SELECT product_id,sales_amount,DENSE_RANK() OVER (ORDER BY sales_amount DESC) AS sales_rank FROM sales;
ROW_NUMBER()
:為每行數據分配一個唯一的行號,按照指定的排序規則依次遞增。SELECT product_id,sales_amount,ROW_NUMBER() OVER (ORDER BY sales_amount DESC) AS row_num FROM sales;
SUM()
?作為窗口函數:計算窗口內的累計總和。SELECT product_id,sales_amount,SUM(sales_amount) OVER (ORDER BY product_id) AS cumulative_sum FROM sales;
實戰場景
在一個銷售數據分析系統中,需要統計每個月的銷售排名和累計銷售額。
-- 創建 sales 表 CREATE TABLE sales (sale_id INT AUTO_INCREMENT PRIMARY KEY,product_id INT,sale_date DATE,sale_amount DECIMAL(10, 2) );-- 插入示例數據 INSERT INTO sales (product_id, sale_date, sale_amount) VALUES (1, '2024-01-01', 100), (2, '2024-01-02', 200), (1, '2024-02-01', 150), (2, '2024-02-02', 250);-- 查詢每個月的銷售排名和累計銷售額 SELECT sale_date,product_id,sale_amount,RANK() OVER (PARTITION BY MONTH(sale_date) ORDER BY sale_amount DESC) AS monthly_rank,SUM(sale_amount) OVER (PARTITION BY MONTH(sale_date) ORDER BY sale_date) AS cumulative_monthly_sales FROM sales;
十六、公用表表達式(CTE)
16.1 CTE 的概念
?公用表表達式是一個臨時命名的結果集,它只在當前查詢的執行范圍內有效。CTE 可以簡化復雜查詢,提高代碼的可讀性和可維護性。
16.2 創建和使用 CTE
-- 定義一個 CTE,計算每個部門的平均工資 WITH department_avg_salary AS (SELECT department_id,AVG(salary) AS avg_salaryFROM employeesGROUP BY department_id ) -- 主查詢,查詢工資高于所在部門平均工資的員工 SELECT e.employee_id,e.department_id,e.salary FROM employees e JOIN department_avg_salary das ON e.department_id = das.department_id WHERE e.salary > das.avg_salary;
實戰場景
在一個人力資源管理系統中,需要查詢每個部門中工資最高的員工信息。可以使用 CTE 來實現這個功能。
-- 創建 employees 表 CREATE TABLE employees (employee_id INT AUTO_INCREMENT PRIMARY KEY,department_id INT,employee_name VARCHAR(100),salary DECIMAL(10, 2) );-- 插入示例數據 INSERT INTO employees (department_id, employee_name, salary) VALUES (1, 'Alice', 5000), (1, 'Bob', 6000), (2, 'Charlie', 4500), (2, 'David', 5500);-- 使用 CTE 查詢每個部門中工資最高的員工信息 WITH department_max_salary AS (SELECT department_id,MAX(salary) AS max_salaryFROM employeesGROUP BY department_id ) SELECT e.employee_id,e.department_id,e.employee_name,e.salary FROM employees e JOIN department_max_salary dms ON e.department_id = dms.department_id AND e.salary = dms.max_salary;
十七、分區表
17.1 分區表的概念
?分區表是將一個大表按照一定的規則(如范圍、列表、哈希等)劃分為多個小的分區,每個分區可以單獨進行管理和維護。分區表可以提高查詢性能、方便數據管理和維護。
17.2 分區類型及示例
- 范圍分區(RANGE):按照列值的范圍進行分區。
-- 創建按訂單日期范圍分區的訂單表 CREATE TABLE orders (order_id INT AUTO_INCREMENT PRIMARY KEY,order_date DATE,order_amount DECIMAL(10, 2) ) PARTITION BY RANGE (YEAR(order_date)) (PARTITION p2023 VALUES LESS THAN (2024),PARTITION p2024 VALUES LESS THAN (2025),PARTITION p2025 VALUES LESS THAN MAXVALUE );
- 列表分區(LIST):按照列值的列表進行分區
-- 創建按地區列表分區的用戶表
CREATE TABLE users (user_id INT AUTO_INCREMENT PRIMARY KEY,user_name VARCHAR(100),region VARCHAR(50)
)
PARTITION BY LIST COLUMNS (region) (PARTITION p_north VALUES IN ('North', 'Northeast'),PARTITION p_south VALUES IN ('South', 'Southeast'),PARTITION p_west VALUES IN ('West', 'Northwest')
);
- 哈希分區(HASH):根據列值的哈希值進行分區。
-- 創建按用戶 ID 哈希分區的用戶表 CREATE TABLE users (user_id INT AUTO_INCREMENT PRIMARY KEY,user_name VARCHAR(100) ) PARTITION BY HASH(user_id) PARTITIONS 4;
- 鍵分區(KEY):類似于哈希分區,但使用 MySQL 內部的哈希函數。
-- 創建按用戶 ID 鍵分區的用戶表 CREATE TABLE users (user_id INT AUTO_INCREMENT PRIMARY KEY,user_name VARCHAR(100) ) PARTITION BY KEY(user_id) PARTITIONS 4;
實戰場景
在一個電商系統中,訂單表的數據量非常大。為了提高查詢性能,可以按訂單日期進行范圍分區。
-- 創建按訂單日期范圍分區的訂單表 CREATE TABLE orders (order_id INT AUTO_INCREMENT PRIMARY KEY,order_date DATE,order_amount DECIMAL(10, 2) ) PARTITION BY RANGE (YEAR(order_date)) (PARTITION p2023 VALUES LESS THAN (2024),PARTITION p2024 VALUES LESS THAN (2025),PARTITION p2025 VALUES LESS THAN MAXVALUE );-- 插入示例數據 INSERT INTO orders (order_date, order_amount) VALUES ('2023-01-01', 100), ('2024-02-02', 200), ('2025-03-03', 300);-- 查詢 2024 年的訂單信息,MySQL 會只在 p2024 分區中查找 SELECT * FROM orders WHERE YEAR(order_date) = 2024;
十八、總結
MySQL 8.4 提供了豐富的 SQL 功能,涵蓋了數據庫操作、表操作、數據操作、查詢優化、事務處理等多個方面。通過合理運用這些功能,可以構建高效、穩定、安全的數據庫應用系統。在實際項目中,需要根據具體的業務需求選擇合適的 SQL 語句和數據庫特性,同時要注意數據的安全性和性能優化。希望本文能夠幫助讀者全面掌握 MySQL 8.4 的 SQL 知識,并在實際工作中靈活運用。