선물 특성으로 알려진 주제와 관련된 - 어떤 시나리오 분석 시간 데이터베이스 - 개념의 관점에서를, 하나는 결정할 수 : (a)는 "현재 ' 스토리 버전 블로그 와 (b)는"과거 " 블로그 스토리 버전을 매우 비록 서로 다른 유형의 엔티티입니다.
또한 논리적 추상화 레벨에서 작업 할 때 고유 한 종류의 사실 (행으로 표시됨)을 고유 한 테이블에 보유해야합니다. 고려중인 경우, 상당히 유사하더라도 (i)“현재” 버전 에 대한 사실은 (ii)“과거” 버전에 대한 사실과 다릅니다 .
따라서 두 테이블을 사용하여 상황을 관리하는 것이 좋습니다.
각각 (1) 약간 다른 수의 열과 (2) 다른 제약 조건 그룹이 있습니다.
개념적 계층으로 돌아가서 비즈니스 환경에서 작성자 와 편집자 는 사용자 가 수행 할 수있는 역할 로 묘사 될 수있는 개념 이며, 이러한 중요한 측면은 데이터 파생 (논리 수준 조작 조작을 통해) 에 따라 다릅니다. 및 해석 (에 의해 실시 블로그 사례 하나 개 이상의 응용 프로그램의 도움으로, 전산 정보 시스템의 외부 수준에서, 독자와 작가).
이러한 모든 요소와 기타 관련 사항을 다음과 같이 자세히 설명하겠습니다.
비즈니스 규칙
귀하의 요구 사항에 대한 나의 이해에 따르면, 다음과 같은 비즈니스 규칙 공식 (관련 엔티티 유형 및 해당 상호 관계의 종류로 정리)은 해당 개념 스키마 를 설정하는 데 특히 도움이됩니다 .
- 사용자는 제로 하나 또는-많은 기록 BlogStories을
- BlogStory은 제로 일 또는 일대 보유 BlogStoryVersions을
- 사용자가 제로 일 또는 일대 다 쓴 BlogStoryVersions을
설명 IDEF1X 다이어그램
따라서 그래픽 디바이스 인하여 내 제안을 상세히 설명하기 위해, I 샘플 IDEF1X 작성한 관련된 것 이상으로 비지니스 규칙 제형 및 다른 특징으로부터 도출된다 다이어그램. 그것은에 나타낸다 도 1 :
왜 BlogStory 와 BlogStoryVersion 이 두 개의 다른 엔티티 유형으로 개념화됩니까?
때문에:
BlogStoryVersion의 경우 (즉, "과거"한) 항상 값 보유 UpdatedDateTime에 잠시 속성을 BlogStory 발생이 (즉, "현재"사람이) 결코를 보유하지 않습니다.
또한 해당 유형의 엔티티는 BlogStoryNumber ( BlogStory 발생의 경우) 및 BlogStoryNumber 와 CreatedDateTime ( BlogStoryVersion 인스턴스 의 경우)이라는 두 가지 고유 한 특성 세트 값으로 고유하게 식별됩니다 .
정보 모델링을위한 통합 정의 ( IDEF1X는 )이 설립되었다 매우 추천 할 데이터 모델링 기술이다 표준 미국 12 월 1993 년 국립 표준 기술 연구소 (NIST). 그것은 초기의 이론적 자료에 근거은에 의해 작성된 유일한 발신자 의 관계형 모델 즉, 박사 EF 커드 ; 온 개체 - 관계 에 의해 개발 된 데이터의보기 박사 PP 첸 ; 또한 Robert G. Brown이 만든 논리 데이터베이스 디자인 기술에 대해서도 설명합니다.
예시적인 논리적 SQL-DDL 레이아웃
그런 다음 이전에 제시 한 개념적 분석을 기반으로 아래에서 논리적 수준 설계를 선언했습니다.
-- You should determine which are the most fitting
-- data types and sizes for all your table columns
-- depending on your business context characteristics.
-- Also you should make accurate tests to define the most
-- convenient index strategies at the physical level.
-- As one would expect, you are free to make use of
-- your preferred (or required) naming conventions.
CREATE TABLE UserProfile (
UserId INT NOT NULL,
FirstName CHAR(30) NOT NULL,
LastName CHAR(30) NOT NULL,
BirthDate DATETIME NOT NULL,
GenderCode CHAR(3) NOT NULL,
UserName CHAR(20) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT UserProfile_PK PRIMARY KEY (UserId),
CONSTRAINT UserProfile_AK1 UNIQUE ( -- Composite ALTERNATE KEY.
FirstName,
LastName,
BirthDate,
GenderCode
),
CONSTRAINT UserProfile_AK2 UNIQUE (UserName) -- ALTERNATE KEY.
);
CREATE TABLE BlogStory (
BlogStoryNumber INT NOT NULL,
Title CHAR(60) NOT NULL,
Content TEXT NOT NULL,
CoverImageName CHAR(30) NOT NULL,
IsActive BIT(1) NOT NULL,
AuthorId INT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT BlogStory_PK PRIMARY KEY (BlogStoryNumber),
CONSTRAINT BlogStory_AK UNIQUE (Title), -- ALTERNATE KEY.
CONSTRAINT BlogStoryToUserProfile_FK FOREIGN KEY (AuthorId)
REFERENCES UserProfile (UserId)
);
CREATE TABLE BlogStoryVersion (
BlogStoryNumber INT NOT NULL,
CreatedDateTime DATETIME NOT NULL,
Title CHAR(60) NOT NULL,
Content TEXT NOT NULL,
CoverImageName CHAR(30) NOT NULL,
IsActive BIT(1) NOT NULL,
AuthorId INT NOT NULL,
UpdatedDateTime DATETIME NOT NULL,
--
CONSTRAINT BlogStoryVersion_PK PRIMARY KEY (BlogStoryNumber, CreatedDateTime), -- Composite PK.
CONSTRAINT BlogStoryVersionToBlogStory_FK FOREIGN KEY (BlogStoryNumber)
REFERENCES BlogStory (BlogStoryNumber),
CONSTRAINT BlogStoryVersionToUserProfile_FK FOREIGN KEY (AuthorId)
REFERENCES UserProfile (UserId),
CONSTRAINT DatesSuccession_CK CHECK (UpdatedDateTime > CreatedDateTime) --Let us hope that MySQL will finally enforce CHECK constraints in a near future version.
);
MySQL 5.6에서 실행 되는이 SQL Fiddle에서 테스트 되었습니다 .
BlogStory
테이블
데모 디자인에서 볼 수 있듯이 BlogStory
PRINTARY KEY (PK 간결) 열을 INT 데이터 유형으로 정의했습니다. 이와 관련하여 모든 행 삽입에서 이러한 열에 숫자 값을 생성하고 지정하는 기본 제공 자동 프로세스를 수정하려고 할 수 있습니다. 이 값 집합에서 간헐적으로 공백을 남기지 않으려면 MySQL 환경에서 일반적으로 사용되는 AUTO_INCREMENT 속성을 사용할 수 있습니다.
모든 개별 BlogStory.CreatedDateTime
데이터 포인트를 입력 할 때 NOW () 함수를 사용할 수 있습니다. NOW () 함수 는 정확한 INSERT 조작 순간에 데이터베이스 서버에서 현재 날짜 및 시간 값을 리턴합니다 . 나 에게이 연습은 외부 루틴을 사용하는 것보다 결정적으로 더 적합하고 오류가 덜 발생합니다.
(현재 제거 된) 주석에서 설명한대로 BlogStory.Title
중복 값 을 유지할 가능성을 피하려면 이 열에 대해 UNIQUE 제약 조건 을 설정해야합니다 . 주어진 제목 이 여러 개의 (또는 모든) "과거" BlogStoryVersions에 의해 공유 될 수 있기 때문에 열에 대해 UNIQUE 제약 조건을 설정 하지 않아야 합니다 BlogStoryVersion.Title
.
“소프트”또는“논리적”DELETE 기능을 제공해야하는 경우를 대비 하여 BIT (1)BlogStory.IsActive
유형 의 열 ( TINYINT 도 사용 가능)을 포함 시켰습니다 .
BlogStoryVersion
테이블 에 대한 세부 사항
한편, BlogStoryVersion
테이블 의 PK는 물론 (a) BlogStoryNumber
와 (b)로 명명 된 열로 구성되며 CreatedDateTime
, 물론 BlogStory
행이 INSERT를 거친 정확한 순간을 표시합니다 .
BlogStoryVersion.BlogStoryNumber
는 PK의 일부일뿐 아니라이 두 테이블의 행 사이에 참조 무결성BlogStory.BlogStoryNumber
을 강제하는 구성 인을 참조하는 FORKNK (FK)로 제한됩니다 . 이와 관련 하여 FK로 설정하면이 열에 INSERT 된 값이 관련 상대방 에 이미 포함 된 값에서 "인출"되어야하므로 자동 생성 a를 구현할 필요가 없습니다 .BlogStoryVersion.BlogStoryNumber
BlogStory.BlogStoryNumber
BlogStoryVersion.UpdatedDateTime
열이 예상대로 유지해야하는 시점에 BlogStory
로우가 추가, 결과적으로 수정 된 BlogStoryVersion
테이블. 따라서이 상황에서도 NOW () 함수를 사용할 수 있습니다.
간격 간의 이해 BlogStoryVersion.CreatedDateTime
및 BlogStoryVersion.UpdatedDateTime
전체 표현 기간 동안 BlogStory
행 "본"또는 "현재"하였다.
Version
열에 대한 고려 사항
생각하는 것이 유용 할 수 있습니다 BlogStoryVersion.CreatedDateTime
특정 "과거"나타내는 값 보유하고있는 열로 버전 의 BlogStory을 . 사람들이 시간 개념에 더 익숙한 경향이 있다는 점에서 사용자에게 친숙하기 때문에 나는 VersionId
or 보다 훨씬 더 유익하다고 생각합니다 . 예를 들어 블로그 작성자 또는 독자 는 다음과 유사한 방식 으로 BlogStoryVersion 을 참조 할 수 있습니다 .VersionCode
- "나는 특정보고 싶어 버전 의 BlogStory 식별 번호
1750
되었다 만든 에서 26 August 2015
시를 9:30
".
저자 와 편집자의 역할 : 데이터 유도 및 해석
이 방법, 당신은 쉽게 "원래"보유하고있는 구별 할 수 AuthorId
콘크리트의 BlogStory 은 "최초"를 선택 버전 특정의를 BlogStoryId
으로부터 BlogStoryVersion
인가 덕분에 테이블 MIN () 함수 로를 BlogStoryVersion.CreatedDateTime
.
이런 식으로, 모든 "나중"또는 "성공" 버전 행에 BlogStoryVersion.AuthorId
포함 된 각 값 은 당연히 각 버전 의 작성자 식별자를 나타내지 만, 이러한 값은 동시에 역할 침범에 의해 연주 사용자 로 편집기 은 "원래"의 버전 의 BlogStory .
예, 주어진 AuthorId
값은 여러 BlogStoryVersion
행 으로 공유 될 수 있지만 실제로는 각 버전 에 대해 매우 중요한 정보를 알려주는 정보 이므로 해당 데이텀의 반복은 문제 가 되지 않습니다 .
DATETIME 열의 형식
DATETIME 데이터 유형에 관해서는 그렇습니다.“ MySQLYYYY-MM-DD HH:MM:SS
은 DATETIME 값을 ' '형식으로 검색하여 표시합니다. ' 이지만이 방법으로 관련 데이터를 자신있게 입력 할 수 있으며 쿼리를 수행해야 할 때 내장 된 DATE 및 TIME 함수 를 사용하여 관련 값을 사용자에게 적합한 형식으로 표시하십시오. 또는 애플리케이션 프로그램 코드를 통해 이러한 종류의 데이터 형식을 수행 할 수도 있습니다.
BlogStory
UPDATE 조작의 의미
• 그래도 때마다 BlogStory
행에 UPDATE를 앓고, 당신은 확인해야 수정이 발생한 때까지 "현재"했다 대응하는 값은 다음에 삽입되는 BlogStoryVersion
테이블. 따라서 단일 ACID 거래 내에서 이러한 작업을 수행 하여 개별 작업 단위로 취급되도록하는 것이 좋습니다 . TRIGGERS를 채용 할 수도 있지만 말을하기에는 어수선한 경향이 있습니다.
VersionId
또는 VersionCode
열 소개
BlogStoryVersions 를 구별하기 위해 (비즈니스 환경 또는 개인 선호로 인해) BlogStory.VersionId
또는 BlogStory.VersionCode
열을 통합하도록 선택 하면 다음 가능성을 고려해야합니다.
A VersionCode
는 (i) 전체 BlogStory
테이블과 (ii)에서 고유해야합니다 BlogStoryVersion
.
따라서 각 값 을 생성하고 할당하려면 신중하게 테스트되고 완전히 신뢰할 수있는 방법 을 구현 해야Code
합니다.
어쩌면 VersionCode
값이 다른 BlogStory
행 에서 반복 될 수 는 있지만 결코 같은 행과 중복 되지는 않습니다BlogStoryNumber
. 예를 들어 다음과 같은 이점이 있습니다.
- BlogStoryNumber
3
- 버전83o7c5c
동시에,
- BlogStoryNumber
86
- 버전83o7c5c
및
- BlogStoryNumber
958
- 버전83o7c5c
.
후자의 가능성은 또 다른 대안을 엽니 다.
유지 VersionNumber
에 대한 것은 BlogStories
, 그래서이있을 수 있습니다 :
- BlogStoryNumber-
23
버전1, 2, 3…
;
- BlogStoryNumber-
650
버전1, 2, 3…
;
- BlogStoryNumber-
2254
버전1, 2, 3…
;
- 기타
단일 테이블에 "원본"및 "후속"버전 유지
모든 BlogStoryVersion 을 동일한 개별 기본 테이블 에 유지하는 것이 가능하지만 두 가지 구별되는 (개념적) 유형의 사실을 혼합하므로 바람직하지 않은 부작용이 있으므로 수행하지 않는 것이 좋습니다.
- 데이터 제약 및 조작 (논리 수준에서)
- 관련 처리 및 저장 (물리적 계층)
그러나 해당 행동 과정을 따르기로 선택한 경우에도 위에서 설명한 여러 가지 아이디어를 활용할 수 있습니다.
- 복합 지능 컬럼 (이루어진 PK
BlogStoryNumber
) 및 DATETIME 컬럼 ( CreatedDateTime
);
- 적절한 프로세스를 최적화하기위한 서버 기능 의 사용
- 저자 와 편집자 유도 역할 .
이러한 접근 방식을 진행함으로써 “최신” 버전 이 추가 되 자마자 BlogStoryNumber
값이 복제 되고 평가할 수있는 옵션 (이전 섹션에서 언급 한 것과 매우 유사 함)이 PK를 설정한다는 것을 알 수 있습니다. 열로 구성 하고 , 이러한 방식으로는 유일하게 각 식별 할 수있을 것입니다 버전 의 BlogStory을 . 그리고 당신은의 조합으로 시도 할 수 및 도.BlogStory
BlogStoryNumber
VersionCode
BlogStoryNumber
VersionNumber
비슷한 시나리오
관련 데이터베이스에서 일시적인 기능을 사용하여 비슷한 시나리오를 처리 할 수 있도록 제안 하기 때문에이 도움말 질문 에 대한 답변을 찾을 수 있습니다 .