3

我使用 SQL Server 和实体框架作为 ORM。

目前我有一张Product包含任何类型的所有产品的表格。不同种类的产品具有不同的属性。

例如:

  • 所有同类产品TV都有属性titleresolution并且contrast
  • 所有同类产品Car都具有类似modelhorsepower

基于这种情况,我创建了一个名为的表Attribute,其中包含产品的所有属性。

现在要从数据库中获取产品,我总是必须加入所有属性。

要插入产品,我必须将所有属性一一插入为单行。

该应用程序不仅仅是商店或类似的东西。应该可以在不更改数据库的情况下动态添加/删除一种产品的属性。

但我对你的问题仍然是:

  • 这是一个糟糕的设计吗?
  • 还有另一种方法吗?
  • 我的解决方案会显着减慢速度吗?(假设产品有数百个属性,插入需要几秒钟......)

更新

问题是我的应用程序非常复杂。有很多庞大的算法。该软件用于统计目的。

例如,以下问题是一个问题:在算法表中,我存储了哪些属性用于过滤器。假设管理员想要过滤所有小于 100 马力的汽车。过滤器是动态的,这意味着我有一个过滤器表,其中存储过滤器类型(lessThan)和属性(马力)。如何使用建议的方法(使用“硬编码”列)保持这种灵活性?

4

1 回答 1

1

在设计关系时,我认为每个人都没有意识到关于 EF 的一件事。

当您查询某些内容时,EF(至少 <= 4)希望为该查询创建一个 SELECT。

这意味着如果您有实体 A,它与实体 B 具有一对多的关系(例如项目到属性),那么 EF 将两者连接在一起,这样每个 A 的所有依赖 B 都会返回一个行。如果 A 有许多属性、多个依赖项,或者更糟糕的是,如果 B 有许多子依赖项,那么返回的表将非常庞大,因为将为依赖 B 的每一行复制所有 A 属性。随着时间的推移,当您的实体模型随着复杂性的增加,这可能会变成一个真正的性能问题。

如果您明确告诉它急切加载依赖项“包含”,则 EF 仅包含 B。如果包含被省略,你的东西最初会加载得更快,但是一旦你访问你的属性,它们就会被 EF 延迟加载。这被称为 SELECT N+1 问题(每个 A 将需要 N 次 B-lazy 查询,这可能是一个巨大的开销)。

虽然这不是您问题的直接答案,但在设计表格时需要考虑。

另请注意,EF 支持多种基分类替代方案。一种策略是拥有一个公用表,该表自动与子实体连接在一起。另一种通常性能更好但更难升级的替代方法是拥有一个表,其中包含所有子类的所有属性的超集。

更多(过度)通用数据库设计注意事项:

  • 细节决定成败。你可以通过做出好的数据库设计选择来完成整个职业生涯。没有银弹数据库模式。
  • EF 有很多限制。这是方便的价格。如果模型非常适合 EF,那么 EF 相当不错,但请考虑更灵活的替代方案,例如 NHibernate。有时甚至会首选带有视图和存储过程的普通旧数据表。
  • 如果您的模型有很多小的依赖项(例如项目表的大量属性),则 EF 效率不高。这将导致怪物查询和返回表或选择 n+1 问题。您可以编写一些棘手的多部分 LINQ 查询来进行一些补偿,但这很棘手。
  • SQL 的优势在于完整性和报告,这对于相当严格的数据模型最有效。
  • 根据细节,您的模型看起来很适合 NoSql 后端,例如 RavenDb 和 MongoDb。NoSql 更适合动态数据模型,并且扩展性非常好。
于 2013-11-14T10:10:30.577 回答