-
Giới thiệu và khởi tạo môi trường MySQL
- Hướng dẫn cài đặt và cấu hình MySQL Server trên Windows cho kết nối từ xa
- Vận dụng tư duy phân tích dữ liệu với Mysql từ cơ bản đến nâng cao
- Vận dụng tư duy phân tích quản trị dữ liệu với MySQL
- Tối ưu hoá công việc quản trị với view và bảng tạm
- Tôi ưu hoá với thủ tục – procedure trong mysql
- Nhóm hàm windown
- Con trỏ và phân vùng trong mysql
- Làm việc với hàm tự tạo trong Mysql
- Làm việc với trigger trong Mysql
- Làm việc với giao dịch
- Tìm hiểu về truy vấn động
- Even – Sự kiện định kỳ trong Mysql
-
Quản trị dữ liệu trong doanh nghiệp
- Tổng quan về trục quản trị dữ liệu
- Quản trị & Giám sát hệ thống với cơ sở dữ liệu ảo information_schema
- Cấu hình và lưu trữ
- Cấu hình file my.ini
- An toàn và toàn vẹn dữ liệu – Bảo mật – Backup
- Hiệu năng và tối ưu hoá
- Đồng bộ và phục hồi
- Phân tích tối ưu hoá hiệu năng với dữ liệu bảng performance_schema
-
Chiến lược quản trị dữ liệu
Con trỏ và phân vùng trong mysql
- Cursor (con trỏ) giúp duyệt từng dòng dữ liệu để xử lý phức tạp trong thủ tục và giao dịch.
- Partition (phân vùng) giúp quản lý dữ liệu lớn hiệu quả trong lưu trữ và tối ưu hệ thống.
Ta cùng đi từng phần một, kèm ví dụ nghiệp vụ Kho bạc Nhà nước, để cô có thể đưa trực tiếp vào giáo trình.
🧭 I. CON TRỎ (CURSOR) TRONG MYSQL
1️⃣ Khái niệm
- Cursor (con trỏ) là vùng nhớ tạm trong thủ tục (stored procedure) cho phép duyệt từng bản ghi trong tập kết quả của một truy vấn.
- Cursor giống như “ngón tay chỉ” qua từng dòng của bảng dữ liệu để xử lý logic phức tạp mà lệnh SQL đơn không thực hiện được.
👉 MySQL chỉ hỗ trợ read-only, non-scrollable cursor (nghĩa là đọc tuần tự, không quay lại dòng trước).
2️⃣ Cấu trúc hoạt động của Cursor
Một con trỏ trong MySQL có 4 bước chính:
| Bước | Câu lệnh | Chức năng |
|---|---|---|
| 1 | DECLARE cursor_name CURSOR FOR SELECT... |
Khai báo con trỏ |
| 2 | OPEN cursor_name; |
Mở con trỏ |
| 3 | FETCH cursor_name INTO variable_list; |
Lấy từng dòng dữ liệu |
| 4 | CLOSE cursor_name; |
Đóng con trỏ, giải phóng bộ nhớ |
3️⃣ Ví dụ minh hoạ: Cập nhật phí giao dịch hàng loạt
Tình huống thực tế Kho bạc:
Hàng ngày cần duyệt qua từng giao dịch để tính và cập nhật phí dựa theo loại nghiệp vụ (chuyển khoản, thu ngân sách, hoàn thu…).
🔧 Tạo dữ liệu mẫu:
CREATE TABLE giao_dich (
id INT AUTO_INCREMENT PRIMARY KEY,
so_tk VARCHAR(20),
loai_giao_dich VARCHAR(50),
so_tien DECIMAL(18,2),
phi DECIMAL(18,2)
);
INSERT INTO giao_dich (so_tk, loai_giao_dich, so_tien)
VALUES
('KB001','Chuyển khoản',2000000),
('KB002','Thu ngân sách',10000000),
('KB003','Rút tiền',3000000);
🧮 Thủ tục sử dụng CURSOR:
DELIMITER //
CREATE PROCEDURE cap_nhat_phi()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE p_id INT;
DECLARE p_loai VARCHAR(50);
DECLARE p_so_tien DECIMAL(18,2);
DECLARE cur CURSOR FOR
SELECT id, loai_giao_dich, so_tien FROM giao_dich;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO p_id, p_loai, p_so_tien;
IF done THEN
LEAVE read_loop;
END IF;
IF p_loai = 'Chuyển khoản' THEN
UPDATE giao_dich SET phi = p_so_tien * 0.005 WHERE id = p_id;
ELSEIF p_loai = 'Rút tiền' THEN
UPDATE giao_dich SET phi = p_so_tien * 0.01 WHERE id = p_id;
ELSE
UPDATE giao_dich SET phi = 0 WHERE id = p_id;
END IF;
END LOOP;
CLOSE cur;
END //
DELIMITER ;
Gọi thử:
CALL cap_nhat_phi();
SELECT * FROM giao_dich;
👉 Ứng dụng thực tế:
- Duyệt kiểm tra chênh lệch dữ liệu.
- Ghi log lỗi dòng theo điều kiện đặc biệt.
- Tự động hiệu chỉnh dữ liệu định kỳ.
🧩 II. PHÂN VÙNG (PARTITION) TRONG MYSQL
1️⃣ Khái niệm
- Partition (phân vùng) là cách chia logic một bảng lớn thành nhiều phần nhỏ hơn (partition), nhưng MySQL vẫn coi đó là một bảng duy nhất khi truy vấn.
- Mỗi partition có thể lưu ở file vật lý khác nhau, giúp:
- Truy xuất nhanh hơn (đọc ít dữ liệu hơn),
- Quản lý dễ hơn (xóa dữ liệu cũ theo phân vùng),
- Tối ưu backup và phục hồi.
2️⃣ Các kiểu phân vùng trong MySQL
| Kiểu Partition | Mô tả | Ví dụ |
|---|---|---|
| RANGE | Chia theo giá trị trong khoảng | Theo năm, tháng, ngày |
| LIST | Chia theo danh sách cụ thể | Mã chi nhánh |
| HASH | Chia ngẫu nhiên theo công thức | Sử dụng cho cân tải |
| KEY | Dựa vào khóa chính | Dành cho dữ liệu có ID lớn |
3️⃣ Ví dụ nghiệp vụ: Phân vùng bảng giao dịch theo năm
Tình huống thực tế Kho bạc:
Dữ liệu giao dịch từ năm 2019 đến 2025, cần chia partition theo năm để tối ưu truy vấn và backup.
🔧 Tạo bảng phân vùng:
CREATE TABLE giao_dich_partition (
id INT AUTO_INCREMENT PRIMARY KEY,
so_tk VARCHAR(20),
loai_giao_dich VARCHAR(50),
so_tien DECIMAL(18,2),
ngay_giao_dich DATE
)
PARTITION BY RANGE (YEAR(ngay_giao_dich)) (
PARTITION p2019 VALUES LESS THAN (2020),
PARTITION p2020 VALUES LESS THAN (2021),
PARTITION p2021 VALUES LESS THAN (2022),
PARTITION p2022 VALUES LESS THAN (2023),
PARTITION p2023 VALUES LESS THAN (2024),
PARTITION pmax VALUES LESS THAN MAXVALUE
);
👉 Khi chèn dữ liệu:
INSERT INTO giao_dich_partition VALUES
(NULL,'KB001','Chuyển khoản',2000000,'2022-05-10'),
(NULL,'KB002','Rút tiền',1500000,'2024-01-12');
MySQL tự động phân vào partition p2022 và p2023.
4️⃣ Kiểm tra thông tin phân vùng
SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 'giao_dich_partition';
5️⃣ Xóa hoặc thêm partition mới
ALTER TABLE giao_dich_partition
ADD PARTITION (PARTITION p2025 VALUES LESS THAN (2026));
6️⃣ Ứng dụng thực tế
| Nhiệm vụ Kho bạc | Cách áp dụng Partition |
|---|---|
| Dữ liệu giao dịch theo năm | RANGE (YEAR) |
| Dữ liệu theo đơn vị địa phương (KBNN) | LIST (Mã chi nhánh) |
| Cân bằng tải truy vấn | HASH (ID giao dịch) |
| Xóa dữ liệu cũ nhanh chóng | ALTER TABLE ... DROP PARTITION |
🧮 III. KẾT HỢP CON TRỎ + PHÂN VÙNG TRONG QUẢN TRỊ
Cô có thể kết hợp cả hai kỹ thuật để tự động quản lý dữ liệu lớn.
Ví dụ: Mỗi tháng, con trỏ duyệt qua từng partition → tính tổng, lưu log, xoá dữ liệu cũ.
⚙️ Mẫu thủ tục quản lý phân vùng:
DELIMITER //
CREATE PROCEDURE tong_hop_theo_partition()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE p_name VARCHAR(64);
DECLARE cur CURSOR FOR
SELECT PARTITION_NAME FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 'giao_dich_partition' AND PARTITION_NAME IS NOT NULL;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur;
read_loop: LOOP
FETCH cur INTO p_name;
IF done THEN LEAVE read_loop; END IF;
SET @sql = CONCAT('SELECT "', p_name, '" AS partition_name, SUM(so_tien) AS tong_tien FROM giao_dich_partition PARTITION(', p_name, ');');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cur;
END //
DELIMITER ;
👉 Gọi:
CALL tong_hop_theo_partition();
→ Cho phép tự động thống kê dữ liệu từng năm.
🧭 IV. TÓM TẮT & SO SÁNH
| Nội dung | Cursor | Partition |
|---|---|---|
| Mục đích | Xử lý từng dòng dữ liệu tuần tự | Quản lý dữ liệu lớn theo nhóm |
| Phạm vi | Trong thủ tục (procedural) | Trong cấu trúc bảng (structural) |
| Ứng dụng | Tự động hoá cập nhật, kiểm tra logic | Tối ưu lưu trữ, backup, phân tích |
| Hạn chế | Tốc độ chậm nếu duyệt lớn | Không hỗ trợ FULLTEXT, FK phức tạp |
| Công cụ hỗ trợ | Stored Procedure | Workbench, CLI, Information_Schema |
🏦 Ví dụ nghiệp vụ tổng hợp Kho bạc Nhà nước
Tình huống:
Mỗi quý, hệ thống Kho bạc phải:
- Duyệt qua từng partition theo năm.
- Tính tổng số giao dịch, tổng phí, và lưu kết quả.
- Ghi log bằng trigger khi phát hiện phân vùng vượt 2 triệu bản ghi.
→ Kết hợp:
Cursorđể duyệt phân vùng,Proceduređể tổng hợp dữ liệu,Triggerđể giám sát,Transactionđể rollback nếu lỗi tính toán.