Giới thiệu về View

Guess Post: Vũ Minh Tâm

Trong buổi SQL SERVER SEMINAR HÈ 2011 có một bài thảo luận về Indexed View. Để tiện cho các bạn theo dõi tôi sẽ giới thiệu sơ qua về khái niệm VIEW và một số kiến thức liên quan đến việc sử dụng VIEW.

Giới thiệu về View

View là một bảng ảo mà dữ liệu chứa trong nó được mô tả bởi một câu truy vấn.
Ví dụ về tạo 1 View đơn giản:

--Tạo một bảng gốc BaseTable và dữ liệu trong nó
CREATE TABLE BaseTable
(
	CustomerID VARCHAR(20),
	CustomerName VARCHAR(200),
	CustomerEmail VARCHAR(200),
	CustomerDOB DATETIME
);
 
INSERT INTO BaseTable(CustomerID, CustomerName, CustomerDOB)
SELECT 'MS001','Wayne Rooney','2005/05/05'
UNION ALL
SELECT 'MS002','Rio Ferdinand','2006/06/06'
UNION ALL
SELECT 'MS003','Ashley Young','2007/07/07'
UNION ALL
SELECT 'MS004','Nemanja Vidic','2008/08/08'
UNION ALL
SELECT 'MS005','De Gea','2009/09/09';
 
--Tạo một View có tên ViewBaseTable:
CREATE VIEW ViewBaseTable
AS
SELECT CustomerID, CustomerName, CustomerDOB
FROM BaseTable

ViewBaseTable đã được tạo ra, dữ liệu trong View này chính là kết quả trả về của câu truy vấn

SELECT CustomerID, CustomerName, CustomerDOB
FROM BaseTable

Về logic, ta có thể coi View như 1 bảng bình thường, tức là có thể truy vấn, thay đổi dữ liệu, tạo index trên các cột của View, v.v…
Về mặt vật lý, View KHÔNG chứa dữ liệu. Đúng như tên gọi của nó, View chỉ là một khung nhìn, cấu trúc của View trong CSDL chỉ là một câu lệnh SELECT tham chiếu đến các bảng khác.

Nhiều bạn cho rằng, sử dụng View thì truy vấn sẽ nhanh hơn. Thực chất không phải như vậy. Với ví dụ View ở trên:

SELECT * 
FROM ViewBaseTable

thì SQL Server xử lý nó cũng như

SELECT *
FROM   (
           SELECT CustomerID,
                  CustomerName,
                  CustomerDOB
           FROM   BaseTable
       ) DT

Điều này giải thích rất đơn giản. Vì View không chưa dữ liệu, nên khi làm việc với View, bắt buộc hệ thống phải thực hiện lại truy vấn tạo View.

Khi nào thì dùng View

  • Khi bạn muốn user chỉ có thể truy cập giới hạn một số lượng cột ( trong câu lệnh SELECT ), hoặc số lượng dòng (thêm WHERE để lọc điều kiện ) nhất định.
  • Khi một câu truy vấn phức tạp trong tương lai có thể phải sử dụng lại nhiều lần. Tạo View để lưu câu truy vấn. Trường hợp hay xảy ra nhất là các câu truy vấn tính toán, tổng hợp dữ liệu.
  • Không muốn user biết được tên bảng, cấu trúc thật sự của bảng.
  • Trong các hệ thống lớn, nhiều lúc chúng ta tưởng rằng mình đang SELECT trên một bảng X. Nhưng có thể, X chỉ là synonyms của View Y, mà Y lại tham chiếu lên nhiều bảng Z1, Z2, Z3, … khác nhau.

Các loại View

Trong thực tế các loại View mà ta gặp thường có dạng sau

  • Là 1 tập các cột trong 1 bảng (SELECT không đủ cột)
  • Là 1 tập các dòng trong 1 bảng (SELECT có mệnh đề WHERE)
  • Là 1 tập các dòng, các cột trong 1 bảng (Kết hợp của hai trường hợp trên)
  • Là 1 tập kết quả của các phép JOIN
  • Là 1 truy vấn tổng hợp, sử dụng các hàm trên một tập giá trị như SUM, COUNT, MIN, MAX, v.v…
  • Là tổng hợp của các trường hợp trên.

Ngoài cách phân loại trên, còn hai kiểu View đặc biệt mà ít người để ý đến. Đó là Updatable View và Partition View
Updatable View:
Như đã nói ở trên, View cũng có thể coi như là 1 bảng. Vì vậy có thể thực hiện các thao tác DML ( Insert, Update, Delete ) trên View. Và khi thay đổi dữ liệu trong View thì những bảng liên quan đến View dữ liệu cũng sẽ thay đổi theo.

Với ví dụ đã nói ở đầu bài.

DELETE FROM ViewBaseTable

Sau khi thực hiện câu lệnh này thì toàn bộ các rows trong BaseTable cũng bị xóa. Vì thế khi làm việc với View, các bạn nên để ý xem View của mình có phải Updatable View hay không. Nếu có thì nên GRANT quyền cho User chỉ được phép SELECT trên View để tránh trường hợp đáng tiếc.

View không phải là Updatable trong một số tình huống sau:

  • Trong View sử dụng các hàm như SUM, COUNT, MIN, MAX, v.v…
  • Sử dụng các mệnh đề UNION, UNION ALL, CROSSJOIN, INTERSECT, EXCEPT, v.v….

Chi tiết các bạn có thể tham khảo thêm trong MSDN

Partition View:
Nếu View có dạng sau thì được gọi là Partition View

SELECT <select_list1>
FROM T1
UNION ALL
SELECT <select_list2>
FROM T2
UNION ALL
...
SELECT <select_listn>
FROM Tn

Trong đó T1, T2,…Tn là các bảng có thể ở nhiều Server khác nhau.




Tags: , ,

25 Comments
Posted on 23/7/2011 | Categories: SQL Server Programming, Thiết kế database, View

Các bài viết tương tự

Comments
  • CuongIT (25/08/2011 1:26 pm)

    Bài viết khá hay. Thanks bạn nhiu` :)

  • HoangTung (06/09/2011 9:22 am)

    Dear All,

    Mình tạo 1 view ứng với các cột được sửa alias lại theo tên tiếng việt như sau:

    CREATE VIEW vwSalary 
    AS
    SELECT 
        A.EmpID		AS 'Mã nhân viên'
       ,A.EmpNm		AS 'Tên nhân viên'
       ,B.DeptNm		AS 'Phòng ban'
       ,A.Salary		AS 'Lương cơ bản'
       ,A.WorkingDays	AS 'Số ngày làm'
       ,A.Income		AS 'Thực lĩnh'
      FROM tblEmployee A
     INNER JOIN tblDepartment B ON A.DeptID = B.DeptID

    vậy khi mình muốn tìm kiếm 1 nhân viên nào đó theo mã thì mình gặp sự cố vì chưa biết sử dụng cột của View như thế nào:

     
    SELECT * FROM vw_Salary  WHERE ??? = 'NV001'

    Mong mọi người giúp đỡ (^.^)

    • PhaoThu (06/09/2011 9:36 am)

      SELECT * FROM vwSalary WHERE [Mã nhân viên] = ‘NV001′

      • Hoang Tung (13/09/2011 12:24 am)

        @PhaoThu : Thanks bạn nhé :)

        @Red Devilic : Cám ơn chia sẻ của bạn, nhưng đôi lúc mình vẫn cần phải change title của column trong truy vấn của SP, điều này là cần thiết khi mình tách biệt phần nghiệp vụ sang lập trình trên SP để giảm chi phí sửa chữa trên code lập trình.

        Anyway thanks all :)

  • Red Devilic (06/09/2011 10:31 pm)

    Hi bạn.

    Nên hạn chế đặt tên DB, tên bảng, tên cột ( nói chung là tên các object ) bằng tiếng Việt, hoặc có chứa khoảng trắng.

    Nếu cần, bạn có thể sửa tên cột tùy ý trên giao diện của chương trình.

    • chip07 (09/09/2011 12:08 pm)

      rất ủng hộ ý kiến của Red, chip nghĩ là Hoang Tung chắc tò mò muốn thử thôi, thực tế chưa gặp ai nghĩ đến chuyện sử dụng alias tiếng việt cả (>.<)

  • bach - Index View ? (13/10/2011 10:09 pm)

    Dear all,
    mình được xem qua slide trình bày về index view trong bài :SQL Server Seminar Hè 2011 – Download
    Mình code theo ví dụ trong slide nhưng ko hiểu sao ko chạy mặc dù đã set on off các tham số để MS SQL hỗ trợ index view như trong msdn hướng dẫn.
    Mình dùng SQL 2008 bản standard.
    Mình down AdventureWork và AdventureWorkR2 để test thử nhưng đều không thành công.
    Chỉ khi thay bằng lấy dữ liệu từ view with (Noexpand) thì mới dùng được index view.

    Nhân tiện vui lòng cho mình biết rõ hơn khi dùng : with (Noexpand) với view được không. Mình search code thấy nói dùng with Noexpand sẽ gợi ý MS SQL sử dụng index trên view. Tuy nhiên mình cũng chưa hiểu rõ lắm.

    • Red Devilic (14/10/2011 2:57 am)

      Mình cũng không nhớ là trên slide có ghi phiên bản hay không nhưng tại buổi seminar hôm đó thì mình có nói chức năng Indexed View chỉ có trên bản Enterprise, ở các phiên bản khác thì phải dùng NOEXPAND.

      Và tóm lại các bạn nên dùng bản Developer, vì bản này có tính năng tương đương với Enterprise mà không cần phải cài trên Win Server

      • bach (14/10/2011 5:05 am)

        Cám ơn bạn đã trả lời,

        Mình cũng vào msdn xem code thì cũng có như đề cập trong slide, tuy nhiên chạy thử thì execution plan ko thấy sử dụng index view.. muốn dùng thì phải truy vấn dữ liệu từ view chứ ko phải như code trong slide trình bày nên mình hỏi lại :)

  • Red Devilic (15/10/2011 12:27 am)

    Hi bạn

    Silde thì không nói đủ như ở trên seminar được. Khi bạn sử dụng phiên bản Enterprise, bạn có thể viết truy vấn thông thường. Tự SQL sẽ kiểm tra xem truy vấn của bạn có phải là 1 tập con của index view đã định nghĩa từ trước hay không. Và nó sẽ tự sử dụng Index View

  • NHQ (26/12/2011 11:28 pm)

    e muon hoi neu ko dung view thi giai phap thay the la gi a?

    • Vũ Huy Tâm (09/05/2012 2:57 pm)

      Bạn có thể dùng synonym, nhưng nó chỉ thay tên bảng chứ không select hay join như view

  • nguyenminh (08/05/2012 3:43 pm)

    Anh ơi,
    câu lệnh:

    CREATE VIEW PGIAODICH2
    AS
    select *
    from PHIENGIAODICH3
    union all
    select *
    from PHIENGIAODICH4
    union all
    select *
    from PHIENGIAODICH5
    Thế mỗi khi em thay đổi dữ liệu trong bảng PHIENGIAODICH5 chẳng hạn thì phải tạo lại CREATE VIEW à?
    Em thấy khi thay đổi dữ liệu thi truy xuất trên PGIAODICH2 vẫn không thay đổi.
    Có cách nào để chỉ dùng 1 lần CREATE VIEW PGIAODICH2 không a?

    • Vũ Huy Tâm (09/05/2012 2:58 pm)

      Không biết trường hợp của bạn thế nào mới không thấy dữ liệu mới thôi. Chứ view luôn lấy dữ liệu mới nhất từ bảng, không cần tạo lại trước khi truy vấn

  • Tùng (04/01/2014 3:15 am)

    cho mình hỏi mình có thể lồng lệnh if … else vào trong view được không ? ở ví dụ trên
    CREATE VIEW ViewBaseTable
    AS

    SELECT CustomerID, CustomerName, CustomerDOB
    FROM BaseTable

  • Tùng (04/01/2014 3:16 am)

    cho mình hỏi mình có thể lồng lệnh if … else vào trong view được không ? ở ví dụ trên
    CREATE VIEW ViewBaseTable
    AS
    if tableXXX.id=’001′
    SELECT CustomerID, CustomerName, CustomerDOB
    FROM BaseTable
    else
    select …… from……

    Mong các bác chỉ giáo em với :)

  • Sơn (18/02/2014 11:16 am)

    Bài viết hay, cảm ơn bạn!

  • Xuantien Ho (27/03/2014 8:56 pm)

    Nếu view là một bảng dữ liệu ảo thì trong ngôn ngữ lập trình mình có thể load dữ liệu lên bảng được không mọi người!

    • Red Devilic (28/03/2014 12:50 am)

      Ngắn gọn là được :D

      • linh (18/05/2014 9:00 pm)

        tạo view tổng hợp theo từng phòng ban.lam nhu the nao ha? cac bac

  • ve sinh may lanh (18/05/2014 10:47 pm)

    Bạn ơi cho mình hỏi Synonyms ý nghĩa là gì vậy bạn? mình chỉ biết là nó có thể thay thế cho table trong database rồi chỉ có thể select nó thay cho table rồi nó còn zỳ nữa không bạn?

  • linh (26/03/2015 4:40 am)

    như bạn đã nói ở trên là view truy vấn không nhanh hơn truy vấn trực tiếp từ bảng
    nhưng bạn lại ví dụ là vừa tạo view vừa truy vấn
    nếu như mình có view sẵn rồi thì sao
    liệu có nhanh hơn k?
    ^_^

    • Red Devilic (03/04/2015 4:44 am)

      Câu trả lời là không.

  • Ping Pong (02/08/2017 8:20 am)

    Cho mình hỏi chút được không ? Khi nào thì view sẽ được cập nhật dữ liệu. Ví dụ View lấy từ bảng A, và khi Insert vào A một record thì khi nào View có dữ liệu mới chèn này. (Giả sử lấy tất cả thuôc tính trong A) ( Câu này mình bị hỏi khi phỏng vấn vị trí dev của môt công ty mà mình không biết phải trả lời câu này như thế nào)

  • Red Devilic (24/08/2017 9:00 pm)

    View không chứa dữ liệu, nó là 1 phép chiếu lên dữ liệu của các bảng thôi.

    Ví dụ VIEW của bạn là X: (SELECT * FROM A).

    Thì khi SELECT * FROM X thực chất là SELECT * FROM (SELECT * FROM A).

    Thế nên khi bạn INSERT vào A thì select trong View sẽ có luôn dữ liệu mới thôi :)

Leave a Reply

Hướng dẫn: Để nhập mã T-SQL bạn dùng thẻ <pre lang="tsql"> và </pre>.
Ví dụ: <pre lang="tsql">SELECT * FROM MyTable</pre>