Pergunta

Eu estou escrevendo um mecanismo de blog muito simples para uso próprio (uma vez que cada mecanismo de blog que eu encontrei é muito complexo). Eu quero ser capaz de identificar cada mensagem por seu URL, que é algo como /2009/03/05/my-blog-post-slug. Para realizá-lo na camada de dados, eu quero criar uma restrição exclusiva composto em (Date, Slug) onde Date é apenas a parte de data (ignorando a hora do dia) da data de composição. Eu tenho algumas idéias me (como outra coluna, provavelmente calculados, para manter apenas a parte de data), mas eu vim para SO para saber o que é a melhor prática para resolver este problema.

Eu duvido assuntos versão do SQL Server aqui, mas para os registros, eu estou no 2008 Express (eu aprecio uma solução mais portátil).

Esquema da tabela:

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
)

Solução selecionada:

Eu acho que a solução da marc é mais apropriado, considerando esta pergunta é sobre 2008. No entanto, eu vou com o método inteiro (mas não com INSERTs, pois não garante a integridade dos dados, eu vou usar um pré-computados coluna inteira) desde que eu acho que é mais fácil trabalhar com a coisa inteira a partir do cliente (na consulta).

Obrigado rapazes.

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
Foi útil?

Solução

Bem, no SQL Server 2008, há um novo tipo de dados chamado de "DATA" -. Você poderia usar essa coluna e criar um índice em que

Você poderia naturalmente também adicionar uma coluna computada do tipo "DATE" à sua mesa e basta preencher a parte de data da coluna DATETIME em que coluna computada, torná-lo persistiu, e indexá-lo. Deve funcionar muito bem!

Algo assim:

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

CREATE UNIQUE INDEX UX_Entries ON Entries(DateOnly, Slug)

Marc

Outras dicas

Uma vez que você está em 2008, use o tipo de dados Data como Marc sugere. Caso contrário, uma solução mais fácil é ter uma coluna não-computadorizada (que significa que você tem que preenchê-lo em um INSERT) que utiliza a data no formato AAAAMMDD. Esse é um tipo de dados inteiro e é pequeno e fácil de usar.

Para o SQL 2005, você poderia fazer essencialmente a mesma coisa que marc_s recomendado, basta usar um DateTime padrão. Seria algo parecido com isto (código não testado aqui):

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

Em seguida, crie o seu índice em (JustTheDate, Slug)

Nota:. A declaração DATEADD / DATEDIFF não calcula apenas a data da CompositionDate

Ao longo dos anos nós tivemos uma variedade de problemas com colunas calculado em SQL Server, por isso parei de usá-los.

Você pode usar uma exibição com uma coluna para a data-only -. E colocar um índice exclusivo na coluna que de VISTA

(A efeito colateral possivelmente útil é que você pode ter a visão excluir algumas linhas - para que você possa implementar coisas como "DateColumn deve ser exclusivo, mas excluem ONDE DateColumn IS NULL)

A coluna CompositionDate existente poderia ser dividido em dois campos - CompositionDate e CompositionTime - e uma Recuperar Ver que os une novamente juntos se precisar que - o que, em seguida, permitir que um índice nativa na coluna só de data

(Isso pode ser implementado no SQL 2005 e anteriores usando DateTime - embora um pouco extravagante para apenas a data ou hora, e não tanto)

E por último você poderia ter um gatilho INSERT / UPDATE que forçada que nenhum outro registro existiu com um CompositionDate duplicado (data única parte)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top