Database View không chỉ là khái niệm riêng của SQL Server hay MySQL mà nó là khái niệm chung của tất cả những loại cơ sở dữ liệu quan hệ RDBMS (MySQL, SQL Server, Oracle, PostgreSQL...)
Với bài viết này, chúng ta sẽ cùng thảo luận về khái niệm tư tưởng chung của view và cách sử dụng view trong oracle
Database View là sự trình bày data theo ý muốn được trích xuất từ một hoặc nhiều table/view khác. View không lưu data nên nó còn được biết đến với cái tên "bảng ảo(virtual tables)".
Bạn có thể thao tác select, insert, update và delete với view giống như table bình thường. Vì không lưu data nên tất cả những thao tác được thực hiện trên view thì đều được phản ánh đến base table mà được trích xuất dữ liệu.
SQL Statement trong bài viết này sẽ sử dụng SQL SERVER 2019 để demo source
CREATE [OR ALTER ] VIEW [ schema_name. ] view_name AS
select_statement
[WITH CHECK OPTION]
[;]
Chúng ta hãy thử tạo view với tiền đề có 2 table Employee và Department như Figure 1:
CREATE VIEW employee_with_department_view AS
SELECT E.EmployeeNo, E.EmployeeName, D.DepartmentName
FROM Employee E
INNER JOIN Department D ON E.DepartmentNo = D.DepartmentNo
Thực hiện truy xuất dữ liệu qua view bằng câu lệch SELECT, và ta thu được kết quả như table 01
SELECT
EmployeeNo, EmployeeName, DepartmentName
FROM
employee_with_department_view
Table 01: employee_with_department_view | ||||
---|---|---|---|---|
EmployeeNo | EmployeeName | DepartmentName | ||
1 | Adam | Sale | ||
2 | Susan | Marketing | ||
3 | John | IT |
Tạo view truy xuất EmployeeNo, EmployeeName, DepartmentNo của những nhân viên thuộc Department 1 trong table Employee với WITH CHECK OPTION
CREATE VIEW employee_view AS
SELECT E.EmployeeNo, E.EmployeeName, E.DepartmentNo
FROM Employee E
WHERE E.DepartmentNo = 1
WITH CHECK OPTION;
Dùng CHECK OPTION
khi chúng ta muốn tạo ràng buộc cho việc INSERT/UPDATE data thông qua view. Chỉ những record thỏa mãn điều kiện trong câu lệch SELECT khi tạo index mới được INSERT/UPDATE.
Cụ thể trong trường hợp này là record cần thỏa mãn điều kiện WHERE E.DepartmentNo = 1
Với employee_view vừa tạo khi chúng ta execute Statement_01 sẽ thành công và ngược lại Statement_02 sẽ thất bại
-- Statement_01: Success
INSERT INTO employee_view(EmployeeName, DepartmentNo) VALUES ('Selena', 1)
-- Statement_02: The attempted insert or update failed because the target view either specifies WITH CHECK OPTION ...
INSERT INTO employee_view(EmployeeName, DepartmentNo) VALUES ('Peter', 2)
Mặc định view được tạo ra đều có thể thao tác thay đổi data(UPDATE/DELETE/INSERT), tuy nhiên cần thỏa mãn các điều sau
Đôi khi chúng ta muốn disable việc update data thông qua view, ngoài cách deny UPDATE/DELETE/INSERT permissions với view thì ta có thể khiến cho việc update data qua view luôn vi phạm 1 trong những điều kiện được mô tả trong 2.1.3
CREATE VIEW employee_view_read_only AS
SELECT E.EmployeeNo, E.EmployeeName, E.DepartmentNo
FROM Employee E
UNION ALL
SELECT NULL, NULL, NULL
Chúng ta sẽ gặp lỗi khi cố thực hiện Statement_03
-- Statement_03: Update or insert of view or function 'employee_view_read_only' failed because it contains a derived or constant field.
INSERT INTO employee_view_read_only(EmployeeName, DepartmentNo) VALUES ('David', 2)
Để drop view hãy chắc chắn rằng bạn đang sử dụng user có quyển drop view tại schema mong muốn. Tất nhiên việc drop view sẽ không gây ảnh hưởng đến data của base table
DROP VIEW view_name
Khi base table bị thay đổi (alter/drop) có thể gây ảnh hưởng đến view, hoặc khi ta muốn thay đổi cấu trúc của view thì có thể dùng ALTER VIEW
Có 2 cách để thay đổi cấu trúc của view:
Ví dụ thay đổi view employee_view
bên trên, loại bỏ DepartmentNo khỏi danh sách column muốn lấy.
CREATE OR ALTER VIEW employee_view AS
SELECT E.EmployeeNo, E.EmployeeName
FROM Employee E
WHERE E.DepartmentNo = 1
WITH CHECK OPTION;
Note: Một số lại RDBMS khác có thể syntax sẽ khác nhau tuy nhiên ý nghĩa đều như vậy, ví dụ Oracle sẽ là CREATE OR REPLACE VIEW
Trong trường hợp cần truy xuất dữ liệu từ nhiều table với logic phức tạp. Lúc này ta có thể tạo view với logic tương tự và thông qua view chúng ta sẽ chỉ cần sử dụng những câu query đơn giản để truy xuất dữ liệu.
Đôi khi ta không muốn những dữ liệu nhạy cảm được truy cập bởi nhóm user nào đó. View có thể giúp ta giới hạn row/column của những table theo điều kiện ta muốn lấy.
Có những dữ liệu mà một nhóm người dùng có thể truy cập nhưng lại không muốn họ có thể thao tác thay đổi. Option VIEW READ ONLY sẽ giải quyết được vấn đề này.
Giả sử rằng bạn có một database đang được chạy tại môi trường production. Nhưng lại đang tồn tại 1 table Employee với cấu trúc không được tốt như sau:
Employee_Information(EmployeeNo (PK), EmployeeName, Salary, DepartmentNo, DepartmentName, DepartmentDescription)
Sau 1 thời gian dùng Employee số lượng tăng nhiều records nhưng số lượng department thì không nhiều, vài khi thay đổi thông tin Department thì lại phải thay đổi toàn bộ thông tin Employee của Department đó. Để nhất quán và tránh việc dư thừa dữ liệu lúc này bạn quyết định tạo 2 tables mới.
Employee(EmployeeNo (PK), EmployeeName, Salary, DepartmentNo (FK))
Department(DepartmentNo (PK), DepartmentName, DepartmentDescription)
Tuy nhiên nếu xóa table Employee_Information ngay sẽ gây ảnh hưởng đến chức năng đang chạy hiện tại. Hãy import data vào 2 tables mới sau đó tạo 1 view có name và cấu trúc với table Employee_Information, lúc này các phần SELECT vẫn sẽ hoạt động bình thường, ta cần đi điều tra những phần UPDATE/INSERT/DELETE để cập nhật.
Performance
Vì bản chất không lưu dữ liệu nên tất cả những thao tác được thực hiện trên view thì đều được phản ánh đến base table. Do đó query processor phải translate view thành query đến base table nên hiệu năng truy xuất dữ liệu có thẻ giảm nếu view phức tạp được tạo từ nhiều table hoặc view được tạo từ view khác
Mỗi khi base table có sự thay đổi cấu trúc điều đó có thể khiến view trở thành invalid
Trên đây là kiến thức cơ bản về VIEW trong RDBMS. Hi vọng rằng sau bài viết này các bạn sẽ thực sự hiểu và sẽ có những sự lựa chọn đúng đắn khi dùng VIEW.