テーブル設計シナリオがあり、DBA以外のタイプとして、どちらがよりスケーラブルであるかについて意見を求めています。
小さな近所(200戸)から始めて、最終的には5000000+戸まで成長する、メトロエリアの住宅に関する情報を記録するように求められたとします。
基本情報を格納する必要があります:ID#(一意のインデックスとして使用できる一意のロット番号)、Addr、City、State、Zip。細かくてシンプルなテーブルで対応します。
しかし、毎年、すべての家に関する追加情報を記録するように求められます-そして、WHAT情報は毎年変わります。したがって、たとえば、初年度には、所有者の姓と平方フィートを記録するように求められます。 2年目には、姓を維持するように求められますが、平方フィートを捨てて、代わりに所有者の名の収集を開始します。
最後に-追加の列の数は毎年変更されます。 2列を追加して開始し、来年は6列に移動してから、2列に戻す可能性があります。
したがって、1つのテーブルアプローチは、ハウステーブルの列としてカスタム情報を追加して、テーブルが1つだけになるようにすることです。
しかし、私は誰かがこのためにテーブルを次のようにレイアウトした状況があります:
「ハウステーブル」列:ID、Addr、City、State、Zip-ハウスごとに1行
ID Addr City State Zip
-------------------------------------------
1 10 Maple Street Boston MA 11203
2 144 South Street Chelmsford MA 11304
3 1 Main Avenue Lowell MA 11280
「カスタム情報テーブル」列:ID、名前、値-テーブルは次のようになります。
ID Name Value
1 Last Name Smith
2 Last Name Harrison
3 Last Name Markey
1 Square Footage 1200
2 Square Footage 1930
3 Square Footage
したがって、個々の家のレコードごとに複数の行があります。オプションの情報が必要になるたびに、このテーブルは文字通り再構築されるため、来年は次のようになります。
1 Last Name Smith
2 Last Name Harrison
3 Last Name Markey
1 First Name John
2 First Name Harry
3 First Name Jim
結局、あなたは100,000の家の列を蓄積し、1年で10の追加情報があります。 2番目のテーブルは1,000,000行の情報になり、その多くは冗長な(説明)情報を持っています。全体としてのデータベース要件は、人々が家の列の情報+関連するカスタムフィールド値を1日に数千回取得する必要があることです。
だから私の質問:代わりに次のいずれかを行うのは悪い(または恐ろしい)習慣でしょうか?
A)カスタム列の最大数(おそらく「1」から「10」と呼ばれる)でハウステーブルをレイアウトし、それらのカスタム値を家の行に直接挿入します
OR
B)カスタム情報をハウステーブルに保存しますが、要件が変わるたびに、カスタム情報に必要な数の列のみを使用してハウステーブルを再構築します。要件が複雑になる可能性があり、最大数がわからないという考えはありません。オプションのフィールドが要求される場合がありますか?
よろしくお願いいたします。
次の4つの選択肢があります。
NoSQL- definition すべてのレコードは、キーと値のペアのセットとして保存されます。非常に柔軟で高速です。世の中のすべてのレポート作成者がこのスタイルのストレージをサポートしているわけではありません。 NoSQLのデータベース実装の例は多数あります。現在最も人気があると思われるのは、MongoDBです。
[〜#〜] eav [〜#〜]- definition これは、テーブル全体または(別のテーブル内の)部分をオンにする場所ですその側。これは、社内にリレーショナルデータベースが既にあり、簡単に離れることができない場合に適しています。あなたが与えたカスタム情報テーブルの例は、EAVテーブルの良い例です。
XML列のある標準テーブル-NoSQLはリレーショナルテーブルと出会うため、これについて考えてください。 XML列に格納されるデータは、複数の相関サブデータを含め、XMLがサポートする任意の形式にすることができます。 「通常の」列になることがわかっている列については、適切なタイプの列として構築して、データ(LastName、Address、City、Stateなど)を格納できます。
extra列を多く含む標準テーブル-リレーショナルデータベースがあり、どちらも使用できませんXMLまたはEAV、NoSQLはオプションではありません。各タイプの追加の列をたくさん追加します。 30以上のvarchar、30以上の整数、15以上の数値を推測します。また、値に列を使用すると、それを再利用しないでください。また、列も削除しないでください。
これらすべてのソリューションのうち、コードとスキーマのリファクタリングを最小限に抑えて、NoSQLまたはEAVのいずれかのアプローチが最も成功すると思います。
1年後ではなく1年後にデータを収集し、その後再び収集するという状況になります。古いデータを正しい情報で更新しようとすると、問題が発生し、コストがかかります。ストレージはどちらでもありません。
これら2つのオプションについての質問に答えるには、どちらも正しくないと思います。 A)あなたを閉じ込め、B)多くの仕事です。記述した現在のスキーマは悪くありません(情報名(「名」、「平方フィート」など)を、ルックアップテーブルを参照するIDの代わりに文字列として使用する場合を除きます)。
しかし、これはNoSQLデータベース( http://en.wikipedia.org/wiki/NoSQL )の良い候補のように思えます。私はそのようなデータベースを扱ったことはありませんが、あなたが説明するのはこれが解決する典型的なシナリオです。
このデータを保存するすべてのシナリオを列挙できますか?
テーブルに適用できる列の組み合わせが有限数である場合は、すべてのシナリオに適用するためにgpoingしている一般的な列を使用して「ベーステーブル」をモデル化し、さらにテーブルを作成します(ある種の継承を実装するため。これは、ERDおよびデータベース設計ではサブタイプ/スーパータイプとして知られています。)
シナリオごとに1つのテーブル。これにより、少なくともテーブルをクリーンな状態に保ち、「姓」列に住所が格納されないようにすることができます...
このデザインの質問を見てみましょう: https://stackoverflow.com/questions/554522/something-like-inheritance-in-database-design
カスタム列の同時数が有限で制限がわかっている場合(たとえば、文字列のカスタム列は10-20以下、整数の場合はx列以下など)
データ型ごとに追加のフィールドを持つベーステーブルを使用して、毎年テーブルを再構築する代わりに、関連するカスタム列のみを含むその年のビューを作成し、その年のコンテンツを反映するように汎用フィールドの名前を変更できます。
House Table:
ID, Addr, City, State, Zip, custom_string1,cs_2,cs_3,custom_integer_1,ci_2,ci_3 ...
create view house_2014 as
select ID, Addr, City, State, Zip,
custom_string1 as last_name,cs_2 as first_name ...
このアプローチの問題は、履歴がありませんが、列の要件を変更する前に毎年簡単にコピーを作成できることです。
create table house_2014_archive as select * from house_2014;
drop house_2014;
create view house_2015 as "select column list for new year";