提示特性として知られている被写体に関連付け-whichシナリオ分析時間データベース -概念的な観点からは、一方が決定することができる:()「現在」ストーリー版ブログ及び(b)は、「過去」ブログストーリー版、非常にものの似ている、さまざまな種類のエンティティです。
それに加えて、抽象化の論理レベルで作業する場合、異なる種類のファクト(行で表される)を異なるテーブルに保持する必要があります。検討中のケースでは、非常に類似していても、(i)「現在の」バージョンに関する事実は、(ii)「過去の」バージョンに関する事実とは異なります。
したがって、2つのテーブルを使用して状況を管理することをお勧めします。
それぞれ(1)わずかに異なる列数と(2)異なる制約グループを持ちます。
概念層に戻ると、ビジネス環境では、作成者と編集者はユーザーが再生できるロールとして描写できる概念であり、これらの重要な側面はデータの派生に依存すると考えています(論理レベルの操作操作を介して)および解釈(1つまたは複数のアプリケーションプログラムの支援を受けて、コンピューター化された情報システムの外部レベルでBlog Storiesリーダーおよびライターが実行)。
これらすべての要因とその他の関連するポイントを以下に詳述します。
ビジネスルール
お客様の要件を理解した上で、次のビジネスルールの定式化(関連するエンティティタイプとそれらの種類の相互関係の観点からまとめる)は、対応する概念スキーマの確立に特に役立ちます。
- ユーザーは、ゼロ・ワン・オア・多くの書き込みBlogStoriesを
- A BlogStoryはゼロ-1-または-多く保持しているBlogStoryVersionsを
- ユーザーは、ゼロ・ワン・オア・多くの書いたBlogStoryVersionsを
説明的なIDEF1X図
したがって、グラフィカルデバイスを使用して提案を説明するために、上記で定式化されたビジネスルールおよび関連すると思われるその他の機能から派生したダイアグラムIDEF1X のサンプルを作成しました。図1に示します。
BlogStoryとBlogStoryVersionが2つの異なるエンティティタイプとして概念化されるのはなぜですか?
なぜなら:
A BlogStoryVersionのインスタンス(すなわち、「過去」1)は、常にのための値を保持UpdatedDateTimeの一方で、プロパティをBlogStory発生(すなわち、「現在」1)がそれを保持していることはありません。
また、これらのタイプのエンティティは、BlogStoryNumber(BlogStoryオカレンスの場合)、およびBlogStoryNumberとCreatedDateTime(BlogStoryVersionインスタンスの場合)の2つの異なるプロパティセットの値によって一意に識別されます。
インフォメーションモデリングのための統合の定義( IDEF1Xは)として設立された非常にお勧めのデータモデリング技法である標準米国の1993年12月における米国国立標準技術研究所(NIST)。それは著早い理論的な材料に基づいている唯一の発信元のリレーショナルモデル、すなわち、博士はEFコッド。上のエンティティリレーションシップによって開発されたデータのビュー、博士PP・チェン。また、Robert G. Brownが作成したLogical Database Design Techniqueについても。
例示的な論理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
、INTデータ型でPRIMARY KEY(簡潔にするためにPK)列を定義しました。この点で、各行の挿入でそのような列の数値を生成して割り当てる組み込みの自動プロセスを修正することができます。この値のセットに時折ギャップを残しても構わない場合は、MySQL環境で一般的に使用されるAUTO_INCREMENT属性を使用できます。
個々のBlogStory.CreatedDateTime
データポイントをすべて入力する場合、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の一部であることに加えて、これらの2つのテーブルの行間で参照整合性BlogStory.BlogStoryNumber
を強制する構成を参照する外部キー(FK)としても制約されます。この点で、aの自動生成を実装する必要はありません。FKとして設定されるため、この列に挿入される値は、関連するカウンターパートに既に含まれている値から「引き出す」必要があるからです。BlogStoryVersion.BlogStoryNumber
BlogStory.BlogStoryNumber
BlogStoryVersion.UpdatedDateTime
カラムは予想通り、保持する必要があり、時点BlogStory
行が追加、結果として、修正されたBlogStoryVersion
テーブル。したがって、この状況でもNOW()関数を使用できます。
間隔の間に理解BlogStoryVersion.CreatedDateTime
とBlogStoryVersion.UpdatedDateTime
全体の発現期間、その間BlogStory
の行が「有り」または「現在の」であったが。
Version
列に関する考慮事項
考えることが有用でできるBlogStoryVersion.CreatedDateTime
特定の「過去」を表す値を保持列としてバージョンのBlogStoryを。これはa VersionId
やVersionCode
に比べてはるかに有益だと思います。なぜなら、人々は時間の概念に精通しているという意味で、ユーザーにとって使いやすいからです。たとえば、ブログの作成者または読者は、次のような方法でBlogStoryVersionを参照できます。
- 「私は特定の見たいバージョンのBlogStoryで識別番号
1750
れた作成された上26 August 2015
での9:30
」。
著者と編集者の役割:データ導出および解釈
このアプローチを使用すると、MIN()関数をに適用することで、特定のFROMの「最も古い」バージョンを選択AuthorId
する具体的なBlogStoryの「オリジナル」を誰が持っているかを簡単に区別できます。BlogStoryId
BlogStoryVersion
BlogStoryVersion.CreatedDateTime
このように、すべての「後」または「後続」バージョン行にBlogStoryVersion.AuthorId
含まれる各値は、当然、手元の各バージョンの作成者識別子を示しますが、そのような値は、同時に、役割関与によって演じユーザーとしてエディタ「オリジナル」のバージョンのBlogStory。
はい、特定のAuthorId
値は複数のBlogStoryVersion
行で共有できますが、これは実際には各Versionについて非常に重要なことを伝える情報の一部であるため、前述のデータの繰り返しは問題ではありません。
DATETIME列の形式
DATETIMEデータ型については、そうです、「MySQLはDATETIME値を ' YYYY-MM-DD HH:MM:SS
'形式で取得および表示します」が、この方法で適切なデータを自信を持って入力でき、クエリを実行する必要がある場合は組み込みのDATEおよびTIME関数を使用して、とりわけ、ユーザーに適切な形式で関連する値を表示します。または、アプリケーションプログラムコードを介してこの種のデータフォーマットを確実に実行できます。
BlogStory
UPDATE操作の意味
たびにBlogStory
行がUPDATEを受けるには、あなたは確認する必要があります変更が行われたまでは「存在」して対応する値は、その後に挿入されていることをBlogStoryVersion
表。したがって、これらの操作を単一のACID TRANSACTION内で実行して、不可分な作業単位として扱われることを保証することを強くお勧めします。TRIGGERSを採用することもできますが、いわば物事を乱雑にする傾向があります。
VersionId
またはVersionCode
列の紹介
BlogStoryVersionsを区別するためにBlogStory.VersionId
or 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…
。
- 等
単一のテーブルに「オリジナル」バージョンと「後続」バージョンを保持する
すべてのBlogStoryVersionsを同じ個別のベーステーブルで維持することは可能ですが、2つの異なる(概念)タイプのファクトを混合するため、これを行わないことをお勧めします。
- データの制約と操作(論理レベル)、および
- 関連する処理およびストレージ(物理層)。
ただし、その行動方針に従うことを選択した場合は、上記で説明した多くのアイデアを活用できます。例:
- 複合 INTカラム(成るPK
BlogStoryNumber
)およびDATETIMEカラム(CreatedDateTime
)。
- 関連するプロセスを最適化するためのサーバー機能の使用
- 著者と編集者誘導の役割。
このようなアプローチを進めると、「新しい」バージョンが追加されるとすぐにBlogStoryNumber
値が複製され、評価できるオプション(前のセクションで説明したものと非常に似ている)がPKを確立していることがわかります。列で構成して、このようにあなたは一意に識別することができるだろうバージョンのBlogStoryを。そして、あなたはの組み合わせで試すことができますし、あまりにも。BlogStory
BlogStoryNumber
VersionCode
BlogStoryNumber
VersionNumber
同様のシナリオ
このヘルプの質問に対する私の答えを見つけるかもしれません。私は、同様のシナリオに対処するために、関係するデータベースの一時的な機能を有効にすることも提案しているからです。