リレーショナルデータベースでかなりの作業を行ったので、優れたスキーマ設計の基本概念をかなりよく理解していると思います。私は最近、DBが高額なコンサルタントによって設計されたプロジェクトの引き継ぎを任されました。私の直感が本能かどうか教えてください-「WTF ??!?」 -正当なのか、それともこの男は私の領域外で活動しているほどの天才なのか?
問題のDBは、従業員からのリクエストを入力するために使用される社内アプリです。その小さなセクションを見るだけで、ユーザーに関する情報と、行われた要求に関する情報が得られます。私はこれを次のように設計します:
UserID (primary Key, indexed, no dupes)
FirstName
LastName
Department
RequestID (primary Key, indexed, no dupes)
<...> various data fields containing request details
UserID -- foreign key associated with User table
シンプルでしょ?
コンサルタントは次のように設計しました(サンプルデータを使用)。
UserID FirstName LastName
234 John Doe
516 Jane Doe
123 Foo Bar
DepartmentID Name
1 Sales
2 HR
3 IT
UserDepartmentID UserID Department
1 234 2
2 516 2
3 123 1
RequestID UserID <...>
1 516 blah
2 516 blah
3 234 blah
データベース全体はこのように構築され、すべてのデータを独自のテーブルにカプセル化し、数値IDですべてをリンクします。どうやらコンサルタントはOLAPについて読み、「整数ルックアップの速度」を望んでいた
また、これらのすべてのテーブルを相互参照するための多数のストアドプロシージャもあります。
これは中小規模のSQL DBに有効な設計ですか?
コメント/回答をありがとう...
私には完璧な意味があります。これは非常に正規化されたものであり、他の方法では得られないほどの柔軟性をもたらします。非正規化されたデータはお尻の痛みです。
私は、WTFが保証されているとか、その男が狂った天才的な種類の設計を行っているとは思いません。これは、かなり標準的なデータベースの正規化です。
部門テーブルの理由は、部門を別のテーブルに配置しない場合、「販売」、「販売」、「販売員」、「セール」、および「販売」部門のユーザーを処理する必要があるためです。あなたがそれを防ぐために何かをしない限り。そして、追加のテーブルを持つことは、私が知っている最良の方法(の一部)です。
UserDepartmentテーブルが存在する必要があるかどうかは、より厳しい呼び出しです。これは、当然、どちらの決定も狂っていないという意味ではありません。一方で、すべてのテーブルデザインとロジックがユーザーごとに1つの部署を想定し、それが変更された場合、それは苦痛です。他方、何年にもわたって理由もなく追加の結合を行うことは、実際の可能性であり、苦痛でもあります。
個人的には、UserDepartmentテーブルは多すぎると思います。それが含まれている場合でも、時間の経過に伴い、部門ごとにユーザーが1人だけであると想定してクエリが作成される可能性があるため、両方の世界で最悪の結果になる-テーブルを必要とする前に理由もなく余分な結合いずれにしても、ユーザーごとに複数の部門が許可されるとコードが機能しなくなります。
編集-多対多の関係をサポートする必要があるかどうかの主要なドライバーは、ビジネスルールが明確であるかどうかです。複数の部門のユーザーがどのように機能するかさえわからない場合は、コードがユーザーが複数の部門にいる場合を正しく処理できない可能性があるため、テーブルを追加しても意味がありません。
念のため、ユーザーごとに多くの部門を許可したとします。次に、部門に基づいてコミッションを割り当てるためのビジネスルールを実装しました。その後、複数の部門が許可されました。幸いなことに、これを考慮した方法でコミッションコードを書くこともできました。残念ながら、両方のユーザーに各部門からのコミッションを追加しました。経営陣は、販売ごとに人の役割に基づいてほしいと考えました。それで、事前にテーブルを持っていることはどれほど良かったですか? 「念のため」に、まったく必要のない他のテーブルについてはどうですか?
後の編集-コンサルタントがこれらすべての中間テーブルを追加したいと思ったもう1つの理由は このフォローアップの質問 で対処されています。これに対する答えは、データベースのリファクタリングが通常、コードのリファクタリングよりも難しい理由です。これは、「必要になる可能性のあるすべてのテーブルに入力する」アプローチに向かわせる傾向があります。
ユーザーごとに複数の部門を持つことが要件である場合、この設計は理にかなっています。それについての唯一の不満は、不要なサロゲートキーUserDepartmentTable
があるUserDepartmentID
です(UserId
とDepartmentId
を複合主キーにするだけです)。
ユーザーが1つの部門にのみ属している場合、設計は理にかなっています(ただし、部門のルックアップテーブルは引き続き有効です)。
いくつかの要件はあなたの質問で明確ではありません。正しい答えは、お客様が何を望んでいるかによって異なります。私があなただったら、これについてお客様に尋ねます。
0-ユーザーと従業員の違いは何ですか?
1-employee = userを想定して、従業員が部門を変更した場合はどうなりますか?
2-従業員のグループが1つの要求を行うことはできますか?
3-従業員は複数の部門に所属できますか? CEOはどうですか
4-リクエストを行うことが許可されている従業員のサブセットはありますか?
5-(もしあれば)従業員レコードが削除されると、リクエストはどうなりますか?
6-リクエストを削除できますか?リクエストが削除されるとどうなりますか(RIによって従業員レコードを削除しないようにしてください)
7-従業員が「同じ」リクエストを複数回行うことができますか(「同じ」を定義します)
8-従業員が退職したときのリクエストの処理方法(リクエストをキャンセルするか、リクエストを削除しますか?)
さらに質問があるかもしれませんが、私のポイントは、解決策は正確な要件とプロジェクトの範囲に依存するということです。それが決定したら、スキーマを直接導出できます。したがって、提示された両方のソリューションは正しいかもしれません。
給与の高いコンサルタントが行った方法で結合テーブルを使用することの潜在的な利点のいくつかについて明示的に述べた、いくつかのポイントフォームのメモを追加したいと思います。
UserDepartmentTable.Department
の検索は、User
テーブルの他の列を検索するよりも「難しく」ありません。UserDepartmentTable.Active
などのインデックスブールフラグをfalseにトリガーし、アクティブな新しい関連付けを作成します)。 2テーブルモデル(ユーザーと部門のみ)を使用して部門の関連付けのバージョン管理を行うこともできますが、主キーの重複を避けるために、タフで、少なくとも1つの列を追加するか、データベースアクロバットを実行する必要があります。そうは言っても、あなたの高額なコンサルタントがやったことをしない理由はいくつかあります。
必要な情報の完全な構造がなければ、私はそれが恐ろしいかどうかは言えません。しかし、少なくとも示されている作品は「WTF」デザインのものではありません。それはちょうどデータ構造の第3正規形のようです(まあ、理論的には第4と第5もあります)
一部のトークは、表示されている部分の「自然」キーと「人工」キーの2つの学校の間にUserDepartmentTableの場所を置くことができます。私が見ることができるように、これ以上はありません
正規化は、多くの理由から、優れたDB開発者/設計者のルールです。* de *正規化は、開発の途中で、ほとんどの場合、速度を上げるために使用されます