我已经开始在另一个开发公司创建的网站上工作。数据库结构是使用实体框架的代码优先方法创建的。在C#代码中,我们遵循以下原则:
public class MainBusinessObject
{
...
public SubBusinessObject { get; set; }
}
public abstract class SubBusinessObject
{
...
}
public class SubBusinessObjectTypeOne : SubBusinessObject
{
....
}
public class SubBusinessObjectTypeTwo : SubBusinessObject
{
...
}
...
有6种SubBusinessObject
类型。最小的具有一个属性,最大的具有约50个属性。SubBusinessObject
抽象类定义了另外17个属性。 MainBusinessObject
大约有35。
这些实体代表什么样的现实世界实体?如果MainBusinessObject
持有FruitForSale
的数据,则SubBusinessObject
将代表Fruit
,而SubBusinessObjectTypeOne
可能是Apple
,{{1 }}可以是SubBusinessObjectTypeTwo
,依此类推。
Orange
和MainBusinessObject
类都链接到其他数据库对象(例如项目的源和位置)。所有这些实体都直接映射到SQL Server表。
根据此设计,处理SubBusinessObject
的查询很慢。例如,检索单个MainBusinessObject
的数据大约需要半秒(第一次运行将近5秒)。我曾尝试拨打多个电话,但性能最终大致相同。该站点通常表现不佳,这是一个关键区域。
请注意,我不是DBA,我只是一名开发人员(并且我们都知道开发人员在设计数据库方面做得如何……)。然而,尽管我很可能错了,但桌子的设计似乎对我来说却过于复杂。将这些表展平为一个表是否被视为不良做法?有关处理此类问题的任何建议将不胜感激。
答案 0 :(得分:1)
将这些表展平为一个表是否被视为不良做法?
不,那不是坏习惯。
EF 6支持两种存储继承层次结构的策略,例如:Table-per-Type(TPT)和Table-per-Hierarchy(TPH)。 TPT存储最初很有吸引力,因为每个子类型在数据库中都有自己的表。在TPH中,一个表存储所有属性,并带有一个鉴别符列。
但是,正如我认为您发现的那样,在运行时将这些表连接起来可能会很昂贵。
TPH通常被认为是最佳实践,因为它不太容易出现性能问题。因此,不可以,平整所有这些表不是 不良做法。实际上,由于这个原因,TPT尚未在EF Core中实现。
您应该使用TPH创建数据库的新版本,并将数据从当前数据库复制到新数据库以进行测试。如果您想将读取的数据库转换为TPH,这是有关如何进行迁移的有用文章。 Entity Framework Code First Convert TPT to TPH