2

TARGET_RDBMS: MySQL-5.X-InnoDB( "X"は現在の安定版リリースと同じです)

背景:フィードバックを得るために、真の参照整合性制約を使用して最初のデータベースを構築し、「実際の」DDLを作成した後、データベースの「感触」をカバーすると信じる抽象化を行いました。これは、約20の3つのテーブルのみであり、すべて参照整合性制約があります。欠落しているのは複合キーテーブルだけです。このテーブルには、現時点でダンプするデータがないため、最初の反復に焦点を合わせています。

サンプルデータ/単体テスト:私が知らないことの1つは、モデル化された参照整合性を100%カバーするサンプルデータセットを構築する方法です。そして、そのサンプルデータとこのDDLを中心に「単体テスト」を構築します。

サンプルDLL:

(注:明確にするために、LEGENDと命名基準は、この例にすぎません。これは、「実際の」データベースから抽出したものです。列名は、本質的にロボットであり、特定の名前の意味と関係を作成することを目的としています。インスタンスをできるだけ明確にします。使用されている表記システムについて提案がある場合は、コメントしてください。提案を受け付けています。ありがとうございます。)

CREATE DATABASE sampleDB;

use sampleDB;

# ###############
# LEGEND
# - sID = surrogate key
# - nID = natural key
# - cID = common/shared across tables, but NOT unique/natural-key
# - PK = Primary Key
# - FK = Foreign Key
# - data01 = Sample data (non-key,not-shared-across-tables)
# - data02 = Sample data NOT NULL (non-key,not-shared-across-tables)
#
# - uID = user defined unique/natural key (NOTE: not used)

# ###############
# Behavior
# - create_timestamp (NOT NULL, updated on record creation, NOT update)
# - update_timestamp (NOT NULL, updated on record creation AND updates)

CREATE TABLE `TABLE_01` (
  `TABLE_01_sID_PK` MEDIUMINT NOT NULL AUTO_INCREMENT,
  `TABLE_01_cID` int(8) NOT NULL,
  `TABLE_01_data01` varchar(128) default NULL,
  `TABLE_01_data02`  varchar(128) default NULL,
  `create_timestamp` DATETIME DEFAULT NULL,
  `update_timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY  (`TABLE_01_sID_PK`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `TABLE_02` (
  `TABLE_02_sID_PK` MEDIUMINT NOT NULL AUTO_INCREMENT,
  `TABLE_02_nID_FK__TABLE_01_sID_PK` int(8) NOT NULL,
  `TABLE_02_cID` int(8) NOT NULL,
  `TABLE_02_data01` varchar(128) default NULL,
  `TABLE_02_data02` varchar(128) NOT NULL,
  `create_timestamp` DATETIME DEFAULT NULL,
  `update_timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`TABLE_02_sID_PK`),
  FOREIGN KEY (TABLE_02_nID_FK__TABLE_01_sID_PK) REFERENCES TABLE_01(TABLE_01_sID_PK),
  INDEX `TABLE_02_nID_FK__TABLE_01_sID_PK` (`TABLE_02_nID_FK__TABLE_01_sID_PK`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `TABLE_03` (
  `TABLE_03_sID_PK` MEDIUMINT NOT NULL AUTO_INCREMENT,
  `TABLE_03_nID_FK__TABLE_01_sID_PK` int(8) NOT NULL,
  `TABLE_03_nID_FK__TABLE_02_sID_PK` int(8) NOT NULL,
  `TABLE_03_cID` int(8) NOT NULL,
  `TABLE_03_data01` varchar(128) default NULL,
  `TABLE_03_data02` varchar(128) NOT NULL,
  `create_timestamp` DATETIME DEFAULT NULL,
  `update_timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`TABLE_03_sID_PK`),
  FOREIGN KEY (TABLE_03_nID_FK__TABLE_01_sID_PK) REFERENCES TABLE_01(TABLE_01_sID_PK),
  FOREIGN KEY (TABLE_03_nID_FK__TABLE_02_sID_PK) REFERENCES TABLE_02(TABLE_02_sID_PK),
  INDEX `TABLE_03_nID_FK__TABLE_01_sID_PK` (`TABLE_03_nID_FK__TABLE_01_sID_PK`),
  INDEX `TABLE_03_nID_FK__TABLE_02_sID_PK` (`TABLE_03_nID_FK__TABLE_02_sID_PK`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SHOW TABLES;

# DROP DATABASE `sampleDB`;

# #######################
# View table definition
# DESC inserttablename;

# #######################
# View table create statement
# SHOW CREATE TABLE example;

質問:

このデータベース構築を行うための欠落した、間違った、または「より良い」方法に関するあらゆるフィードバックを歓迎します。ご不明な点がございましたら、コメントしてください。できるだけ早く回答いたします。もう一度、ありがとう〜!

更新(1):

PKに「MEDIUMINTNOTNULLAUTO_INCREMENT」を追加したばかりですが、どうやってそれをやめたのかわかりません。

4

1 に答える 1

3

まず、基準を定義してくださったことに拍手を送りたいと思います。将来あなたを助けるためにどれだけそれが来るかには終わりがありません。

そうは言っても、私の側からの非常に主観的な意見がいくつかあります。

「TABLE_PERSON」や「PERSON_T」などの名前に型情報を埋め込むのは好きではありません。代わりに、テーブルをビューに置き換えると混乱するからです。この時点で、もちろん検索して「PERSON_T」を「PERSON_VW」に置き換えることもできますが、ポイントを見逃します:)同じことが列にも当てはまります(ただし、これはあなたの例ではわかりません)。数値からvarcharに変更される「n_is_dead」列について考えてみてください。

行を作成せずにテーブルに存在させることはできますか(create_timestamp)?列を実際にnullにできない場合は、列をNOTNULLとして宣言します。実際、データの性質について考えるのが難しくなるため、ほとんどの列でNOTNULLを使用するようになりました。

私は主キー列にID以外の名前を付けるのが好きです。例えば

company(company_id, etc)
person(person_id, company_id, firstname etc)

O / Rマッパーに問題があり、常に「ID」という名前の主キーを使用する必要があると聞いていますが、これが最近変更された場合、これがまだ当てはまるかどうかはわかりません。

列名に(s、n、c)を埋め込んで、それらが代理、自然、または共通のキーであるかどうかを示すつもりであるかどうかは、私にはわかりません。しかし、これは良い考えではないと思います。これにより、論理モデルに自然に適合しない実装の詳細が「明らかに」なると思います。

列名に外部キー関係を公開/埋め込みしているようです。考えたことはありませんが、後悔していただけると思います。それが列名を耐え難いほど醜くするという理由だけでなく:)

インデックスの名前を選択するとき。インデックスに名前を付けたことを後悔しているのは、実行プランを見て「index_01」が使用されていることを確認したときだけです。xplanで表示できるように、インデックスに列名を入れていたらよかったのにと思います。インデックス名の制限はわかりませんが、Oracleでは常に制限に遭遇します。したがって、テーブル名を短縮する方法についていくつかのルールを考え出すようにしてください。ここで重要なのは列名です。

混合ケースについて。私は常に(例外なく)ALL_UPPER_CASEまたはall_lower_caseのいずれかを使用します。その理由は、過去に、データベース間でクエリを移行するときに、ケースの扱いが異なる場合に、私はやけどを負ったことがあるからです。最近、私はall_lower_caseを使用しています。これは、エディターの一般的なフォントを使用すると、大文字よりも小文字の方がスペルミスを見つけやすくなるためです。そして、私が物事に失敗したとき、編集者が私に叫んでいるようには見えません;)

于 2010-12-03T15:50:47.640 に答える