Apache Derby Bài 28: Tạo và quản lý View để trừu tượng hóa dữ liệu
1. View (Bảng ảo) là gì?
Trong các bài trước, chúng ta đã làm việc với Bảng vật lý (Base Table) – nơi dữ liệu thực sự được ghi xuống ổ đĩa. Tuy nhiên, khi hệ thống cơ sở dữ liệu lớn lên, việc truy vấn trực tiếp các bảng vật lý bộc lộ hai vấn đề lớn:
-
Bảo mật: Bạn muốn cho nhân viên phân tích xem bảng
nhan_vien, nhưng không muốn họ nhìn thấy cộtluong(lương). -
Sự phức tạp: Một báo cáo doanh thu yêu cầu
JOINtới 5 bảng khác nhau. Việc lập trình viên phải viết đi viết lại câu lệnhJOINdài 30 dòng ở nhiều nơi rất dễ gây lỗi.
View (Khung nhìn / Bảng ảo) ra đời để giải quyết bài toán này. View thực chất là một câu lệnh SELECT được lưu lại trong cơ sở dữ liệu dưới dạng một đối tượng có tên. Khi bạn truy vấn một View, Derby sẽ ngầm định chạy câu lệnh SELECT bên dưới và trả về tập kết quả như thể nó là một bảng thật.
2. Cú pháp khởi tạo View
Cú pháp tạo View rất đơn giản, theo chuẩn ANSI SQL:
SQL
CREATE VIEW ten_view AS
SELECT cot1, cot2...
FROM ten_bang
WHERE dieu_kien;
3. Ứng dụng 1: Trừu tượng hóa và Bảo mật dữ liệu
Giả sử chúng ta có bảng nhan_vien(id, ho_ten, email, so_dien_thoai, luong, mat_khau). Chúng ta muốn cấp quyền cho bộ phận Hành chính nhân sự xem danh bạ liên lạc, nhưng tuyệt đối che giấu mức lương và mật khẩu.
Thay vì phân quyền phức tạp trên từng cột, ta tạo một View chỉ chứa các thông tin công khai:
SQL
CREATE VIEW view_danh_ba_nhan_vien AS
SELECT id, ho_ten, email, so_dien_thoai
FROM nhan_vien
WHERE trang_thai_lam_viec = 'DANG_LAM';
Lúc này, trong mã nguồn Java hoặc công cụ quản trị, người dùng chỉ cần gõ:
SQL
SELECT * FROM view_danh_ba_nhan_vien;
Derby sẽ tự động lọc bỏ các nhân viên đã nghỉ việc và ẩn hoàn toàn cột lương. Bảng vật lý gốc được bảo vệ an toàn phía sau bức màn trừu tượng.
4. Ứng dụng 2: Đơn giản hóa các truy vấn phức tạp
Hãy tưởng tượng bạn có 3 bảng: don_hang, khach_hang, và chi_tiet_don. Để lấy hóa đơn in cho khách, bạn phải viết câu lệnh JOIN phức tạp:
SQL
SELECT
d.ma_don,
k.ten_khach_hang,
d.ngay_tao,
c.ten_san_pham,
c.so_luong,
(c.so_luong * c.don_gia) AS thanh_tien
FROM don_hang d
INNER JOIN khach_hang k ON d.ma_khach = k.ma_khach
INNER JOIN chi_tiet_don c ON d.ma_don = c.ma_don;
Thay vì bắt lập trình viên Java copy-paste đoạn mã dài dòng này, DB Admin sẽ gói nó vào một View:
SQL
CREATE VIEW view_hoa_don_chi_tiet AS
SELECT
d.ma_don,
k.ten_khach_hang,
d.ngay_tao,
c.ten_san_pham,
c.so_luong,
(c.so_luong * c.don_gia) AS thanh_tien
FROM don_hang d
INNER JOIN khach_hang k ON d.ma_khach = k.ma_khach
INNER JOIN chi_tiet_don c ON d.ma_don = c.ma_don;
Trong Java, bạn chỉ cần một lệnh SQL duy nhất, vô cùng sạch sẽ và dễ bảo trì:
Java
String sql = "SELECT * FROM view_hoa_don_chi_tiet WHERE ma_don = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
5. Cập nhật dữ liệu qua View (Updatable Views)
Mặc định, View thường được dùng để ĐỌC (SELECT). Tuy nhiên, Apache Derby cho phép bạn dùng lệnh INSERT, UPDATE, DELETE trực tiếp trên một View (dữ liệu sẽ được đẩy ngược về bảng vật lý) NẾU VÀ CHỈ NẾU View đó thỏa mãn các điều kiện cực kỳ khắt khe:
-
View chỉ truy vấn từ duy nhất một bảng vật lý (Không có
JOIN). -
Không sử dụng các hàm tổng hợp (
SUM,COUNT,MAX...). -
Không sử dụng
GROUP BY,HAVING, hoặcDISTINCT. -
Không chứa biểu thức tính toán (như cột
thanh_tien=so_luong * don_giaở trên).
Best Practice: Trong kiến trúc phần mềm hiện đại, người ta hiếm khi cập nhật dữ liệu qua View để tránh các hiệu ứng phụ (side effects). Hãy luôn giữ nguyên tắc: Đọc dữ liệu qua View, Ghi dữ liệu trực tiếp vào Bảng vật lý (hoặc qua Stored Procedure).
6. Sửa đổi và Xóa View
Nếu cấu trúc bảng gốc thay đổi (ví dụ: đổi tên cột), View sẽ bị lỗi (invalid). Apache Derby không hỗ trợ lệnh ALTER VIEW. Để sửa đổi một View, bạn bắt buộc phải xóa nó đi và tạo lại.
Cú pháp xóa View:
SQL
DROP VIEW ten_view;
Lưu ý: Việc xóa View (
DROP VIEW) không bao giờ làm mất dữ liệu, vì View chỉ là một câu lệnh được lưu lại, không chứa dữ liệu thật. Tuy nhiên, nếu bạn xóa bảng vật lý (DROP TABLE), tất cả các View phụ thuộc vào bảng đó cũng sẽ bị hỏng.
7. Tổng kết
-
View (Bảng ảo) là công cụ đắc lực để ẩn giấu độ phức tạp của lược đồ cơ sở dữ liệu và tăng cường bảo mật.
-
Sử dụng View giúp mã nguồn SQL trong ứng dụng (Java/Web) ngắn gọn, tập trung logic tính toán tại tầng Database thay vì tầng Application.
-
Tránh lạm dụng View lồng View (View này truy vấn từ một View khác) vì sẽ làm trình tối ưu hóa (Optimizer) của Derby bối rối, gây suy giảm hiệu năng nghiêm trọng.
Ở bài tiếp theo, chúng ta sẽ giải quyết một bài toán vô cùng quen thuộc: làm sao để cột ID tự động tăng mỗi khi có dữ liệu mới được chèn vào: Apache Derby Bài 29: Sử dụng Sequence và cột tự tăng (IDENTITY / GENERATED ALWAYS AS IDENTITY).
All rights reserved