web-dev-qa-db-ja.com

何が良いですか-多くの小さなテーブルまたは1つの大きなテーブル?

私は個人に関するプロファイルを保存するデータベースを持っています。これらの個人には、約50の可能なフィールドがあります。

いくつかは、姓、名、電子メール、電話番号などの一般的なものです。

その他は趣味、スキル、興味のようなものです

いくつかは身長、体重、肌の色です。

これらの各グループは、システムによって異なるときに使用されます。データベースを介して交渉できるという点で、私はそれぞれ約8つのフィールドの7つのテーブルを持つことを望みます。実行するためのベストプラクティスは何ですか?

編集:データは、プロファイルの一致を見つけるために、検索エンジンで使用されます。これは私がしていることに影響しますか?

39
Mazatec

言うのは難しく、アプリケーションが必要とするものに基づいています。 Database Normalization を調べて、データベースを正規化する方法を示し、独自のテーブルなどに分離する必要があるものを明らかにする必要があるためです。

34
Jim W.

私はノーマライズキャンプにいます。

ここにあなたを始めるためのいくつかのヒントがあります:

各「人物」に任意の一意の識別子を割り当てるプロセスから始めます。これをPersonIdまたはそのようなものと呼びます。この識別子は代理キーと呼ばれます。代理キーの唯一の目的は、代理キーと実世界の実在の人物との1対1の関係を保証することです。他の属性の値をデータベースの「人物」に関連付ける場合は、代理キーを使用します。

データベースレイアウトを開発するときに、他のいくつかの属性にも代理キーが必要(または少なくとも有用)になる場合があります。

管理する各属性を確認します。次の質問をしてください:特定の人がこの属性の値を1つだけ持っていますか?

たとえば、各人の「生年月日」は1つだけです。しかし、彼らはどのように「趣味」を持つことができますか?おそらく0から多く。単一の値を持つ属性(たとえば、誕生日、身長、体重など)は、PersonIdをキーとして、共通のテーブルに入れる候補です。この時点では、各テーブルの属性の数は問題になりません。

Hobbyなどの複数の値を持つ属性は、少し異なる処理が必要です。複数の値を持つ属性ごとに個別のテーブルを作成することができます。例として趣味を使用すると、次のテーブルPersonHobby(PersonId, Hobby)を作成できます。このテーブルの行は、_(123, "Stamp Collecting")_のようになります。この方法で、各人に必要な数の趣味を1行に1つずつ記録できます。 「興味」、「スキル」などについても同じようにします。

_PersonId + Hobby_の組み合わせが他に何も決定しない多数の多値属性がある場合(つまり、この「趣味」、「興味」、または「スキル」を実行しているこの人物について記録する興味深いものがない場合")PersonAV(PersonId, AttributeName, Value)のような構造を持つAttribute-Valueテーブルにまとめることができます。この場合、行は次のようになります:_(123, "Hobby", "Stamp Collecting")_。

この方法を使用する場合は、代理キーをAttributeNameテーブルのPersonAVに置き換え、このキーをその説明に関連付ける別のテーブルを作成することもお勧めします。 Attribute(AttributeId, AttributeName)など。このテーブルの行は_(1, "Hobby")_のようになり、対応するPersonAV行は_(123, 1, "Stamp Collecting")_になります。これは一般的に行われるため、データベース/アプリケーションで有効なAttributeNamesを知る必要がある場合は、それらを検索する場所があります。 「インタレスト」がAttributeNameの有効な値であるかどうかを検証する方法について考えてください。そのAttributeNameを持っている人を記録していない場合、その記録はありませんAttributeName on your database-データベースが存在するかどうかをどのようにして知るのですか? Attributeテーブルでよく調べてください!

一部の属性には複数の関係があり、それもテーブルの正規化方法に影響します。あなたの例にはこれらの依存関係はありませんでしたので、次のことを考慮してください:倉庫で部品がいっぱいになっていて、PartIdWeightClassStockCountShipCost。これは、Part(PartId, WeightClass, StockCount, ShipCost)のようなテーブルを示唆しています。ただし、非キー属性間に関係が存在する場合は、それらを除外する必要があります。たとえば、WeightClassShipCostを直接決定するとします。これは、WeightClassだけでShipCostを決定するのに十分であり、ShipCostPartテーブルから除外する必要があることを意味します。

正規化はかなり微妙な芸術です。適切に実行するには、データモデルのすべての属性間に存在する機能の依存関係を特定する必要があります。機能的な依存関係を思い付くだけでも、かなりの考察と考慮が必要ですが、適切なデータベース設計に到達することは非常に重要です。

データベースを構築する前に、時間をかけて正規化についてもう少し検討することをお勧めします。ここで数日を過ごすことは、将来のためにそれだけのお金を稼ぐだけではありません。 Google/Wikipediaで「機能依存」、「正規化」、「データベース設計」を検索してみてください。読んで、勉強して、学び、正しく構築してください。

データベース設計の正規化に関して私が行った提案は、取るべき方向性に関するヒントにすぎません。アプリケーションで管理しようとしているすべてのデータを十分に理解していない場合、ここでのアドバイスは「細かいこと」で行う必要があります。

25
NealB

私はいくつかのテーブルをお勧めします。正規化を超えると管理が難しくなり、複雑なクエリを作成することになり、パフォーマンスが低下します。

絶対に必要な場合にのみ正規化し、論理的に考えます。上記で提供した情報が限られているため、3つの表を作成します。

表1: PersonalDetails 表2:アクティビティ表3:その他

クラスタリングなど、パフォーマンスを高速化する他の手法があり、必要に応じて使用できます。

9
RKh

あなたが説明したことから、私は確かにそれを複数の表に分けます。ただし、任意の数の列で分割するのではなく、エンティティを構成するか、データをヒットするために使用するアクセスパターンと一致する列の論理コレクションについて考えてみてください

6
Kevin O'Donovan

IMO、必要なテーブルの数よりも、保存されているデータの品質を考慮することが重要です。

たとえば、変更を追跡する必要がありますか?ジョンが2007年1月に5'2 "で、2010年10月に5'11"だった場合、知りたいですか。その場合は、人を高さから2つのテーブルに分離する必要があります。

趣味はどうですか-彼らは3つの趣味しか持つことができませんか?彼らはより多く/より少なくできますか?これは、今後クエリしたいものですか?その場合は、別のテーブルが必要です。

データベースの設計と正規化について読んでください(このサイト自体にはいくつかの優れたスレッドがあります)。

https://stackoverflow.com/questions/tagged/normalization

6
Raj More

すべての人が同じ数の趣味を持っている場合(つまり、すべての人に2つの趣味がリストされている場合)は、正規化する必要があります。

人と常に1対1であるフィールドは、同じテーブルにある必要があります。たとえば年齢。 2つの異なる年齢を持つ人はいません。

5
David Oneill

この質問に対する正しい答えはありません。データを使用する時期と方法、データが変更される頻度、データベースでの使用量に大きく依存するためです。

私が個人的に行うことは、データを論理エンティティに編成し、それらのエンティティに基づいてテーブルを作成することです。これは少なくとも私が始めるところです。

3

100%正しいデータベース構成はありません。目的に十分合ったデータベース構成は1つだけです。将来、単一の優れたデータベースサーバーの機能を超えることが予想されない場合は、データを正規化し、外部キー、カスケード削除などの多くの制約を使用することで、データベースを操作できるようになります。一方、何十億ものリクエストがある多くのアプリケーションのデータベースを見ると、パフォーマンスとスケーラビリティの名のもとに、これらの優れた点の多くを忘れていることがわかります。

3
Novikov

多くの小さなテーブル、つまりここでは正規化が最適です。柔軟性を提供し、冗長性を減らし、データベース構成を改善します。

2
Adeel