让我们考虑的备选方案的利弊:
其中的所有目录+表属性:
- 很宽表 - 很难查看模型&模式定义和表数据
- 一个查询没有联接要求中检索关于上市(S)的所有数据
- 需要为每个新的属性架构+模式的变革。
- 有效的,如果你总是加载所有的属性和多数项目已大部分属性的值。根据属性
- 例LINQ查询:
context.Listings.Where(l => l.PricePerMonthInUsd < 10e3 && l.SquareMeters >= 200)
.ToList();
一个的所有目录表中,属性类型一个表,一个用于(清单的ID +属性IDS +)值(EAV):
- 清单表是窄
- 有效的,如果数据非常稀疏的(大多数属性不具备莫值st items)
- 需要从值中提取所有数据 - 一个额外的查询(或一个连接,但会浪费带宽 - 将获取每个属性值行的基本列表数据)
- 不需要模式+模型更改新属性
- 如果你想类型安全的访问通过代码的属性,你会基于属性类型的表需要自定义代码生成
- 例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:0 .1带有列表表格,而不是1:很多)
- 要求对新属性进行模式+模型更改
- 查看模式/模型更简单 - 如果您可以将属性划分为10个组,则会有25个表在列表中有11列而不是另外250列表
- LINQ查询位于上述两个示例之间的某处。
根据您的具体统计数据(关于稀疏),并要求/维护计划(例如添加多久是属性类型/改变了吗?),并决定考虑利弊。
哎呀,对不起,我的意思是EAV(实体 - 属性 - 值),我会更新我的问题。 – Ricketts
重新标记 - 问题与C#无关 - .NET语言不可知。重要的考虑事项是SQL Server优化,实体框架优化。此外,ASP.NET WCF并不相关,因为您不必在EF和WCF中使用相同的实体(如果需要,您可以使用映射)。 –