83

以前の同僚は、テーブル数が多く、列数が少ないデータベースの方が、テーブル数が少なく、列数が多いデータベースよりも優れていると主張しました。たとえば、名前、住所、都市、州、郵便番号などの列を持つ顧客テーブルではなく、名前テーブル、住所テーブル、都市テーブルなどを作成します。

彼は、この設計はより効率的で柔軟であると主張しました。おそらくより柔軟ですが、その効率性についてコメントする資格はありません。たとえそれがより効率的であったとしても、それらの利点は、追加された複雑さによって上回る可能性があると思います.

So, are there any significant benefits to more tables with fewer columns over fewer tables with more columns?

4

18 に答える 18

66

データベースを設計するときに従うかなり単純な経験則がいくつかあります。これは、このような決定を下すのに役立つと思います....

  1. 正規化を優先します。非正規化は最適化の一形態であり、必要なトレードオフがすべて含まれているため、YAGNIの態度でアプローチする必要があります。
  2. データベースを参照するクライアント コードがスキーマから十分に分離されていることを確認してください。これにより、クライアントの大幅な再設計が必要になることはありません。
  3. 非正規化によってパフォーマンスやクエリの複雑さが明らかに改善される場合は、恐れずに非正規化してください。
  4. データ量と使用シナリオで許可されている場合は、スキーマのコアを非正規化するのではなく、ビューまたはダウンストリーム テーブルを使用して非正規化を実装します。

これらのルールの通常の結果は、最初の設計では、冗長性を排除することに重点を置いて、列よりもテーブルを優先することです。プロジェクトが進行し、非正規化ポイントが特定されると、全体的な構造は、他の貴重な利点と引き換えに、限られた冗長性と列の増殖で妥協するバランスに向かって進化します。

于 2008-09-12T17:02:49.613 に答える
12

私はより多くのテーブルを支持すると主張しますが、それは特定のポイントまでです。あなたの例を使用して、ユーザーの情報を 2 つのテーブル (たとえば、USERS と ADDRESS) に分けた場合、これにより、ユーザーごとに複数のアドレスを持つ柔軟性が得られます。これの明白なアプリケーションの 1 つは、別々の請求先住所と配送先住所を持つユーザーです。

個別の CITY テーブルを持つことを支持する議論は、各都市の名前を 1 回だけ格納すればよく、必要なときにそれを参照する必要があるということです。これにより重複は減りますが、この例ではやり過ぎだと思います。よりスペース効率が良いかもしれませんが、データベースからデータを選択するときに結合で代償を払うことになります。

于 2008-09-12T16:50:10.470 に答える
11

テーブル/列に関する質問ではなく、正規化に関する質問のように聞こえます。状況によっては、高度な正規化(この場合は「より多くのテーブル」) が適切でクリーンですが、通常、関連する結果を得るには多数の JOIN が必要です。また、データセットが十分に大きいと、パフォーマンスが低下する可能性があります。

Jeff は、StackOverflow の設計に関して、それについて少し書いています。Jeff がDare Obasanjoによってリンクしている投稿も参照してください。

于 2008-09-12T16:48:42.970 に答える
5

It depends on your database flavor. MS SQL Server, for example, tends to prefer narrower tables. That's also the more 'normalized' approach. Other engines might prefer it the other way around. Mainframes tend to fall in that category.

于 2008-09-12T16:47:27.043 に答える
5

完全に正規化された設計 (つまり、「より多くのテーブル」) はより柔軟で、保守が容易で、データの重複を避けることができます。つまり、データの整合性を確保するのがはるかに簡単になります。

これらは正常化する強力な理由です。最初に正規化することを選択し、パフォーマンスが問題になっていることがわかった後で、特定のテーブルのみを非正規化します。

私の経験では、現実の世界では、たとえ非常に大きなデータ セットであっても、非正規化が必要なポイントに到達することはありません。

于 2008-09-12T16:54:18.493 に答える
5

各テーブルには、主キーによって一意に識別されるエンティティに関連する列のみを含める必要があります。データベース内のすべての列がすべて同じエンティティの属性である場合、すべての列を含む 1 つのテーブルのみが必要になります。

ただし、いずれかの列が NULL である可能性がある場合は、正規化するために、NULL 可能な各列をメイン テーブルへの外部キーを持つ独自のテーブルに配置する必要があります。これは一般的なシナリオであるため、よりクリーンな設計のために、既存のテーブルに列よりも多くのテーブルを追加する可能性があります。また、これらのオプションの属性を独自のテーブルに追加することで、NULL を許可する必要がなくなり、NULL 関連の問題を回避できます。

于 2008-09-12T17:00:52.770 に答える
3

これらの 1 対 1 の関係のいずれかが将来 1 対多または多対多になる可能性がある場合、マルチテーブル データベースははるかに柔軟です。たとえば、一部の顧客の複数の住所を格納する必要がある場合、顧客テーブルと住所テーブルがあれば非常に簡単です。住所の一部を複製する必要があり、他の部分を複製する必要がないという状況は実際にはわかりません。そのため、住所、都市、州、郵便番号の表を別々にするのは少しやり過ぎかもしれません。

于 2008-09-12T16:50:00.517 に答える
3

他のすべてと同様に、場合によって異なります。

列数とテーブル数に関して厳密なルールはありません。

顧客が複数の住所を持つ必要がある場合は、そのための別のテーブルが理にかなっています。City 列を独自のテーブルに正規化する十分な理由がある場合は、それも可能ですが、(通常は) 自由形式のフィールドであるため、これまで見たことがありません。

表が多く正規化された設計は、スペースの点では効率的であり、「教科書のように」見えますが、非常に複雑になる可能性があります。顧客の名前と住所を取得するために 12 回の結合を行う必要があるまでは、見栄えがします。これらの設計は、最も重要なパフォーマンスの点で自動的に優れているわけではありません: クエリです。

複雑なものはできるだけ避けてください。たとえば、顧客が 2 つの住所しか持てない (任意に多くはない) 場合、それらすべてを 1 つのテーブル (CustomerID、Name、ShipToAddress、BillingAddress、ShipToCity、BillingCity など) に保持することが理にかなっています。

このトピックに関するJeff の投稿は次のとおりです。

于 2008-09-12T16:53:43.237 に答える
2

列の少ないテーブルを使用することには利点がありますが、上記のシナリオを見て、次の質問に答える必要もあります。

顧客は複数の住所を持つことができますか? そうでない場合は、アドレス用の別のテーブルは必要ありません。その場合は、必要に応じてアドレスを簡単に追加できるため、別のテーブルが役立ちます。テーブルに列を追加するのは難しくなります。

于 2008-09-12T16:48:49.520 に答える
1

うーん。

私はそれが洗浄だと思います、そしてあなたの特定のデザインモデルに依存します。いくつかのフィールドを含むエンティティを独自のテーブルに確実に除外するか、アプリケーションの要件の変更に応じて構成が変更される可能性が高いエンティティを除外します(たとえば、フィールドが非常に多いため、アドレスを除外しますが、私は特に、外国の住所を処理する必要があると思われる場合は、それを実行します。これは、形式が異なる場合があります。電話番号についても同じです)。

とは言うものの、それが機能するようになったら、パフォーマンスに注意してください。大規模で高価な結合を行う必要があるエンティティをスピンアウトした場合は、そのテーブルを元のテーブルにスピンバックする方が設計上の決定になります。

于 2008-09-12T17:46:46.310 に答える
1

データベースを設計するときは、アプリケーションのニーズではなく、データの意味にできるだけ近づける必要があります。

優れたデータベース設計は、変更なしで 20 年以上存続する必要があります。

顧客は複数の住所を持つことができます。それが現実です。アプリケーションが最初のリリースで 1 つのアドレスに限定されていると判断した場合は、データではなくアプリケーションの設計に問題があります。

クエリを簡素化する場合は、複数の列ではなく複数のテーブルを使用し、ビューを使用することをお勧めします。

ほとんどの場合、データベースのパフォーマンスの問題は、クエリの複雑さではなく、ネットワーク パフォーマンス (1 行の結果を伴うチェーン クエリ、不要な列のフェッチなど) に関するものです。

于 2014-07-29T07:46:36.360 に答える
1

最初のステップとして正規化を検討します。したがって、都市、郡、州、国は別々の列として使用する方がよいでしょう...現在の DBMS-es と組み合わせた SQL 言語の力により、後で表示する必要がある場合にデータをグループ化できます他の正規化されていないビューで表示されます。

システムが開発されているとき、改善と思われる場合は、一部を「非正規化」することを検討してください。

于 2008-09-12T16:48:25.090 に答える
1

この場合、バランスが取れていると思います。列をテーブルに入れることが理にかなっている場合は、テーブルに入れます。そうでない場合は、入れないでください。同僚のアプローチは間違いなくデータベースの正規化に役立ちますが、必要な情報を取得するために 50 個のテーブルを結合する必要がある場合はあまり役に立ちません。

私の答えは、最善の判断を下すことです。

于 2008-09-12T16:48:35.963 に答える
1

これには多くの側面がありますが、アプリケーション効率の観点からすると、モート テーブルの方が効率的である場合があります。データベースがロックを作成する可能性がある操作を行うたびに、一連の列を持ついくつかのテーブルがある場合、ロックの期間中はより多くのデータが使用できなくなります。ロックがページとテーブル (テーブルではないことを願っています :) にエスカレートされた場合、これがシステムの速度を低下させる可能性があることがわかります。

于 2008-09-12T16:49:44.870 に答える
0

できるだけ少ない列を使用するクエリには大きな利点があります。ただし、テーブル自体には多数の値を含めることができます。ジェフもこれについて何か言っています。

基本的に、クエリを実行するときに必要以上に要求しないようにしてください。クエリのパフォーマンスは、要求する列の数に直接関係します。

于 2008-09-12T16:49:50.563 に答える
0

その決定を下す前に、保存しているデータの種類を確認する必要があると思います。住所テーブルを持つことは素晴らしいことですが、同じ住所を複数の人が共有する可能性が高い場合に限られます。すべての人が異なるアドレスを持っている場合、そのデータを別のテーブルに保持すると、不要な結合が発生するだけです。

都市自体がアプリケーションで重要なエンティティでない限り、都市テーブルを使用するメリットはないと思います。または、ユーザーが利用できる都市の数を制限したい場合。

肝心なのは、このような決定は、効率性を追求する前に、アプリケーション自体を考慮に入れる必要があるということです。IMO。

于 2008-09-12T16:50:04.930 に答える
0

まず、テーブルを正規化します。これにより、冗長なデータが回避され、スキャンするデータの行が少なくなり、クエリが改善されます。次に、結合している正規化されたテーブルが原因でクエリの処理に時間がかかるポイントに遭遇した場合 (高価な結合句)、より適切な場所で非正規化します。

于 2014-08-11T21:01:02.617 に答える
0

非常に多くの刺激的で根拠のある回答を見ることができてうれしいです。

私の答えは (残念ながら) です: それは依存します.

2 つのケース: * 長年使用されるデータモデルを作成し、将来の多くの変更に適応する必要がある場合: テーブルを増やし、行を減らし、かなり厳密な正規化を行います。* それ以外の場合は、表を少なくして行を増やすか、表を減らして行を増やすかを選択できます。特に、このテーマに比較的慣れていない人にとっては、この最後のアプローチはより直感的で理解しやすいものです。

同じことは、オブジェクト指向アプローチとその他のオプションのどちらを選択する場合にも当てはまります。

于 2016-11-21T12:11:41.617 に答える