11

私は自分用に非常に単純なブログ エンジンを作成しています (私が遭遇したすべてのブログ エンジンは複雑すぎるため)。のような URL で各投稿を一意に識別できるようにしたいと考えています/2009/03/05/my-blog-post-slug。データ層でそれを達成するために、構成日の日付部分 (時刻は無視) のみが(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
4

4 に答える 4

13

さて、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)

マルク

于 2009-03-06T21:55:54.317 に答える
2

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

于 2009-03-06T22:10:26.793 に答える
1

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の日付のみを計算します。

于 2009-03-06T22:01:37.220 に答える
0

何年にもわたって、SQL Serverの計算列でさまざまな問題が発生したため、それらの使用を停止しました。

日付のみの列を持つVIEWを使用し、そのVIEWの列に一意のインデックスを付けることができます。

(おそらく有用な副作用は、VIEWに一部の行を除外させることができることです。したがって、「DateColumnは一意である必要がありますが、WHERE DateColumn IS NULLを除外する」などの実装が可能です)

既存のCompositionDate列は、CompositionDateとCompositionTimeの2つのフィールドと、必要に応じてそれらを結合するRetrieve Viewに分割できます。これにより、Date-only列のネイティブインデックスが可能になります。

(これは、DateTimeを使用してSQL 2005以前で実装できます-日付または時刻のみでわずかに贅沢ですが、両方ではありません)

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

于 2009-03-08T12:42:14.380 に答える