Wie erstelle ich eine partitionierte Tabelle basierend auf dem Datum?

7

Ich versuche, eine partitionierte Tabelle zu erstellen, in der die Partitionierung durch bestimmt wird OrderDate. Ich versuche ein clustered indexOn OrderDateund ein nonclustered primary keyOn zu erstellen OrderID. Aber ich bekomme eine Fehlermeldung:

Meldung 1908, Ebene 16, Status 1, Zeile 1 Spalte 'OrderDate' ist eine Partitionierungsspalte des Index 'PK_OrderID'. Partitionsspalten für einen eindeutigen Index müssen eine Teilmenge des Indexschlüssels sein. Meldung 1750, Ebene 16, Status 0, Zeile 1 Es konnte keine Einschränkung erstellt werden. Siehe vorherige Fehler.

So ändern Sie dies, damit es funktioniert:

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)
jrara
quelle

Antworten:

11

Wie in der Fehlermeldung angegeben, muss jeder partitionorientierte eindeutige Index den Partitionierungsschlüssel im Indexschlüssel enthalten. Diese Anforderung ist vorhanden, damit die Engine die Eindeutigkeit von Updates erzwingen kann, ohne jede Partition zu überprüfen.

In Ihrem Fall bedeutet dies, dass Sie OrderDateden nicht gruppierten Indexschlüssel aufnehmen oder einen nicht ausgerichteten Index haben. Beides ist abhängig von Ihren Umständen eine potenziell gültige Auswahl. Um die Ausrichtung beizubehalten, lauten Ihre Tabellen- und Indexdefinitionen wie folgt:

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);

Dies ändert natürlich die Eindeutigkeit, die der nicht gruppierte Index erzwingt. Jetzt ist nur noch die Kombination von OrderIDund OrderDategarantiert einzigartig. Es ist theoretisch möglich, doppelte OrderIDs hinzuzufügen , solange das OrderDateanders ist. Ob diese Änderung der Semantik für Sie akzeptabel ist, hängt von Ihren Umständen ab, aber Sie sollten sich dessen bewusst sein.

Die Alternative besteht darin, den nicht gruppierten Primärschlüssel nicht auszurichten:

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);

Dies bewahrt die Einzigartigkeit von OrderIDallein und hat einige Vorteile bei Abfragen, die mithilfe des Index berechnet MINoder MAXaggregiert werden. Sie verlieren jedoch die Möglichkeit, SWITCHPartitionen ein- und auszuschalten, ohne den Primärschlüssel fallen zu lassen und ihn nach dem Umschaltvorgang neu zu erstellen.

Weitere Informationen zur Partitionierung finden Sie in diesem Abschnitt von Books Online und zu den Themen ausgerichtete und nicht ausgerichtete Indizes in dieser hervorragenden Antwort von Remus Rusanu.

Paul White 9
quelle