我使用 SQL Server 和 Entity Framework 作为 ORM。
目前我有一个表 Product
,其中包含任何类型的所有产品。不同种类的产品具有不同的属性。
例如:
TV
类的所有产品都具有属性title
、resolution
和contrast
Car
类的所有产品都具有model
和horsepower
等属性
基于这个场景,我创建了一个名为 Attribute
的表,其中包含产品的所有属性。
现在要从数据库中获取产品,我总是必须加入所有属性。
要插入产品,我必须将所有属性作为单行一一插入。
该应用程序不仅仅是一家商店或类似的任何东西。应该可以在不更改数据库的情况下动态添加/删除一种产品的属性。
但是我想问你的问题仍然是:
- 这是一个糟糕的设计吗?
- 还有其他方法吗?
- 我的解决方案会显着降低速度吗? (假设产品有数百个属性,插入需要几秒钟……)
更新
问题是我的应用程序真的很复杂。有很多庞大的算法。该软件用于统计目的。
例如下面的一个问题:在一个算法表中,我存储哪些属性用于过滤器。假设管理员想要过滤所有小于 100 马力的汽车。过滤器是动态的,这意味着我有一个过滤器表,用于存储过滤器类型 (lessThan) 和属性 (horsepowers)。我怎样才能通过建议的方法(使用“硬编码”列)保持这种灵 active ?
最佳答案
在设计关系时,我认为每个人都没有意识到关于 EF 的一件事。
当您查询某些内容时,EF(至少 <= 4)想要为该查询创建一个 SELECT。
这意味着如果您有实体 A,它与实体 B 具有一对多关系(比如项目到属性),那么 EF 会将两者连接在一起,这样将为所有依赖 B 返回一个行每个 A。如果 A 有很多属性、多个依赖项,或者如果 B 有很多子依赖项甚至更糟,那么返回的表将非常庞大,因为所有 A 属性都将为依赖 B 的每一行复制。随着时间的推移,当您的实体模型变得越来越复杂,这可能会变成一个真正的性能问题。
如果您明确告诉 EF 预先加载依赖项“include”,则 EF 仅包含 B。如果省略 includes,您的内容最初加载速度会更快,但一旦您访问您的属性,它们将被 EF 延迟加载。这被称为 SELECT N+1 问题(每个 A 将需要 N 次 B 惰性查询,这可能是一个巨大的开销)。
虽然这不是您问题的直接答案,但在设计表格时需要考虑这一点。
另请注意,EF 支持多种基分类备选方案。一种策略是拥有一个公共(public)表,该表自动与子实体连接在一起。另一种通常性能更好但更难升级的替代方法是让一个表包含所有子类的所有属性的超集。
更多(过度)通用的数据库设计注意事项:
- 细节决定成败。做出良好的数据库设计选择可以成就您的整个职业生涯。没有银弹数据库模式。
- EF 有很多限制。这是方便的价格。如果该模型非常适合 EF,那么 EF 非常好,但请考虑更灵活的替代方案,如 NHibernate。有时,甚至带有 View 和存储过程的普通旧数据表也是首选。
- 如果您的模型有很多小的依赖项(例如项目表的大量属性),EF 效率不高。它将导致怪物查询和返回表或选择 n+1 问题。您可以编写一些棘手的多部分 LINQ 查询来进行一定程度的补偿,但这很棘手。
- SQL 的优势在于完整性和报告,这最适合相当严格的数据模型。
- 根据详细信息,您的模型看起来很适合 NoSql 后端,例如 RavenDb 和 MongoDb。 NoSql 更适合动态数据模型,并且扩展性非常好。
关于c# - SQL Server 和 Entity Framework - 动态列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19973547/