繁体   English   中英

需要帮助应用程序设计

[英]Need Help With Application Design

所以,我喜欢关于设计类和存储以下情况的数据的最佳方法的一些反馈:

我有一个名为Tasks的接口,如下所示:

interface ITask
{
    int ID{ get; set;}
    string Title {get; set;}
    string Description{get; set;}
}

我希望能够创建不同类型的任务,具体取决于谁在使用该应用程序...例如:

public class SoftwareTask: ITask
{
    //ITask Implementation
    string BuildVersion {get; set;}
    bool IsBug {get; set;}

}

public class SalesTask: ITask
{
    //ITask Implementation
    int AccountID {get; set;}
    int SalesPersonID {get; set;}
}

所以我看到它的方式我可以在数据库中使用与ITask接口匹配的列创建一个Tasks表,并在一列中推送更具体任务的所有属性(甚至可以将任务对象序列化为单个列)柱)

要么

为每个任务类型创建一个表,以存储该类型唯一的属性。

我现在真的不喜欢任何一种解决方案。 我需要能够创建不同类型的任务(或任何其他类),它们通过基本接口共享一组共同的核心属性和方法,但能够以易于搜索的方式存储其独特属性并过滤而不必为每种类型创建一堆数据库表。

我开始研究插件架构和策略模式,但我没有看到哪里可以解决我存储和访问数据的问题。

非常感谢任何帮助或推动正确的方向!

你可能应该从ORM如何处理这个问题,比如TPH / TPC / TPT

鉴于ITask是一个接口,你应该选择TPC(每个混凝土类型的表)。 当你把它作为基类时,TPT和TPH也是选项。

您的第二种方法(每种类型一个表)是解决此问题的规范方法 - 虽然它需要更多的努力来实现它,它更适合大多数数据库的关系模型,并保留数据的一致和有凝聚力的表示。 每种具体类型使用一个表的方法效果很好,并且与大多数ORM库(如EntityFramework和NHibernate)兼容。

然而,当子类型的数量非常大或者在运行中创建子类型时,有时会使用几种替代方法。

备选方案#1:键值扩展表。 这是一个表,每个附加的数据字段需要存储一行,一个外键返回核心表(Task),以及一个指定这是哪种字段的列。 它的结构通常类似于:

TaskExt Table
=================
TaskID     : Number (foreign key back to Task)
FieldType  : Number or String (this would be AccountID, SalesPersonID, etc)
FieldValue : String  (this would be the value of the associated field)

备选方案#2:类型映射扩展表。 在此替代方法中,您创建一个表,其中包含一组可以为不同数据类型(数字,字符串,日期/时间等)的可为空的列,其名称如DATA01,DATA02,DATA03 ......等等。 对于每种任务,您可以选择列的子集并将它们映射到特定字段。 因此,DATA01可能最终成为SoftwareTask的BuildVersion和SalesTask的AccountName。 在此方法中,您必须在某处管理某些元数据,以控制将特定字段映射到的列。 类型映射表通常类似于:

TaskExt Table
=================
TaskID   : Number  (foreign key back to task)
Data01   : String
Data02   : String
Data03   : String
Data04   : String
Data05   : Number
Data06   : Number
Data07   : Number
Data08   : Number
Data09   : Date
Data10   : Date
Data11   : Date
Data12   : Date
// etc...

选项#1的主要好处是您可以根据需要动态添加任意数量的不同字段,甚至可以支持一定程度的向后兼容性。 然而,一个重要的缺点是即使是简单的查询也会变得具有挑战性,因为对象的字段被转移到表中的行中。 Unpivoting原来是一个既复杂又往往表现不佳的操作。

选项#2的好处在于它易于实现,并且在行之间保持一对一的对应关系,使查询变得容易。 不幸的是,这也存在一些缺点。 第一个是列名完全没有信息,你必须引用一些元数据字典来了解哪些列映射到哪个类型的任务的字段。 第二个缺点是大多数数据库将表上的列数限制为相对较小的数字(通常为50-300列)。 因此,您只能使用这么多数字,字符串,日期时间等列。 因此,如果您键入的最终日期时间字段多于表支持,则必须使用字符串字段来存储日期,或者创建多个扩展表。

预先警告,大多数ORM库不提供对这些建模模式中的任何一种的内置支持。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM