Frage

Ich schreibe eine sehr einfache Blog-Engine für den eigenen Gebrauch (da jeder Blog-Engine die ich gestoßen zu komplex ist). Ich möchte in der Lage sein, um eindeutig jeden Beitrag durch seine URL zu identifizieren, die so etwas wie /2009/03/05/my-blog-post-slug ist. Um es in der Datenebene zu erreichen, mag ich eine Verbindung eindeutige Einschränkung auf (Date, Slug) schaffen, wo Date nur das Datum Teil der Zusammensetzung Datums (die Tageszeit zu ignorieren). Ich habe ein paar Ideen selbst (wie eine andere Spalte, wahrscheinlich berechnet, nur das Datum Teil zu halten), aber ich kam so zu wissen, was ist die beste Praxis, dieses Problem zu lösen.

Ich bezweifle, SQL Server, Version Fragen hier, aber für die Datensätze, ich bin auf 2008 Express (ich eine tragbare Lösung zu schätzen).

Tabellenschema:

create table Entries (
    Identifier int not null identity,
    CompositionDate datetime not null default getdate(),
    Slug varchar(128) not null default '',
    Title nvarchar(max) not null default '',
    ShortBody nvarchar(max) not null default '',
    Body nvarchar(max) not null default '',
    FeedbackState tinyint not null default 0,
    constraint pk_Entries primary key(Identifier),

    constraint uk_Entries unique (Date, Slug) -- the subject of the question
)

Ausgewählte Lösung:

Ich denke, marc-Lösung besser geeignet ist, ist diese Frage unter Berücksichtigung 2008 über Allerdings werde ich mit der Integer-Methode gehen (aber nicht mit INSERTs, da sie nicht die Integrität der Daten nicht gewährleistet, ich werde eine vorberechnete verwenden integer-Spalte), da ich denke, dass es einfacher ist, mit der ganzen Zahl Sache von dem Client (in der Abfrage).

arbeiten

Danke Jungs.

create table Entries (
    Identifier int not null identity,
    CompositionDate smalldatetime not null default getdate(),
    CompositionDateStamp as cast(year(CompositionDate) * 10000 + month(CompositionDate) * 100 + day(CompositionDate) as int) persisted,
    Slug varchar(128) not null default '',
    Title nvarchar(max) not null default '',
    ShortBody nvarchar(max) not null default '',
    Body nvarchar(max) not null default '',
    FeedbackState tinyint not null default 0,
    constraint pk_Entries primary key(Identifier),
    constraint uk_Entries unique (CompositionDateStamp, Slug)
)
go
War es hilfreich?

Lösung

Nun, in SQL Server 2008 gibt es einen neuen Datentyp „DATE“ genannt - Sie diese Spalte verwenden könnte und einen Index für das Erstellen

.

Sie könntest natürlich auch eine berechnete Spalte vom Typ „DATE“ zu Ihrer Tabelle hinzufügen und nur das Datum Teil der DATETIME- Spalte in diese berechnete Spalte füllen, macht es anhielt, und indiziert. Sollte gut funktionieren!

So etwas:

ALTER TABLE dbo.Entries
   ADD DateOnly as CAST(CompositionDate AS DATE) PERSISTED

CREATE UNIQUE INDEX UX_Entries ON Entries(DateOnly, Slug)

Marc

Andere Tipps

Da Sie auf das Jahr 2008 sind, verwenden Sie das Datum Datentyp wie Marc vermuten lässt. Ansonsten ist eine einfachere Lösung, die eine nicht berechnete Spalte haben (was bedeutet, werden Sie es auf einer INSERT bevölkern müssen), die das Datum im Format YYYYMMDD verwendet. Das ist ein Integer-Datentyp und ist klein und einfach zu bedienen.

Für SQL 2005, könnten Sie tun, im Wesentlichen die gleiche Sache, die empfohlen marc_s, benutzen Sie einfach einen Standard-Datetime. Es wäre so etwas wie diese (hier nicht getesteten Code) aussehen:

ALTER TABLE Entries ADD
    JustTheDate AS DATEADD(day, DATEDIFF(day, 0, CompositionDate), 0) NOT NULL PERSISTED

Erstellen Sie dann Ihren Index auf (JustTheDate, Slug)

Hinweis: Die DATEADD / DATEDIFF Aussage dort berechnet nur das Datum der CompositionDate

.

Im Laufe der Jahre haben wir eine Vielzahl von Problemen mit Computed Columns in SQL Server haben, so haben wir mit ihnen gestoppt.

Sie eine Ansicht mit einer Spalte für datum nur nutzen könnten -. Und einen eindeutigen Index der auf dieser Ansicht stellen Spalt

(A möglicherweise nützlicher Nebeneffekt ist, dass Sie die Ansicht, die einige Reihen ausschließen haben können - so könnte man die Dinge umzusetzen wie „DateColumn eindeutig sein muss, aber ausschließen WHERE DateColumn IS NULL)

Die bestehende CompositionDate Spalte könnte in zwei Felder aufgeteilt werden - CompositionDate und CompositionTime - und eine Ansicht abrufen, die sie miteinander verbindet zurück, wenn Sie brauchen, dass - die dann einen nativen Index auf dem Datum geschützte Spalte erlauben würde,

(Dies kann in SQL 2005 und früher mit Datetime umgesetzt werden - wenn auch etwas extravagant nur für das Datum oder Zeit, und nicht beide)

Und schließlich könnten Sie einen INSERT / UPDATE-Trigger, die erzwungen, dass kein anderer Datensatz mit einem doppelten CompositionDate (Datum Teil nur) bestand

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top