一尘不染

如何仅在日期时间的日期部分创建唯一约束?

sql

我正在编写一个非常简单的博客引擎供自己使用(因为我遇到的每个博客引擎都太复杂了)。我希望能够通过类似URL的URL来唯一标识每个帖子/2009/03/05/my- blog-post-slug。为了在数据层中完成此操作,我想对组成日期中仅日期部分(忽略一天中的时间)(Date,Slug)所在的位置创建一个复合唯一约束Date。我本人也有一些想法(例如另一列,可能是计算得出的,仅保留日期部分),但是我来了解一下解决此问题的最佳实践。

我怀疑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的解决方案更合适。但是,我将使用整型方法(但不能使用INSERTs,因为它不能确保数据的完整性;我将使用预先计算的整数列)因为我认为使用来自客户端(在查询中)的整数运算会更容易。

感谢大伙们。

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

阅读 164

收藏
2021-03-17

共1个答案

一尘不染

好吧,在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)
2021-03-17