3

不動産 MLS (Multiple Listing Service) データを保持するデータベースがあります。現在、すべてのリスト属性 (価格、住所、平方フィートなど) を保持する単一のテーブルがあります。いくつかの異なる不動産タイプ (住宅、商業、賃貸、収入、土地など) があり、各不動産タイプは大部分の属性を共有していますが、その不動産タイプに固有のものもいくつかあります。

私の質問は、共有属性が 250 フィールドを超えており、1 つのテーブルに含めるにはフィールドが多すぎるように思われることです。私の考えでは、それらを EAV (Entity-Attribute-Value) 形式に分割することができますが、それについて多くの悪いことを読んだことがあり、250 のフィールドのいずれかが検索される可能性があるため、クエリの実行が非常に苦痛になります。もし私がそのルートに行くとしたら、文字通りすべてのデータを EAV テーブルから取り出し、リスト ID でグループ化し、それをアプリケーション側でマージしてから、メモリ内のオブジェクト コレクションに対してクエリを実行する必要があります。これもあまり効率的ではないようです。

どの方法で進めるかについてのアイデアや推奨事項を探しています。おそらく、250 以上のフィールド テーブルが先に進む唯一の方法です。

注意として、私はSQL Server 2012、.NET 4.5、Entity Framework 5、C#を使用しており、データはWCFサービスを介してasp.net Webアプリケーションに渡されます。

前もって感謝します。

4

3 に答える 3

5

代替案の長所と短所を考えてみましょう。

すべてのリストと属性の1つのテーブル:

  1. 非常に幅の広いテーブル-モデルとスキーマの定義およびテーブルデータを表示するのが難しい
  2. リストのすべてのデータを取得するために必要な結合のない1つのクエリ
  3. 新しい属性ごとにスキーマとモデルの変更が必要です。
  4. 常にすべての属性をロードし、ほとんどのアイテムにほとんどの属性の値がある場合に効率的です。
  5. 属性に従ったLINQクエリの例:
context.Listings.Where(l => l.PricePerMonthInUsd < 10e3 && l.SquareMeters >= 200)
    .ToList();


すべてのリストに1つのテーブル、属性タイプに1つのテーブル、(リストID+属性IDS+)値(EAV)に1つのテーブル:

  1. リスティングテーブルが狭い
  2. データが非常にまばらな場合に効率的です(ほとんどの属性にはほとんどのアイテムの値がありません)
  3. 値からすべてのデータをフェッチする必要があります-1つの追加クエリ(または1つの結合、ただし帯域幅を浪費します-属性値の行ごとに基本的なリストテーブルデータをフェッチします)
  4. 新しい属性のスキーマとモデルの変更は必要ありません
  5. コードを介して属性にタイプセーフにアクセスする場合は、属性タイプテーブルに基づいてカスタムコードを生成する必要があります
  6. 属性に従ったLINQクエリの例:
var listingIds = context.AttributeValues.Where(v =>
                    v.AttributeTypeId == PricePerMonthInUsdId && v < 10e3)
                .Select(v => v.ListingId)
                .Intersection(context.AttributeVales.Where(v =>
                    v.AttributeTypeId == SquareMetersId && v.Value >= 200)
                .Select(v => v.ListingId)).ToList();

または:(実際のDBのパフォーマンスを比較してください)

var listingIds = context.AttributeValues.Where(v =>
                    v.AttributeTypeId == PricePerMonthInUsdId && v < 10e3)
                .Select(v => v.ListingId).ToList();

listingIds = context.AttributeVales.Where(v =>
                listingIds.Contains(v.LisingId)
                && v.AttributeTypeId == SquareMetersId
                && v.Value >= 200)
            .Select(v => v.ListingId).ToList();

その後:

var listings = context.Listings.Where(l => listingIds.Contains(l.ListingId)).ToList();


妥協オプション-すべてのリストに1つのテーブル、値を含む属性のグループごとに1つのテーブル(属性をグループに分割できると仮定):

  1. 複数の中幅テーブル
  2. データがグループごとにまばらである場合に効率的です(たとえば、庭のないリストでは庭関連の属性がすべてnullであるため、庭関連のテーブルに行を追加しないでください)
  3. 複数の結合を含む1つのクエリが必要です(グループテーブルはリストテーブルで1:0..1であり、1:manyではないため、結合で帯域幅が無駄になることはありません)
  4. 新しい属性にはスキーマとモデルの変更が必要です
  5. スキーマ/モデルの表示が簡単になります-属性を10のグループに分割できる場合、リストテーブルに別の250の代わりに、11の列を持つ25のテーブルがあります
  6. LINQクエリは、上記の2つの例の間のどこかにあります。


特定の統計(まばらさに関する)および要件/保守性計画(たとえば、属性タイプが追加/変更される頻度)に従って長所と短所を検討し、決定します。

于 2012-12-02T20:38:15.283 に答える
0

私がおそらくすること:

最初に、IDとFieldNameを持っている250フィールドのテーブルを作成します。次に例を示します。

price   -> 1
address -> 2
sqft    -> 3

このテーブルは、私のコードに列挙型としてハードコーディングされ、クエリで使用されます。

次に、メインテーブルに2つのフィールドがあります。1つは上記のテーブルから取得したフィールドIDのタイプで、もう1つはその値です。

Line1: 122(map id), 1 (for price), 100 (the actually price)
Line2: 122(map id), 2 (for address), "where is it" 
Line3: 122(map id), 3 (for sqft), 10 (sqft)

ここでの問題は、少なくとも2つのフィールドが必要になる可能性があることです。1つは数値用、もう1つは文字列用です。

もちろんこれは単なる提案です。

于 2012-12-02T20:17:34.560 に答える
0

listing共有属性のみを含むテーブルを作成します。このテーブルはlistingId主キーとして持っています。リスティングの種類を格納する列があるため、住宅用のリスティングか着陸用のリスティングかなどがわかります。

次に、サブタイプごとに追加のテーブルを作成します。したがって、、residential_listingなどland_listingのテーブルがあります。これらすべてのテーブルの主キーも になりますlistingId。この列は への外部キーでもありますlisting

共有データを操作したい場合は、これをすべてlistingテーブルから行うことができます。特定のデータに関心がある場合は、特定のテーブルに参加します。すべてのデータがそこにある場合、一部のクエリは特定のテーブルで完全に実行できる場合があります。

于 2012-12-03T05:01:11.523 に答える