1

次のような方法でエンティティ (たとえばuser ) を複数のテーブルに分散するのはなぜですか。

user(user_id, username)
user_tel(user_id, tel_no)
user_addr(user_id, addr)
user_details(user_id, details)

この DB 設計から得られるスピードアップ ボーナスはありますか? 連鎖結合を実行してデータを取得することは、選択プロジェクションを使用するよりも計り知れないほど悪いように思われるため、非常に直感に反します..

もちろん、user_id とユーザー名のみを使用して他のクエリを実行すると、速度が向上しますが、それだけの価値があるでしょうか? では、真の利点はどこにあり、そのような DB 設計戦略に適した互換性のある作業シナリオは何でしょうか?

後の編集:この投稿の詳細では、属性が量的に変化しない完全で一意のエンティティを想定してください (たとえば、車の色は 2 つではなく 1 つだけであり、ユーザーはユーザー名/社会的秒番号/入学番号を 1 つだけ持っています)。 /home address/email/etc.. つまり、1 対多の関係ではなく、1 対 1 の完全に一貫したエンティティの説明を扱っています。上の例では、これがまさにそのケースです。単一のテーブルが、それが持っていた非主キー列と同じ数のテーブルに「分割」されています。

4

2 に答える 2

1

この設計の作成者は、単一のテーブルで「インライン」するよりも、このような「スパース」構造で NULL をより効率的に格納できると考えたのでしょう。おそらく、テーブルと(1 , "john", NULL, NULL, NULL)同じように行を保存し、他のテーブルには行をまったく保存しないという考えでした。これが機能するためには、NULL の数が非 NULL の数を大幅に上回る必要があります (そして、適切な方法で「混合」する必要があります)。そうしないと、この設計はすぐに高価になります。(1 , "john")user

また、単一の列を常に SELECT する場合、これはいくらか有益です。列を個別のテーブルに分割することで、ストレージの観点から列を「狭く」し、この特定のケースでは I/O を下げます(ただし、一般的ではありません)。

私の意見では、この設計の問題は、これらの利点をはるかに上回っています。

于 2012-04-17T10:38:57.350 に答える
1

このようにユーザーを分割することにより、ユーザーごとに正確に 1 行がユーザーに作成され、user_tel、user_details、user_addr のそれぞれ 0 ~ n 行にリンクされます。

これは、これらがオプションと見なされる可能性があること、および/または各ユーザーが複数の電話番号にリンクされている可能性があることを意味します。全体として、ユーザーが常に最大 1 つのアドレス、最大 1 つの電話番号を持つようにハードコーディングするよりも適応性の高いソリューションです。

別の方法は ieuser.telephone1 user.telephone2などを使用することですが、この方法論は 3NF ( http://en.wikipedia.org/wiki/Third_normal_form ) に反します。基本的に、同じ情報を格納するために多くの列を導入しています。

編集

OP からの追加の編集に基づいて、各ユーザーが正確に 0 または 1 の各電話番号、住所、詳細、およびそれ以上の情報を持っていないと仮定すると、それらの情報を別々のテーブルに保存するのはやり過ぎです。列 user_id、username、tel_no、addr、および details を含む単一のユーザー テーブル内に格納する方が賢明です。

ただし、メモリが機能する場合、これは 3NF 内で完全に問題ありません。これは通常の形式ではないと述べましたが、各データがその特定のユーザーに直接関連していると見なされる場合は、テーブル内に配置しても問題ありません。

後でテーブルを拡張して、telephone1、telephone2 (たとえば) を含めると、1NF に違反します。重複するフィールドがある場合 (つまり、複数のユーザーが 1 つのアドレスを共有している場合、これは完全に妥当です)、それは 2NF に違反し、さらに 3NF に違反します。

2NF の違反に関するこの点が、誰かがこれを行った理由かもしれません。

于 2012-04-17T08:43:24.000 に答える