我有一个持有房地产MLS(多重上市服务)数据的数据库。目前,我有一个表,其中包含所有列表属性(价格,地址,平方英尺等)。有几种不同的房产类型(住宅,商业,租赁,收入,土地等),每种房产类型共享大部分属性,但有一些是该房产类型所特有的。
我的问题是共享属性超过250个字段,这似乎在一个表中有太多字段。我的想法是我可以将它们分解为EAV(实体 - 属性 - 值)格式,但我已经阅读了很多关于它的不好的事情,它会使运行查询变得非常痛苦,因为可以搜索250个字段中的任何一个。如果我要去那条路线,我真的必须从EAV表中提取所有数据,按列表ID分组,将其合并到应用程序端,然后针对内存对象集合运行我的查询。这似乎也不是很有效。
我正在寻找一些有关进展方式的想法或建议。也许250+字段表是唯一可行的方法。
正如我所说,我正在使用SQL Server 2012,.NET 4.5 w / Entity Framework 5,C#,数据通过WCF服务传递给asp.net Web应用程序。
提前致谢。
答案 0 :(得分:5)
让我们考虑替代方案的利弊:
所有商品+属性的一个表格:
context.Listings.Where(l => l.PricePerMonthInUsd < 10e3 && l.SquareMeters >= 200)
.ToList();
所有商家信息的一个表格,一个属性类型表格和一个(列出ID +属性IDS +)值(EAV):
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();
或:(比较实际数据库的性能)
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 :(得分:0)
我可能做的事情:
我首先为250个字段创建一个表,其中我有ID和FieldName,例如:
price -> 1
address -> 2
sqft -> 3
此表还将我的代码硬编码为枚举并用于查询。
然后在主表中我有两个字段,一个是字段ID的类型,从上面的表中得到它,第二个是它的值,例如
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 :(得分:0)
我会创建一个listing
表,其中只包含共享属性。该表将listingId
作为主键。它会有一个存储列表类型的列,因此您可以知道它是否包含住宅列表,登陆列表等。
然后,对于每个子类型,创建一个额外的表。因此,您将拥有residential_listing
,land_listing
等表格。所有这些表格的主键也是listingId
。此列也是listing
的外键。
如果您希望操作共享数据,可以完全从listing
表执行此操作。当您对特定数据感兴趣时,您将加入特定表格。如果所有数据都存在,某些查询可能完全在特定表上运行。