Cân bằng ghi và đọc trong cơ sở dữ liệu

Cân bằng ghi và đọc trong cơ sở dữ liệu
Trước đây Bài viết Tôi đã mô tả khái niệm và cách triển khai cơ sở dữ liệu được xây dựng trên cơ sở các hàm, thay vì các bảng và trường như trong cơ sở dữ liệu quan hệ. Nó cung cấp nhiều ví dụ cho thấy những ưu điểm của phương pháp này so với phương pháp cổ điển. Nhiều người cho rằng chúng không đủ thuyết phục.

Trong bài viết này, tôi sẽ chỉ ra cách khái niệm này cho phép bạn cân bằng việc ghi và đọc cơ sở dữ liệu một cách nhanh chóng và thuận tiện mà không có bất kỳ thay đổi nào về logic vận hành. Chức năng tương tự đã được thử triển khai trong các DBMS thương mại hiện đại (đặc biệt là Oracle và Microsoft SQL Server). Ở cuối bài viết, tôi sẽ chỉ ra rằng những gì họ đã làm, nói một cách nhẹ nhàng, không hiệu quả lắm.

Описание

Như trước đây, để hiểu rõ hơn tôi sẽ bắt đầu mô tả bằng các ví dụ. Giả sử chúng ta cần triển khai logic sẽ trả về danh sách các phòng ban có số lượng nhân viên trong đó và tổng tiền lương của họ.

Trong cơ sở dữ liệu chức năng, nó sẽ trông như thế này:

CLASS Department ‘Отдел’;
name ‘Наименование’ = DATA STRING[100] (Department);

CLASS Employee ‘Сотрудник’;
department ‘Отдел’ = DATA Department (Employee);
salary ‘Зарплата’ =  DATA NUMERIC[10,2] (Employee);

countEmployees ‘Кол-во сотрудников’ (Department d) = 
    GROUP SUM 1 IF department(Employee e) = d;
salarySum ‘Суммарная зарплата’ (Department d) = 
    GROUP SUM salary(Employee e) IF department(e) = d;

SELECT name(Department d), countEmployees(d), salarySum(d);

Độ phức tạp của việc thực hiện truy vấn này trong bất kỳ DBMS nào sẽ tương đương với O(số lượng nhân viên)vì phép tính này yêu cầu quét toàn bộ bảng nhân viên rồi nhóm lại theo phòng ban. Cũng sẽ có một số bổ sung nhỏ (chúng tôi tin rằng có nhiều nhân viên hơn các phòng ban) tùy thuộc vào kế hoạch đã chọn O(log số lượng nhân viên) hoặc O(số phòng ban) để nhóm và vân vân.

Rõ ràng là chi phí thực thi có thể khác nhau trong các DBMS khác nhau, nhưng độ phức tạp sẽ không thay đổi theo bất kỳ cách nào.

Trong quá trình triển khai được đề xuất, DBMS chức năng sẽ tạo ra một truy vấn con tính toán các giá trị cần thiết cho bộ phận, sau đó thực hiện THAM GIA với bảng bộ phận để lấy tên. Tuy nhiên, đối với mỗi hàm, khi khai báo có thể đặt dấu hiệu MATERIALIZED đặc biệt. Hệ thống sẽ tự động tạo trường tương ứng cho từng chức năng đó. Khi thay đổi giá trị của hàm, giá trị của trường cũng sẽ thay đổi trong cùng một giao dịch. Khi truy cập chức năng này, trường được tính toán trước sẽ được truy cập.

Đặc biệt, nếu bạn đặt MATERIALIZED cho các chức năng đếmNhân viên и tiền lươngTổng hợp, khi đó hai trường sẽ được thêm vào bảng với danh sách các phòng ban, nơi sẽ lưu trữ số lượng nhân viên và tổng tiền lương của họ. Bất cứ khi nào có sự thay đổi về nhân viên, mức lương của họ hoặc các đơn vị liên kết bộ phận, hệ thống sẽ tự động thay đổi giá trị của các trường này. Truy vấn trên sẽ truy cập trực tiếp vào các trường này và sẽ được thực thi trong O(số phòng ban).

Những hạn chế là gì? Chỉ có một điều: một hàm như vậy phải có số lượng hữu hạn các giá trị đầu vào mà giá trị của nó được xác định. Nếu không, sẽ không thể xây dựng một bảng lưu trữ tất cả các giá trị của nó, vì không thể có một bảng có vô số hàng.

Ví dụ:

employeesCount ‘Количество сотрудников с зарплатой > N’ (Department d, NUMERIC[10,2] N) = 
    GROUP SUM salary(Employee e) IF department(e) = d AND salary(e) > N;

Hàm này được xác định cho vô số giá trị của N (ví dụ: bất kỳ giá trị âm nào cũng phù hợp). Vì vậy, bạn không thể đặt VẬT LIỆU lên nó. Vì vậy, đây là một giới hạn hợp lý, không phải là một giới hạn kỹ thuật (nghĩa là không phải vì chúng tôi không thể triển khai nó). Nếu không thì không có hạn chế. Bạn có thể sử dụng các nhóm, sắp xếp, VÀ và HOẶC, PHẦN THAM GIA, đệ quy, v.v.

Ví dụ ở bài 2.2 của bài trước bạn có thể đặt MATERIALIZED trên cả XNUMX hàm:

bought 'Купил' (Customer c, Product p, INTEGER y) = 
    GROUP SUM sum(Detail d) IF 
        customer(order(d)) = c AND 
        product(d) = p AND 
        extractYear(date(order(d))) = y MATERIALIZED;
rating 'Рейтинг' (Customer c, Product p, INTEGER y) = 
    PARTITION SUM 1 ORDER DESC bought(c, p, y), p BY c, y MATERIALIZED;
SELECT contactName(Customer c), name(Product p) WHERE rating(c, p, 1997) < 3;

Bản thân hệ thống sẽ tạo một bảng với các phím loại Khách hàng, Sản phẩm и số nguyên, sẽ thêm hai trường vào đó và sẽ cập nhật các giá trị trường trong đó với bất kỳ thay đổi nào. Khi thực hiện các lệnh gọi tiếp theo đến các hàm này, chúng sẽ không được tính toán mà thay vào đó, các giá trị sẽ được đọc từ các trường tương ứng.

Ví dụ: bằng cách sử dụng cơ chế này, bạn có thể loại bỏ các lần đệ quy (CTE) trong truy vấn. Cụ thể, hãy xem xét các nhóm tạo thành cây bằng cách sử dụng mối quan hệ con/cha mẹ (mỗi nhóm có một liên kết đến cha mẹ của nó):

parent = DATA Group (Group);

Trong cơ sở dữ liệu chức năng, logic đệ quy có thể được chỉ định như sau:

level (Group child, Group parent) = RECURSION 1l IF child IS Group AND parent == child
                                                             STEP 2l IF parent == parent($parent);
isParent (Group child, Group parent) = TRUE IF level(child, parent) MATERIALIZED;

Vì đối với chức năng isParent được đánh dấu là VẬT LIỆU, sau đó một bảng có hai khóa (nhóm) sẽ được tạo cho nó, trong đó trường isParent sẽ chỉ đúng nếu khóa đầu tiên là con của khóa thứ hai. Số lượng mục trong bảng này sẽ bằng số lượng nhóm nhân với độ sâu trung bình của cây. Ví dụ: nếu bạn cần đếm số lượng con cháu của một nhóm nhất định, bạn có thể sử dụng hàm này:

childrenCount (Group g) = GROUP SUM 1 IF isParent(Group child, g);

Sẽ không có CTE trong truy vấn SQL. Thay vào đó sẽ có một NHÓM THEO đơn giản.

Sử dụng cơ chế này, bạn cũng có thể dễ dàng chuẩn hóa cơ sở dữ liệu nếu cần:

CLASS Order 'Заказ';
date 'Дата' = DATA DATE (Order);

CLASS OrderDetail 'Строка заказа';
order 'Заказ' = DATA Order (OrderDetail);
date 'Дата' (OrderDetail d) = date(order(d)) MATERIALIZED INDEXED;

Khi gọi một hàm ngày đối với dòng thứ tự, trường có chỉ mục sẽ được đọc từ bảng có dòng thứ tự. Khi ngày đặt hàng thay đổi, hệ thống sẽ tự động tính toán lại ngày không chuẩn hóa trong dòng.

Lợi thế

Toàn bộ cơ chế này để làm gì? Trong các DBMS cổ điển, không cần viết lại các truy vấn, nhà phát triển hoặc DBA chỉ có thể thay đổi chỉ mục, xác định số liệu thống kê và cho người lập kế hoạch truy vấn biết cách thực hiện chúng (và HINT chỉ có sẵn trong các DBMS thương mại). Dù có cố gắng thế nào thì họ cũng sẽ không thể hoàn thành được truy vấn đầu tiên trong bài viết ở O (số phòng ban) mà không thay đổi truy vấn hoặc thêm trình kích hoạt. Trong sơ đồ đề xuất, ở giai đoạn phát triển, bạn không cần phải suy nghĩ về cấu trúc lưu trữ dữ liệu và những tập hợp nào sẽ sử dụng. Tất cả điều này có thể dễ dàng thay đổi nhanh chóng, trực tiếp khi vận hành.

Trong thực tế nó trông như thế này. Một số người phát triển logic trực tiếp dựa trên nhiệm vụ trước mắt. Họ không hiểu các thuật toán và độ phức tạp của chúng, cũng như các kế hoạch thực hiện, các loại liên kết cũng như bất kỳ thành phần kỹ thuật nào khác. Những người này là nhà phân tích kinh doanh nhiều hơn là nhà phát triển. Sau đó, tất cả điều này sẽ được đưa vào thử nghiệm hoặc vận hành. Cho phép ghi nhật ký các truy vấn chạy dài. Khi phát hiện một truy vấn dài, thì những người khác (kỹ thuật hơn - về cơ bản là DBA) quyết định bật VẬT LIỆU trên một số chức năng trung gian. Điều này làm chậm quá trình ghi một chút (vì nó yêu cầu cập nhật một trường bổ sung trong giao dịch). Tuy nhiên, không chỉ truy vấn này được tăng tốc đáng kể mà còn tất cả những truy vấn khác sử dụng chức năng này. Đồng thời, việc quyết định thực hiện chức năng nào là tương đối dễ dàng. Hai tham số chính: số lượng giá trị đầu vào có thể có (đây là số lượng bản ghi sẽ có trong bảng tương ứng) và tần suất nó được sử dụng trong các hàm khác.

Chất tương tự

Các DBMS thương mại hiện đại có các cơ chế tương tự: XEM VẬT LIỆU với LÀM MỚI NHANH CHÓNG (Oracle) và XEM CHỈ SỐ (Microsoft SQL Server). Trong PostgreSQL, CHẾ ĐỘ XEM VẬT LIỆU không thể được cập nhật trong một giao dịch mà chỉ theo yêu cầu (và thậm chí với những hạn chế rất nghiêm ngặt), vì vậy chúng tôi không xem xét nó. Nhưng họ có một số vấn đề làm hạn chế đáng kể việc sử dụng chúng.

Đầu tiên, bạn chỉ có thể kích hoạt hiện thực hóa nếu bạn đã tạo XEM thông thường. Nếu không, bạn sẽ phải viết lại các yêu cầu còn lại để truy cập vào chế độ xem mới được tạo để sử dụng vật chất hóa này. Hoặc để nguyên mọi thứ, nhưng ít nhất nó sẽ không hiệu quả nếu có một số dữ liệu đã được tính toán trước, nhưng nhiều truy vấn không phải lúc nào cũng sử dụng nó mà tính toán lại.

Thứ hai, họ có một số hạn chế rất lớn:

Oracle

5.3.8.4 Hạn chế chung về làm mới nhanh

Truy vấn xác định của chế độ xem cụ thể hóa bị hạn chế như sau:

  • Chế độ xem cụ thể hóa không được chứa các tham chiếu đến các biểu thức không lặp lại như SYSDATEROWNUM.
  • Chế độ xem cụ thể hóa không được chứa các tham chiếu đến RAW or LONG RAW Loại dữ liệu.
  • Nó không thể chứa một SELECT truy vấn phụ danh sách.
  • Nó không thể chứa các chức năng phân tích (ví dụ: RANK) Trong SELECT mệnh đề.
  • Nó không thể tham chiếu đến một bảng mà trên đó XMLIndex chỉ số được xác định.
  • Nó không thể chứa một MODEL mệnh đề.
  • Nó không thể chứa một HAVING mệnh đề với một truy vấn phụ.
  • Nó không thể chứa các truy vấn lồng nhau có ANY, ALL, hoặc là NOT EXISTS.
  • Nó không thể chứa một [START WITH …] CONNECT BY mệnh đề.
  • Nó không thể chứa nhiều bảng chi tiết tại các trang web khác nhau.
  • ON COMMIT các khung nhìn cụ thể hóa không thể có các bảng chi tiết từ xa.
  • Các chế độ xem cụ thể hóa lồng nhau phải có sự tham gia hoặc tổng hợp.
  • Các chế độ xem tham gia được cụ thể hóa và các chế độ xem tổng hợp được cụ thể hóa với một GROUP BY mệnh đề không thể chọn từ một bảng được tổ chức theo chỉ mục.

5.3.8.5 Hạn chế về việc làm mới nhanh trên các chế độ xem cụ thể hóa chỉ với các liên kết

Việc xác định các truy vấn cho các chế độ xem cụ thể hóa chỉ có các phép nối và không có tổng hợp nào có các hạn chế sau đây đối với việc làm mới nhanh:

  • Tất cả các hạn chế từ «Hạn chế chung về làm mới nhanh".
  • Họ không thể có GROUP BY mệnh đề hoặc tập hợp.
  • Hàng của tất cả các bảng trong FROM danh sách phải xuất hiện trong SELECT danh sách truy vấn.
  • Nhật ký chế độ xem cụ thể hóa phải tồn tại cùng với các hàng cho tất cả các bảng cơ sở trong FROM danh sách truy vấn.
  • Bạn không thể tạo chế độ xem cụ thể hóa có thể làm mới nhanh từ nhiều bảng bằng các phép nối đơn giản bao gồm cột loại đối tượng trong SELECT tuyên bố.

Ngoài ra, phương pháp làm mới bạn chọn sẽ không hiệu quả tối ưu nếu:

  • Truy vấn xác định sử dụng phép nối ngoài hoạt động giống như phép nối trong. Nếu truy vấn xác định có chứa một phép nối như vậy, hãy xem xét việc viết lại truy vấn xác định để chứa một phép nối bên trong.
  • Sản phẩm SELECT danh sách chế độ xem cụ thể hóa chứa các biểu thức trên các cột từ nhiều bảng.

5.3.8.6 Hạn chế về việc làm mới nhanh trên các chế độ xem được cụ thể hóa với các tập hợp

Việc xác định các truy vấn cho các chế độ xem cụ thể hóa bằng tổng hợp hoặc kết hợp có các hạn chế sau đây đối với việc làm mới nhanh:

Làm mới nhanh được hỗ trợ cho cả hai ON COMMITON DEMAND quan điểm cụ thể hóa, tuy nhiên các hạn chế sau được áp dụng:

  • Tất cả các bảng trong chế độ xem cụ thể hóa phải có nhật ký chế độ xem cụ thể hóa và nhật ký chế độ xem cụ thể hóa phải:
    • Chứa tất cả các cột từ bảng được tham chiếu trong chế độ xem cụ thể hóa.
    • Chỉ định với ROWIDINCLUDING NEW VALUES.
    • Xác định SEQUENCE mệnh đề nếu bảng dự kiến ​​​​sẽ có sự kết hợp giữa các thao tác chèn/tải trực tiếp, xóa và cập nhật.

  • Chỉ có SUM, COUNT, AVG, STDDEV, VARIANCE, MINMAX được hỗ trợ để làm mới nhanh chóng.
  • COUNT(*) phải được chỉ định.
  • Các hàm tổng hợp chỉ được xuất hiện ở phần ngoài cùng của biểu thức. Nghĩa là, các tập hợp như AVG(AVG(x)) or AVG(x)+ AVG(x) không được cho phép.
  • Đối với mỗi tổng hợp như AVG(expr), tương ứng COUNT(expr) phải có mặt. Oracle khuyến nghị rằng SUM(expr) được chỉ định.
  • If VARIANCE(expr) or STDDEV(expr) được quy định, COUNT(expr)SUM(expr) phải được chỉ định. Oracle khuyến nghị rằng SUM(expr *expr) được chỉ định.
  • Sản phẩm SELECT cột trong truy vấn xác định không thể là một biểu thức phức tạp với các cột từ nhiều bảng cơ sở. Một cách giải quyết khả thi cho vấn đề này là sử dụng chế độ xem cụ thể hóa lồng nhau.
  • Sản phẩm SELECT danh sách phải chứa tất cả GROUP BY cột.
  • Chế độ xem cụ thể hóa không dựa trên một hoặc nhiều bảng từ xa.
  • Nếu bạn sử dụng một CHAR loại dữ liệu trong các cột bộ lọc của nhật ký chế độ xem cụ thể hóa, bộ ký tự của trang chính và chế độ xem cụ thể hóa phải giống nhau.
  • Nếu chế độ xem cụ thể hóa có một trong những điều sau đây, thì làm mới nhanh chỉ được hỗ trợ trên các phần chèn DML thông thường và tải trực tiếp.
    • Quan điểm cụ thể hóa với MIN or MAX tổng hợp
    • Những quan điểm cụ thể hóa có SUM(expr) nhưng không COUNT(expr)
    • Các quan điểm cụ thể hóa mà không có COUNT(*)

    Một khung nhìn vật chất hóa như vậy được gọi là một khung nhìn vật chất hóa chỉ chèn.

  • Một cái nhìn cụ thể hóa với MAX or MIN có thể làm mới nhanh sau khi xóa hoặc trộn các câu lệnh DML nếu nó không có WHERE mệnh đề.
    Làm mới nhanh tối đa/phút sau khi xóa hoặc DML hỗn hợp không có hành vi tương tự như trường hợp chỉ chèn. Nó xóa và tính toán lại các giá trị tối đa/tối thiểu cho các nhóm bị ảnh hưởng. Bạn cần phải nhận thức được tác động hiệu suất của nó.
  • Các chế độ xem được cụ thể hóa với các chế độ xem hoặc truy vấn con được đặt tên trong FROM mệnh đề có thể được làm mới nhanh chóng với điều kiện các khung nhìn có thể được hợp nhất hoàn toàn. Để biết thông tin về chế độ xem nào sẽ hợp nhất, hãy xem Tham chiếu ngôn ngữ SQL của Cơ sở dữ liệu Oracle.
  • Nếu không có các kết nối bên ngoài, bạn có thể có các lựa chọn và kết nối tùy ý trong WHERE mệnh đề.
  • Các chế độ xem tổng hợp được cụ thể hóa với các liên kết bên ngoài có thể làm mới nhanh chóng sau DML thông thường và tải trực tiếp, miễn là chỉ bảng bên ngoài đã được sửa đổi. Ngoài ra, các ràng buộc duy nhất phải tồn tại trên các cột nối của bảng nối bên trong. Nếu có các phép nối ngoài thì tất cả các phép nối phải được kết nối bằng ANDs và phải sử dụng đẳng thức (=) nhà điều hành.
  • Đối với các quan điểm cụ thể hóa với CUBE, ROLLUP, tập hợp nhóm hoặc ghép nối chúng, các hạn chế sau sẽ được áp dụng:
    • Sản phẩm SELECT danh sách phải chứa mã phân biệt nhóm có thể là một GROUPING_ID hoạt động trên tất cả GROUP BY biểu thức hoặc GROUPING chức năng một cho mỗi GROUP BY sự biểu lộ. Ví dụ, nếu GROUP BY mệnh đề của quan điểm cụ thể hóa là "GROUP BY CUBE(a, b)", thì SELECT danh sách phải chứa "GROUPING_ID(a, b)" hoặc "GROUPING(a) AND GROUPING(b)» để chế độ xem cụ thể hóa có thể được làm mới nhanh chóng.
    • GROUP BY không được dẫn đến bất kỳ nhóm trùng lặp nào. Ví dụ, "GROUP BY a, ROLLUP(a, b)" không thể làm mới nhanh vì nó tạo ra các nhóm trùng lặp "(a), (a, b), AND (a)".

5.3.8.7 Hạn chế về việc làm mới nhanh trên các chế độ xem cụ thể hóa với UNION ALL

Các quan điểm cụ thể hóa với UNION ALL hỗ trợ toán tử thiết lập REFRESH FAST quyền chọn nếu thỏa mãn các điều kiện sau:

  • Truy vấn xác định phải có UNION ALL nhà điều hành ở cấp cao nhất.

    Sản phẩm UNION ALL toán tử không thể được nhúng vào trong truy vấn con, ngoại trừ một ngoại lệ: UNION ALL có thể ở trong một truy vấn phụ trong FROM mệnh đề với điều kiện truy vấn xác định có dạng SELECT * FROM (xem hoặc truy vấn phụ với UNION ALL) như trong ví dụ sau:

    TẠO VIEW view_with_unionall AS (CHỌN c.rowid crid, c.cust_id, 2 umarker TỪ khách hàng c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker TỪ khách hàng c WHERE c.cust_last_name = 'Jones'); TẠO CHẾ ĐỘ XEM VẬT LIỆU Unionall_inside_view_mv LÀM MỚI NHANH CHÓNG THEO YÊU CẦU NHƯ CHỌN * TỪ view_with_unionall;
    

    Lưu ý rằng quan điểm view_with_unionall đáp ứng yêu cầu làm mới nhanh.

  • Mỗi khối truy vấn trong UNION ALL truy vấn phải đáp ứng các yêu cầu của chế độ xem cụ thể hóa có thể làm mới nhanh với các tập hợp hoặc chế độ xem cụ thể hóa có thể làm mới nhanh bằng các phép nối.

    Nhật ký chế độ xem cụ thể hóa phù hợp phải được tạo trên các bảng theo yêu cầu đối với loại chế độ xem cụ thể hóa có thể làm mới nhanh tương ứng.
    Lưu ý rằng Cơ sở dữ liệu Oracle cũng cho phép trường hợp đặc biệt của một chế độ xem cụ thể hóa một bảng với các phép nối chỉ được cung cấp ROWID cột đã được đưa vào SELECT danh sách và trong nhật ký xem cụ thể hóa. Điều này được hiển thị trong truy vấn xác định của chế độ xem view_with_unionall.

  • Sản phẩm SELECT danh sách mỗi truy vấn phải bao gồm một UNION ALL điểm đánh dấu và UNION ALL cột phải có một giá trị số hoặc chuỗi không đổi riêng biệt trong mỗi cột UNION ALL chi nhánh. Hơn nữa, cột đánh dấu phải xuất hiện ở cùng vị trí thứ tự trong SELECT danh sách từng khối truy vấn. Nhìn thấy "UNION ALL Marker và Viết lại truy vấn» để biết thêm thông tin về UNION ALL các điểm đánh dấu.
  • Một số tính năng như liên kết ngoài, truy vấn chế độ xem cụ thể hóa tổng hợp chỉ chèn và bảng từ xa không được hỗ trợ cho các chế độ xem cụ thể hóa với UNION ALL. Tuy nhiên, lưu ý rằng các chế độ xem cụ thể hóa được sử dụng trong sao chép, không chứa các phép nối hoặc tập hợp, có thể được làm mới nhanh chóng khi UNION ALL hoặc các bảng từ xa được sử dụng.
  • Tham số khởi tạo khả năng tương thích phải được đặt thành 9.2.0 hoặc cao hơn để tạo chế độ xem cụ thể hóa có thể làm mới nhanh với UNION ALL.

Tôi không muốn xúc phạm những người hâm mộ Oracle, nhưng xét theo danh sách hạn chế của họ, có vẻ như cơ chế này được viết ra không phải trong trường hợp chung, sử dụng một loại mô hình nào đó, mà bởi hàng nghìn người Ấn Độ, nơi mọi người đều được trao cơ hội để viết chi nhánh riêng của họ, và mỗi người trong số họ đã làm những gì có thể. Sử dụng cơ chế này cho logic thực sự cũng giống như việc đi qua một bãi mìn. Bạn có thể nhận được mỏ bất kỳ lúc nào bằng cách chạm vào một trong những hạn chế không rõ ràng. Nó hoạt động như thế nào cũng là một câu hỏi riêng biệt, nhưng nó nằm ngoài phạm vi của bài viết này.

Microsoft SQL Server

Yêu cầu bổ sung

Ngoài các tùy chọn SET và các yêu cầu về chức năng xác định, phải đáp ứng các yêu cầu sau:

  • Người dùng thực thi CREATE INDEX phải là chủ sở hữu của chế độ xem.
  • Khi bạn tạo chỉ mục, IGNORE_DUP_KEY tùy chọn phải được đặt thành TẮT (cài đặt mặc định).
  • Các bảng phải được tham chiếu bằng tên gồm hai phần, kế hoạch.bảng tên trong định nghĩa khung nhìn.
  • Các hàm do người dùng định nghĩa được tham chiếu trong dạng xem phải được tạo bằng cách sử dụng WITH SCHEMABINDING tùy chọn.
  • Mọi hàm do người dùng xác định được tham chiếu trong dạng xem phải được tham chiếu bằng tên gồm hai phần, ..
  • Thuộc tính truy cập dữ liệu của hàm do người dùng xác định phải là NO SQLvà thuộc tính truy cập bên ngoài phải là NO.
  • Các hàm thời gian chạy ngôn ngữ chung (CLR) có thể xuất hiện trong danh sách chọn của dạng xem nhưng không thể là một phần trong định nghĩa của khóa chỉ mục được nhóm. Các hàm CLR không thể xuất hiện trong mệnh đề WHERE của dạng xem hoặc mệnh đề ON của thao tác THAM GIA trong dạng xem.
  • Các hàm và phương thức CLR của các kiểu do người dùng định nghĩa CLR được sử dụng trong định nghĩa khung nhìn phải có các thuộc tính được đặt như trong bảng sau.

    Bất động sản
    Chú thích

    XÁC ĐỊNH = ĐÚNG
    Phải được khai báo rõ ràng là một thuộc tính của phương pháp Microsoft .NET Framework.

    CHÍNH XÁC = ĐÚNG
    Phải được khai báo rõ ràng là thuộc tính của phương thức .NET Framework.

    TRUY CẬP DỮ LIỆU = KHÔNG SQL
    Được xác định bằng cách đặt thuộc tính DataAccess thành DataAccessKind.None và thuộc tính SystemDataAccess thành SystemDataAccessKind.None.

    TRUY CẬP BÊN NGOÀI = KHÔNG
    Thuộc tính này mặc định là KHÔNG cho các thủ tục CLR.

  • Chế độ xem phải được tạo bằng cách sử dụng WITH SCHEMABINDING tùy chọn.
  • Chế độ xem chỉ được tham chiếu các bảng cơ sở trong cùng cơ sở dữ liệu với chế độ xem. Chế độ xem không thể tham chiếu các chế độ xem khác.
  • Câu lệnh SELECT trong định nghĩa dạng xem không được chứa các phần tử Transact-SQL sau:

    COUNT
    Hàm ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, VÀ OPENXML)
    OUTER tham gia (LEFT, RIGHT, hoặc là FULL)

    Bảng dẫn xuất (được xác định bằng cách chỉ định một SELECT tuyên bố trong FROM mệnh đề)
    Tự tham gia
    Chỉ định các cột bằng cách sử dụng SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARP, hoặc là AVG
    Biểu thức bảng chung (CTE)

    phao1, văn bản, văn bản, hình ảnh, XML, hoặc là tập hồ sơ cột
    subquery
    OVER mệnh đề, bao gồm các chức năng cửa sổ xếp hạng hoặc tổng hợp

    Vị từ toàn văn (CONTAINS, FREETEXT)
    SUM hàm tham chiếu một biểu thức có thể rỗng
    ORDER BY

    Hàm tổng hợp do người dùng xác định CLR
    TOP
    CUBE, ROLLUP, hoặc là GROUPING SETS khai thác

    MIN, MAX
    UNION, EXCEPT, hoặc là INTERSECT khai thác
    TABLESAMPLE

    Biến bảng
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Tập hợp cột thưa thớt
    Các hàm có giá trị bảng nội tuyến (TVF) hoặc nhiều câu lệnh (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Chế độ xem được lập chỉ mục có thể chứa phao cột; tuy nhiên, các cột như vậy không thể được đưa vào khóa chỉ mục được nhóm.

  • If GROUP BY hiện diện, định nghĩa VIEW phải chứa COUNT_BIG(*) và không được chứa HAVING. Kia là GROUP BY các hạn chế chỉ áp dụng cho định nghĩa chế độ xem được lập chỉ mục. Một truy vấn có thể sử dụng chế độ xem được lập chỉ mục trong kế hoạch thực hiện của nó ngay cả khi nó không đáp ứng được những điều này GROUP BY hạn chế.
  • Nếu định nghĩa khung nhìn chứa một GROUP BY mệnh đề, khóa của chỉ mục được nhóm duy nhất chỉ có thể tham chiếu đến các cột được chỉ định trong GROUP BY mệnh đề.

Ở đây rõ ràng là người da đỏ không tham gia, vì họ quyết định thực hiện theo kế hoạch “chúng tôi sẽ làm ít, nhưng tốt”. Tức là họ có nhiều mỏ hơn trên thực địa nhưng vị trí của họ minh bạch hơn. Điều đáng thất vọng nhất là hạn chế này:

Chế độ xem chỉ được tham chiếu các bảng cơ sở trong cùng cơ sở dữ liệu với chế độ xem. Chế độ xem không thể tham chiếu các chế độ xem khác.

Theo thuật ngữ của chúng tôi, điều này có nghĩa là một chức năng không thể truy cập vào một chức năng cụ thể hóa khác. Điều này cắt đứt mọi ý thức hệ từ trong trứng nước.
Ngoài ra, hạn chế này (và hơn nữa trong văn bản) làm giảm đáng kể các trường hợp sử dụng:

Câu lệnh SELECT trong định nghĩa dạng xem không được chứa các phần tử Transact-SQL sau:

COUNT
Hàm ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, VÀ OPENXML)
OUTER tham gia (LEFT, RIGHT, hoặc là FULL)

Bảng dẫn xuất (được xác định bằng cách chỉ định một SELECT tuyên bố trong FROM mệnh đề)
Tự tham gia
Chỉ định các cột bằng cách sử dụng SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARP, hoặc là AVG
Biểu thức bảng chung (CTE)

phao1, văn bản, văn bản, hình ảnh, XML, hoặc là tập hồ sơ cột
subquery
OVER mệnh đề, bao gồm các chức năng cửa sổ xếp hạng hoặc tổng hợp

Vị từ toàn văn (CONTAINS, FREETEXT)
SUM hàm tham chiếu một biểu thức có thể rỗng
ORDER BY

Hàm tổng hợp do người dùng xác định CLR
TOP
CUBE, ROLLUP, hoặc là GROUPING SETS khai thác

MIN, MAX
UNION, EXCEPT, hoặc là INTERSECT khai thác
TABLESAMPLE

Biến bảng
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Tập hợp cột thưa thớt
Các hàm có giá trị bảng nội tuyến (TVF) hoặc nhiều câu lệnh (MSTVF)
OFFSET

CHECKSUM_AGG

OUTER JOINS, UNION, ORDER BY và những thứ khác đều bị cấm. Có thể dễ dàng xác định những gì có thể sử dụng hơn là những gì không thể sử dụng. Danh sách có lẽ sẽ ngắn hơn nhiều.

Tóm lại: có rất nhiều hạn chế trong mọi DBMS (hãy lưu ý đến tính thương mại) và không có (ngoại trừ một hạn chế logic, không phải kỹ thuật) trong công nghệ LGPL. Tuy nhiên, cần lưu ý rằng việc thực hiện cơ chế này trong logic quan hệ có phần khó khăn hơn so với logic chức năng được mô tả.

Thực hiện

Làm thế nào nó hoạt động? PostgreSQL được sử dụng như một “máy ảo”. Có một thuật toán phức tạp bên trong để xây dựng các truy vấn. Đây nguồn. Và không chỉ có một tập hợp lớn các phương pháp phỏng đoán với hàng loạt câu hỏi nếu. Vì vậy, nếu bạn có vài tháng để học, bạn có thể cố gắng hiểu kiến ​​trúc.

Nó có hoạt động hiệu quả không? Khá hiệu quả. Thật không may, điều này rất khó để chứng minh. Tôi chỉ có thể nói rằng nếu bạn xem xét hàng nghìn truy vấn tồn tại trong các ứng dụng lớn, thì nhìn chung chúng hiệu quả hơn so với truy vấn của một nhà phát triển giỏi. Một lập trình viên SQL xuất sắc có thể viết bất kỳ truy vấn nào hiệu quả hơn, nhưng với hàng nghìn truy vấn, đơn giản là anh ta sẽ không có động lực hoặc thời gian để thực hiện việc đó. Điều duy nhất bây giờ tôi có thể trích dẫn làm bằng chứng về tính hiệu quả là một số dự án đang hoạt động trên nền tảng được xây dựng trên DBMS này hệ thống ERP, có hàng nghìn hàm VẬT LIỆU khác nhau, với hàng nghìn người dùng và cơ sở dữ liệu terabyte với hàng trăm triệu bản ghi chạy trên máy chủ hai bộ xử lý thông thường. Tuy nhiên, bất kỳ ai cũng có thể kiểm tra/bác bỏ tính hiệu quả bằng cách tải xuống nền tảng và PostgreSQL, đã bật lên ghi lại các truy vấn SQL và cố gắng thay đổi logic và dữ liệu ở đó.

Trong các bài viết tiếp theo, tôi cũng sẽ nói về cách bạn có thể đặt các hạn chế đối với các chức năng, làm việc với các phiên thay đổi, v.v.

Nguồn: www.habr.com

Thêm một lời nhận xét