문제

나는 자신이 사용할 매우 간단한 블로그 엔진을 작성하고 있습니다(내가 만난 모든 블로그 엔진은 너무 복잡하기 때문입니다).나는 다음과 같은 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의 솔루션이 더 적절하다고 생각합니다.그러나 나는 정수 방법을 사용하겠습니다. 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
도움이 되었습니까?

해결책

SQL Server 2008에는 "날짜"라는 새로운 데이터 유형이 있습니다. 해당 열을 사용하여 인덱스를 만들 수 있습니다.

물론 테이블에 계산 된 유형의 "날짜"열을 추가하고 DateTime 열의 날짜 부분을 해당 계산 된 열로 채우고 유지하고 인덱싱 할 수 있습니다. 잘 작동해야합니다!

그런 것 :

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

CREATE UNIQUE INDEX UX_Entries ON Entries(DateOnly, Slug)

마크

다른 팁

2008 년이므로 Marc가 제안한대로 날짜 데이터 유형을 사용하십시오. 그렇지 않으면 더 쉬운 솔루션은 yyyymmdd 형식의 날짜를 사용하는 비 컴퓨터 열 (삽입물에 채워야 함)을 갖는 것입니다. 그것은 정수 데이터 유형이며 작고 사용하기 쉽습니다.

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의 두 필드와 필요한 경우 다시 결합하는 검색 보기로 분할될 수 있습니다. 그러면 날짜 전용 열에 기본 인덱스가 허용됩니다.

(이것은 DateTime을 사용하여 SQL 2005 및 이전 버전에서 구현될 수 있습니다. 단, 날짜 또는 시간에만 약간 사치가 있지만 둘 다는 아닙니다.)

마지막으로 중복된 CompositionDate가 있는 다른 레코드가 존재하지 않도록 강제하는 INSERT/UPDATE 트리거를 사용할 수 있습니다(날짜 부분만).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top