Sql server 2008 子系统上下文的数据库设计-KVP与列

Sql server 2008 子系统上下文的数据库设计-KVP与列,sql-server-2008,database-design,Sql Server 2008,Database Design,在复杂系统中,具有与多个实体相关的通用子系统是很常见的。例如,工作流引擎中的申请、工作和评估可能都有自己的工作流 有些甚至可能具有到子系统的>1链接,例如表单引擎,其中用户可能具有个人详细信息表单和员工历史记录表单 你甚至可以考虑日志记录是一个子系统,其中一个实体可以有多个日志记录。 有两种方法可以对此“上下文”建模,一种是使用KVP样式: 创建表工作流(WorkflowID、ContextObject varchar(20)、ContextKey int),其中ContextObject将包含

在复杂系统中,具有与多个实体相关的通用子系统是很常见的。例如,工作流引擎中的申请、工作和评估可能都有自己的工作流

有些甚至可能具有到子系统的>1链接,例如表单引擎,其中用户可能具有个人详细信息表单和员工历史记录表单

<>你甚至可以考虑日志记录是一个子系统,其中一个实体可以有多个日志记录。 有两种方法可以对此“上下文”建模,一种是使用KVP样式:

创建表工作流(WorkflowID、ContextObject varchar(20)、ContextKey int),其中ContextObject将包含“作业”、“用户”、“评估”和ContextKey将是作业ID、用户ID、评估ID等

另一种方法是使用具有可空列的更宽表,例如

创建表工作流(WorkflowID、JobID INT NULL、UserID INT NULL、AssessmentID INT NULL)

其中上下文键是互斥的

我想知道从性能的角度看,哪种方法“更好”,尤其是当行数增加到几十万到几百万时

KVP样式的表将以较窄的行(较大的表)结束,可空列方法具有较宽的行,但是可以在这些行上构建单独的索引。使用SQL Server,我们可以使用筛选索引为每个上下文创建索引,其中contextID不为null

使用可为空的列方法将使optmizer获得更好的统计信息,也就是说,如果它是一个基于JobID的连接,那么optimzier将知道在该表中的100万行中,只有10000行与JobID相关

我想知道人们对这两种不同的方法有什么看法

假设每个上下文都提供了相当高的基数(几乎每个上下文类型都有1个基数)。还假设SQL Server的最新版本