可変列を使用したテーブル設計の処理方法


16

私はテーブル設計シナリオを持っていますが、非DBAタイプとして、よりスケーラブルな意見を求めています。

メトロエリアの家に関する情報を記録するように求められたとします。小さな近所(200の家)から始まり、最終的には5000000以上の家に成長します。

基本情報を保存する必要があります:ID#(一意のインデックスとして使用できる一意のロット番号)、Addr、City、State、Zip。素晴らしくシンプルなテーブルがそれを処理します。

しかし、毎年、すべての家に関する追加情報を記録するように求められます-そして、何の情報は毎年変わります。したがって、たとえば、最初の年には、所有者の姓と面積を記録するように求められます。2年目は、姓を残すよう求められますが、面積を捨てて、代わりに所有者の名の収集を開始します。

最後に-毎年、追加の列の数が変更されます。余分な2つの列から始めて、来年は6に、その後2に戻すことができます。

そのため、テーブルのアプローチの1つは、ハウステーブルの列としてカスタム情報を追加して、テーブルが1つだけになるようにすることです。

しかし、私は誰かがこれのためにテーブルを次のようにレイアウトする状況を持っています:

「House Table」列: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」と呼ばれる)を推測してハウステーブルをレイアウトし、それらのカスタム値をハウス行に挿入します。

または

B)カスタム情報をハウステーブルに保存しますが、毎年要件が変更されると、要件が非常に多くなり、最大数がわからないという考えで、カスタム情報に必要な列数だけでハウステーブルを再構築しますオプションのフィールドが求められる場合がありますか?

ありがとう、これが理にかなっていることを願っています!


こんにちは、どのように問題を管理しましたか?私は同じ種類のシナリオで実行しています。追加情報ごとに1つのリレーショナルテーブルを作成し、それをビューで「単一のテーブル」としてレンダリングしようとしています。
Benj

回答:


15

次の4つの選択肢があります。

NoSQLの - 定義すべてのレコードは、キー/値ペアのセットとして保存されます。非常に柔軟で高速です。そこにいるすべてのレポート作成者がこのスタイルのストレージをサポートしているわけではありません。NoSQLの多くのデータベース実装例があります。現在最も人気があると思われるものはMongoDBです。

EAV - 定義あなたがテーブル全体またはその側に(別のテーブル内の)部分のいずれかを回す場所です。社内に既に簡単に移動できないリレーショナルデータベースがある場合は、これが適切な選択です。指定したカスタム情報テーブルの例は、EAVテーブルの良い例です。

XML列のある標準テーブル -これは、NoSQLがリレーショナルテーブルに適合していると考えてください。XML列に格納されるデータは、複数の相関サブデータを含む、XMLがサポートする任意の形式にすることができます。「通常の」列になることがわかっている列については、データを保存する適切なタイプの列(LastName、Address、City、Stateなど)として作成できます。

余分な列がたくさんある標準的なテーブル -リレーショナルデータベースがあり、XMLもEAVも使用できず、NoSQLはオプションではありません。各タイプの追加の列を多数追加します。30以上のvarchar、30以上の整数、15以上の数値を推測します。また、値に列を使用したら、それを再使用しないください。また、列削除しないでください

これらすべてのソリューションのうち、NoSQLまたはEAVアプローチのいずれかが、コードとスキーマのリファクタリングを最小限に抑えて最も成功することがわかると思います。

次の年ではなく、ある年にデータを収集し、その後再び収集するという状況になります。古いデータを正しい情報で更新しようとすると、問題が発生し、費用がかかります。ストレージもどちらでもありません。


ピボットテーブルなどを使用することもできると聞きました
アレクサンダーミルズ

2

これらの2つのオプションに関する質問に答えるために、どちらも私には適切ではないようです。A)あなたを閉じ込め、B)多くの作業が必要です。説明する現在のスキーマは、ルックアップテーブルを参照するIDではなく、文字列としての情報名(「名」、「平方フィート」など)を除いてそれほど悪くはありません。

ただし、これはNoSQLデータベース(http://en.wikipedia.org/wiki/NoSQL)の良い候補のように思えます。私はそのようなデータベースで作業したことはありませんが、あなたが説明するのはこれが解決する典型的なシナリオです。


0

カスタム列の同時数は有限ではないとの制限は、(これ以上など整数のx列よりも、文字列のために例えばせいぜい10-20カスタム列)が知られている場合は
あなたの代わりに、データ型ごとに余分なフィールドとベーステーブルを使用して可能性があり毎年テーブルを再構築することにより、関連するカスタム列のみを含むその年のビューを作成し、その年の内容を反映するように汎用フィールドの名前を変更します。

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";

0

このデータを保存するすべてのシナリオを列挙できますか?

テーブルに適用できる列の組み合わせの数が限られている場合、すべてのシナリオに適用するgpoingである共通の列を使用して「ベーステーブル」をモデル化してから、さらにテーブルを作成します(何らかの継承を実装します。これは、ERDおよびデータベース設計ではサブタイプ/スーパータイプとして知られています。)

シナリオごとに1つのテーブル、この方法では、少なくともテーブルをきれいに保ち、「姓」列に番地を保存することを避けることができます...

この設計の質問を見てくださいhttps : //stackoverflow.com/questions/554522/something-like-inheritance-in-database-design

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.