Làm thế nào để tạo một bảng phân vùng dựa trên ngày?


7

Tôi đang cố gắng tạo một bảng được phân vùng trong đó phân vùng được xác định bởi OrderDate. Tôi đang cố gắng để tạo ra một clustered indextrên OrderDatenonclustered primary keytrên OrderID. Nhưng tôi nhận được một lỗi nói:

Msg 1908, Cấp 16, Trạng thái 1, Dòng 1 'OrderDate' là cột phân vùng của chỉ mục 'PK_OrderID'. Các cột phân vùng cho một chỉ mục duy nhất phải là một tập hợp con của khóa chỉ mục. Msg 1750, Cấp 16, Trạng thái 0, Dòng 1 Không thể tạo ràng buộc. Xem các lỗi trước.

Làm thế nào để sửa đổi điều này để làm cho nó hoạt động:

CREATE TABLE dbo.Orders
    (
      OrderID INT NOT NULL ,
      Name NVARCHAR(20) NULL ,
      OrderDate DATE NOT NULL ,
    )
ON  PartSchemeOrders(OrderDate)

CREATE CLUSTERED INDEX IX_OrderDate
 on dbo.Orders (OrderDate)
 on PartSchemeOrders(OrderDate)

ALTER TABLE dbo.Orders
    ADD CONSTRAINT PK_OrderID PRIMARY KEY NONCLUSTERED  (OrderID)

Câu trả lời:


11

Như thông báo lỗi cho biết, bất kỳ chỉ mục duy nhất phù hợp với phân vùng phải bao gồm khóa phân vùng trong khóa chỉ mục. Yêu cầu này tồn tại để động cơ có thể thực thi tính duy nhất trên các bản cập nhật mà không cần kiểm tra mọi phân vùng.

Trong trường hợp của bạn, điều này có nghĩa là bao gồm OrderDatetrong khóa chỉ mục không bao gồm hoặc có chỉ mục không liên kết. Cả hai đều có khả năng lựa chọn hợp lệ, tùy thuộc vào hoàn cảnh của bạn. Để duy trì căn chỉnh, định nghĩa bảng và chỉ mục của bạn sẽ là:

CREATE TABLE dbo.Orders
(
    OrderID     integer NOT NULL,
    Name        nvarchar(20) NULL,
    OrderDate   date NOT NULL,

    CONSTRAINT PK__Orders_OrderID_OrderDate
        PRIMARY KEY NONCLUSTERED 
            (OrderID, OrderDate)
        ON PS (OrderDate)
)
ON PS (OrderDate);
GO
CREATE CLUSTERED INDEX CX__Orders_OrderDate
ON dbo.Orders (OrderDate)
ON PS (OrderDate);

Tất nhiên điều này thay đổi tính duy nhất mà chỉ mục không bao gồm thực thi. Bây giờ, chỉ có sự kết hợp OrderIDOrderDateđược đảm bảo là duy nhất. Về mặt lý thuyết có thể thêm OrderIDcác s trùng lặp , miễn OrderDatelà khác nhau. Việc thay đổi ngữ nghĩa này có được bạn chấp nhận hay không tùy thuộc vào hoàn cảnh của bạn, nhưng đó là điều cần lưu ý.

Thay thế là có khóa chính không được bao gồm không được căn chỉnh:

CREATE TABLE dbo.Orders
(
    OrderID     integer NOT NULL,
    Name        nvarchar(20) NULL,
    OrderDate   date NOT NULL,

    CONSTRAINT PK__Orders_OrderID
        PRIMARY KEY NONCLUSTERED 
            (OrderID)
        ON [PRIMARY]
)
ON PS (OrderDate);
GO
CREATE CLUSTERED INDEX CX__Orders_OrderDate
ON dbo.Orders (OrderDate)
ON PS (OrderDate);

Điều này duy trì tính duy nhất của OrderIDmột mình và có một số lợi ích với các truy vấn tính toán MINhoặc MAXtổng hợp bằng cách sử dụng chỉ mục, nhưng bạn mất khả năng SWITCHphân vùng vào và ra mà không bỏ khóa chính và tạo lại nó sau thao tác chuyển đổi.

Bạn có thể đọc thêm về phân vùng trong phần Sách trực tuyến này và nhiều hơn về các vấn đề về chỉ mục được căn chỉnh và không liên kết trong câu trả lời xuất sắc này của Remus Rusanu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.