web-dev-qa-db-ja.com

これはDBスキーマを構造化するためのばかげた方法ですか、それとも完全に何か不足していますか?

リレーショナルデータベースでかなりの作業を行ったので、優れたスキーマ設計の基本概念をかなりよく理解していると思います。私は最近、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

シンプルでしょ?

コンサルタントは次のように設計しました(サンプルデータを使用)。

UsersTable

UserID  FirstName   LastName
234     John        Doe
516     Jane        Doe
123     Foo         Bar

DepartmentsTable

DepartmentID   Name
1              Sales
2              HR
3              IT

UserDepartmentTable

UserDepartmentID   UserID   Department
1                  234      2
2                  516      2
3                  123      1

RequestTable

RequestID   UserID   <...>
1           516      blah
2           516      blah
3           234      blah

データベース全体はこのように構築され、すべてのデータを独自のテーブルにカプセル化し、数値IDですべてをリンクします。どうやらコンサルタントはOLAPについて読み、「整数ルックアップの速度」を望んでいた

また、これらのすべてのテーブルを相互参照するための多数のストアドプロシージャもあります。

これは中小規模のSQL DBに有効な設計ですか?

コメント/回答をありがとう...

61
Jim

私には完璧な意味があります。これは非常に正規化されたものであり、他の方法では得られないほどの柔軟性をもたらします。非正規化されたデータはお尻の痛みです。

73
Blrfl

私は、WTFが保証されているとか、その男が狂った天才的な種類の設計を行っているとは思いません。これは、かなり標準的なデータベースの正規化です。

部門テーブルの理由は、部門を別のテーブルに配置しない場合、「販売」、「販売」、「販売員」、「セール」、および「販売」部門のユーザーを処理する必要があるためです。あなたがそれを防ぐために何かをしない限り。そして、追加のテーブルを持つことは、私が知っている最良の方法(の一部)です。

UserDepartmentテーブルが存在する必要があるかどうかは、より厳しい呼び出しです。これは、当然、どちらの決定も狂っていないという意味ではありません。一方で、すべてのテーブルデザインとロジックがユーザーごとに1つの部署を想定し、それが変更された場合、それは苦痛です。他方、何年にもわたって理由もなく追加の結合を行うことは、実際の可能性であり、苦痛でもあります。

個人的には、UserDepartmentテーブルは多すぎると思います。それが含まれている場合でも、時間の経過に伴い、部門ごとにユーザーが1人だけであると想定してクエリが作成される可能性があるため、両方の世界で最悪の結果になる-テーブルを必要とする前に理由もなく余分な結合いずれにしても、ユーザーごとに複数の部門が許可されるとコードが機能しなくなります。

編集-多対多の関係をサポートする必要があるかどうかの主要なドライバーは、ビジネスルールが明確であるかどうかです。複数の部門のユーザーがどのように機能するかさえわからない場合は、コードがユーザーが複数の部門にいる場合を正しく処理できない可能性があるため、テーブルを追加しても意味がありません。

念のため、ユーザーごとに多くの部門を許可したとします。次に、部門に基づいてコミッションを割り当てるためのビジネスルールを実装しました。その後、複数の部門が許可されました。幸いなことに、これを考慮した方法でコミッションコードを書くこともできました。残念ながら、両方のユーザーに各部門からのコミッションを追加しました。経営陣は、販売ごとに人の役割に基づいてほしいと考えました。それで、事前にテーブルを持っていることはどれほど良かったですか? 「念のため」に、まったく必要のない他のテーブルについてはどうですか?

後の編集-コンサルタントがこれらすべての中間テーブルを追加したいと思ったもう1つの理由は このフォローアップの質問 で対処されています。これに対する答えは、データベースのリファクタリングが通常、コードのリファクタリングよりも難しい理由です。これは、「必要になる可能性のあるすべてのテーブルに入力する」アプローチに向かわせる傾向があります。

48
psr

ユーザーごとに複数の部門を持つことが要件である場合、この設計は理にかなっています。それについての唯一の不満は、不要なサロゲートキーUserDepartmentTableがあるUserDepartmentIDです(UserIdDepartmentIdを複合主キーにするだけです)。

ユーザーが1つの部門にのみ属している場合、設計は理にかなっています(ただし、部門のルックアップテーブルは引き続き有効です)。

14
Oded

いくつかの要件はあなたの質問で明確ではありません。正しい答えは、お客様が何を望んでいるかによって異なります。私があなただったら、これについてお客様に尋ねます。

0-ユーザーと従業員の違いは何ですか?

1-employee = userを想定して、従業員が部門を変更した場合はどうなりますか?

2-従業員のグループが1つの要求を行うことはできますか?

3-従業員は複数の部門に所属できますか? CEOはどうですか

4-リクエストを行うことが許可されている従業員のサブセットはありますか?

5-(もしあれば)従業員レコードが削除されると、リクエストはどうなりますか?

6-リクエストを削除できますか?リクエストが削除されるとどうなりますか(RIによって従業員レコードを削除しないようにしてください)

7-従業員が「同じ」リクエストを複数回行うことができますか(「同じ」を定義します)

8-従業員が退職したときのリクエストの処理方法(リクエストをキャンセルするか、リクエストを削除しますか?)

さらに質問があるかもしれませんが、私のポイントは、解決策は正確な要件とプロジェクトの範囲に依存するということです。それが決定したら、スキーマを直接導出できます。したがって、提示された両方のソリューションは正しいかもしれません。

5
NoChance

給与の高いコンサルタントが行った方法で結合テーブルを使用することの潜在的な利点のいくつかについて明示的に述べた、いくつかのポイントフォームのメモを追加したいと思います。

  • 適切にインデックスが作成されている場合(たとえば、UserDepartmentTableが2つの外部キーにインデックスを作成している場合)、外部キーが一意でないため、このような結合テーブルのパフォーマンスはわずかしか失われません。外部キーが一意であることが保証されている場合、私が知っている小さなデータベース理論によると、UserDepartmentTable.Departmentの検索は、Userテーブルの他の列を検索するよりも「難しく」ありません。
  • 結合テーブルを使用すると、ユーザーと部門間の関連付けに関するその他の情報(作成時のタイムスタンプなど)をより柔軟に設定できます。
  • 結合テーブルを使用すると、関連付けをかなり簡単に「バージョン管理」できます(たとえば、ユーザーが部門を変更した場合、UserDepartmentTable.Activeなどのインデックスブールフラグをfalseにトリガーし、アクティブな新しい関連付けを作成します)。 2テーブルモデル(ユーザーと部門のみ)を使用して部門の関連付けのバージョン管理を行うこともできますが、主キーの重複を避けるために、タフで、少なくとも1つの列を追加するか、データベースアクロバットを実行する必要があります。
  • これにより、1対多または多対1または多対多の関連付けを非常に簡単に割り当てることができます。

そうは言っても、あなたの高額なコンサルタントがやったことをしない理由はいくつかあります。

  • 上記のすべての利点はすべて、将来のニーズの予測であり、現在の状況では複雑すぎます。 YAGNIに準拠していません。 。 2テーブルモデルから結合テーブルモデルに移行する移行を作成することは、後で簡単に困難になります。ビジネスニーズが発生したときに、それを行うことができます。その前にそれを行うのは混乱する可能性があります。
  • 他の開発者を混乱させます。はい、私はあなたの身長(コンサルタントの決定を検討している)のWeb開発者への期待は結合テーブルを理解して認識することですが、それは必要以上に複雑であり、ビジネスニーズの欠如を考慮します、それは混乱を引き起こします。
1
Steven

必要な情報の完全な構造がなければ、私はそれが恐ろしいかどうかは言えません。しかし、少なくとも示されている作品は「WTF」デザインのものではありません。それはちょうどデータ構造の第3正規形のようです(まあ、理論的には第4と第5もあります)

一部のトークは、表示されている部分の「自然」キーと「人工」キーの2つの学校の間にUserDepartmentTableの場所を置くことができます。私が見ることができるように、これ以上はありません

正規化は、多くの理由から、優れたDB開発者/設計者のルールです。* de *正規化は、開発の途中で、ほとんどの場合、速度を上げるために使用されます

0
Lazy Badger