Bài 11: View, Index và Trigger – Tối ưu và Tự động hóa
I. Mục đích (Objectives)
Sau bài học này, người đọc sẽ:
- Hiểu View là gì và cách dùng nó để đóng gói các câu lệnh SELECT phức tạp (tạo “Bảng ảo”).
- Nắm được khái niệm Index (Chỉ mục) để tăng tốc độ tìm kiếm dữ liệu lên gấp hàng trăm lần.
- Biết cách sử dụng Trigger để tự động thực thi logic khi dữ liệu thay đổi (ví dụ: Tự động lưu lịch sử tác động).
II. Yêu cầu (Prerequisites)
- Đã nắm vững SELECT và JOIN (kết quả từ Bài 9: Truy vấn nhiều bảng (JOINs) – Sức mạnh của sự liên kết).
III. Nội dung chi tiết (Detailed Content)
1. View (Khung nhìn) – Chiếc kính lúp thông minh
Vấn đề: Ở Bài 9, để lấy danh sách đầy đủ (Tên HS + Tên Lớp), ta phải viết câu lệnh JOIN khá dài. Nếu ngày nào sếp cũng đòi báo cáo này, việc gõ lại câu lệnh đó rất mất công và dễ sai.
Giải pháp: Tạo một View. Hãy tưởng tượng View giống như việc bạn “Lưu kết quả tìm kiếm” lại thành một bảng ảo.
Cú pháp:
CREATE VIEW Ten_View AS
Cau_Lenh_Select_Phuc_Tap;
Thực hành: Tạo View danh sách chi tiết.
CREATE VIEW View_HocSinh_DayDu AS
SELECT
h.id,
h.ho_ten,
h.diem_tb,
l.ten_lop
FROM HocSinh h
JOIN LopHoc l ON h.ma_lop_id = l.id_lop;
Cách sử dụng: Sau khi tạo xong, từ nay về sau bạn coi View_HocSinh_DayDu như một bảng bình thường.
-- Lấy dữ liệu cực nhanh gọn, không cần nhớ JOIN nữa
SELECT * FROM View_HocSinh_DayDu WHERE diem_tb >= 8.0;
2. Index (Chỉ mục) – Tăng tốc tìm kiếm
Khái niệm: Hãy tưởng tượng cuốn từ điển dày 1000 trang.
- Không có Index (Full Table Scan): Bạn muốn tìm từ “SQLite”, bạn phải lật từng trang từ trang 1 đến trang 1000 để tìm. Rất chậm!
- Có Index: Bạn lật ra mục lục phía sau, tìm chữ “S”, máy sẽ chỉ ngay cho bạn đến trang 800. Rất nhanh!
Trong Database, khi dữ liệu lên tới hàng chục ngàn dòng, việc tìm kiếm theo Tên hoặc Số điện thoại sẽ rất chậm nếu không có Index.
Cú pháp:
CREATE INDEX idx_ten_chi_muc ON Ten_Bang(ten_cot);
Thực hành: Tạo chỉ mục cho cột ho_ten để tìm kiếm tên nhanh hơn.
CREATE INDEX idx_hocsinh_hoten ON HocSinh(ho_ten);
Lưu ý kỹ thuật (Quan trọng cho môn Công nghệ phần mềm (CNPM)):
- Tại sao không đánh Index cho tất cả các cột?
- Vì Index cũng chiếm dung lượng bộ nhớ. Và khi bạn INSERT/UPDATE, máy phải cập nhật cả bảng chính lẫn bảng Index -> Làm chậm tốc độ ghi.
- Quy tắc: Chỉ đánh Index cho các cột thường xuyên dùng để tìm kiếm (WHERE) hoặc sắp xếp (ORDER BY).
3. Trigger (Bẫy sự kiện) – Tự động hóa nghiệp vụ
Khái niệm: Trigger là đoạn code sẽ tự động chạy khi một sự kiện (INSERT, UPDATE, DELETE) xảy ra trên bảng.
Bài toán thực tế: Giám hiệu yêu cầu: “Bất cứ khi nào có ai sửa điểm của học sinh, hệ thống phải tự động ghi lại ‘bằng chứng’ (Log) để sau này đối chiếu”.
Bước 1: Tạo bảng lưu lịch sử (Audit Log)
CREATE TABLE Log_ThayDoiDiem (
id INTEGER PRIMARY KEY,
id_hoc_sinh INTEGER,
diem_cu REAL,
diem_moi REAL,
thoi_gian TEXT
);
Bước 2: Tạo Trigger theo dõi việc sửa điểm
CREATE TRIGGER TheoDoi_SuaDiem
AFTER UPDATE OF diem_tb ON HocSinh -- Chỉ chạy khi cột diem_tb bị sửa
BEGIN
INSERT INTO Log_ThayDoiDiem (id_hoc_sinh, diem_cu, diem_moi, thoi_gian)
VALUES (OLD.id, OLD.diem_tb, NEW.diem_tb, DATETIME('now'));
END;
- OLD.diem_tb: Lấy giá trị cũ trước khi sửa.
- NEW.diem_tb: Lấy giá trị mới sau khi sửa.
- DATETIME(‘now’): Lấy thời gian hiện tại.
Kiểm thử: Bây giờ bạn thử sửa điểm của một em học sinh xem. Sau đó mở bảng Log_ThayDoiDiem ra, bạn sẽ thấy một dòng dữ liệu mới tự động xuất hiện!
IV. Tổng kết (Summary)
Chúng ta vừa trang bị những vũ khí hiện đại nhất cho hệ thống:
- View: Giúp code gọn gàng, che giấu sự phức tạp.
- Index: Tối ưu hóa tốc độ truy vấn (Performance Tuning).
- Trigger: Tự động hóa quy trình giám sát dữ liệu.
Đến đây, phần kiến thức về Cơ sở dữ liệu SQLite thuần túy đã hoàn tất. Nhưng một Database đứng một mình thì vô nghĩa. Nó cần được kết nối với phần mềm để người dùng sử dụng.
Ở giai đoạn cuối cùng (Giai đoạn 4), chúng ta sẽ bước vào thế giới lập trình ứng dụng. Hẹn gặp lại các bạn trong Bài 12: Kết nối SQLite với Python – Bước đầu xây dựng ứng dụng.
