質問

私は自分で使用するための非常にシンプルなブログエンジンを書いています(遭遇したすべてのブログエンジンは複雑すぎるため)。 / 2009/03/05 / my-blog-post-slug のようなURLで各投稿を一意に識別できるようにしたいと思います。データ層でそれを実現するために、(Date、Slug)に複合ユニーク制約を作成します。 Date は日付部分のみです(時刻は無視します)作成日。私は自分でいくつかのアイデアを持っています(おそらく計算された、日付部分のみを保持する別のコラムのように)が、この問題を解決するためのベストプラクティスは何かを知るためにSOに来ました。

ここではSQL Serverのバージョンが重要ではないかと思いますが、記録のために2008 Expressを使用しています(よりポータブルなソリューションに感謝します)。

テーブルスキーマ:

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
)

選択したソリューション:

この質問は2008年頃だと考えて、marcのソリューションの方が適切だと思います。ただし、整数メソッドを使用します(ただし、 INSERT は使用しません。データ;事前に計算された整数列を使用します)クライアント(クエリ)からの整数値を扱う方が簡単だと思うので、

ありがとうございます。

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
役に立ちましたか?

解決

まあ、SQL Server 2008には、" DATE"と呼ばれる新しいデータ型があります。 -その列を使用して、その列にインデックスを作成できます。

もちろん、" DATE"型の計算列を追加することもできます。テーブルに追加し、DATETIME列の日付部分をその計算列に入力し、PERSISTEDにして、インデックスを作成します。うまくいくはずです!

そのようなもの:

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

CREATE UNIQUE INDEX UX_Entries ON Entries(DateOnly, Slug)

マーク

他のヒント

2008年になったので、Marcが示唆するようにDateデータ型を使用します。それ以外の場合、YYYYMMDD形式の日付を使用する計算されていない列(INSERTで入力する必要があることを意味します)を使用する方が簡単です。これは整数データ型であり、小さくて使いやすいです。

SQL 2005の場合、marc_sが推奨するものと基本的に同じことを行うことができます。標準のDateTimeを使用するだけです。これは次のようになります(テストされていないコードはこちら):

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

次に(JustTheDate、Slug)にインデックスを作成します

注:そこにあるDATEADD / DATEDIFFステートメントは、CompositionDateの日付のみを計算します。

長年にわたり、SQL Serverの計算列にはさまざまな問題があったため、使用を停止しました。

日付のみの列でVIEWを使用し、そのVIEWの列に一意のインデックスを配置できます。

(おそらく有用な副作用は、VIEWで一部の行を除外できることです。したがって、" DateColumnは一意である必要がありますが、WHERE DateColumn IS NULLは除外できます)

既存のCompositionDate列は、CompositionDateとCompositionTimeの2つのフィールドと、必要に応じてそれらを結合するRetrieveビューに分割できます。これにより、日付のみの列にネイティブインデックスが許可されます

(これは、DateTimeを使用してSQL 2005以前で実装できます-ただし、DateまたはTimeの両方ではなく、両方でわずかに贅沢です)

そして最後に、重複したCompositionDate(日付部分のみ)を持つ他のレコードが存在しないことを強制するINSERT / UPDATEトリガーを使用できます

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top