Har*_* A. 6 normalization database-design sql-server sql-server-2014
我正在研究一个数据建模项目,我正在尝试为一个history
只有四列的表找出最好的数据建模方法:
CREATE TABLE FooHistory
(
SecurityID INT (FK), -- Part of the natural PK.
FieldID INT (FK), -- Part of the natural PK.
DateCreated DATETIME2(0), -- Part of the natural PK.
Value VARCHAR(50)
);
Run Code Online (Sandbox Code Playgroud)
此表中的自然复合 KEY 将是(DateCreated, SecurityId, FieldID)
,并且 ETL 过程每 30 分钟将向此表添加 ~ 2K 行。
问题
声明复合 PRIMARY KEY (PK)(DateCreated, SecurityId, FieldID)
与添加新 IDENTITY 列(即系统生成的代理)并将其用作 PK 的优缺点?
我相信,如果我添加一个 IDENTITY 列并将其用作 PK,那么该表将不会处于第三范式(3NF)中,因为非 PK 列之间将存在函数依赖关系,即,(DateCreated, SecurityId, FieldID)
和Value
.
由于此表保留了历史数据,因此我不希望将此表加入其他外部表,应用程序将主要使用 SELECT 语句与其进行交互。基于这些假设,将表保持在 3NF 中并声明复合 PK 是否值得,或者我应该将 IDENTITY 列添加到该表中?
根据您对正在考虑的案例的描述,似乎(a )通过表的属性附加一列以保存系统分配的代理*(为简洁起见,代理)是(b)多余的。IDENTITY
History
当暂定的自然PRIMARY KEY (PK) 约束有可能被 FOREIGN KEY (FK) 约束定义引用时,保留代理的列可能很有用,但这种暂定的 PK 约束是
因此,具有指向单个列的 FK 约束(1)在某种程度上可以作为上述自然 KEY 的“替代品”,并且(2)将保持较轻的值,这是一种值得评估的可能性。关于History
手头的桌子,它在逻辑上既不宽,也没有沉重的物理脚手架支撑。
此外,为代理附加一列必然会使所讨论的表格更宽,因为它包含了一个暂时不需要的元素(也许?还有推测性的相应物理索引),因此它最终可能会表现得更慢。因此,考虑到它对数据库整体性能的影响,无论如何它可能不会提供任何实用价值。
这种特殊类型的列有时会有所帮助的情况是,当坚持代表独立实体类型的表时†但是,如您所知,即使在这种情况下,每个特定表也需要 (i) 单独和 ( ii) 上下文分析以确定粘贴此类列是否方便(我想这就是您提出问题的原因)。
在逻辑层面,维护代理的列,当然,既不会捕获更多的业务领域含义(这会阻碍结果集的可读性和解释),也不会保护真正的行唯一性(保留无意义值的列是额外的非数据人工制品,所以您仍然必须确保真正数据元素的行唯一性)。见这个优秀的堆栈溢出的答案被@PerformanceDBA有关这些方面的证据。
但是,您“可以”将其添加到History
表中,“使用”它作为 PK,同时通过 (a) 组合的配置将列的组合声明(DateCreated, SecurityId, FieldId)
为 ALTERNATE KEY ‡ (AK) UNIQUE 约束和 (b) 将所述组合中的每一列都指定为不可为空的(实际上保证行与真实数据元素相关的唯一性的安排)。这样,命名的非键列Value
将在功能上依赖于
因此,该表无论如何仍然符合 3NF §,尽管使用带有代理项的列不会提供好处,因此它会过度。
为什么它会过度的实际例子是:
History
表将主要通过 SELECT 语句进行查询,这些 SELECT 语句包含一个或多个作为 WHERE 子句中的条件的自然 AK 的列(而包含代理项的列几乎不会被包含在内,因为它们对最终用户没有意义)。重要的是要注意,在物理层面,建立一个良好的索引策略来服务于复合 PK 定义对于优化相关过程的功能至关重要,因此应该进行一些测试会议,例如,确定由适用的 INDEX(es) 配置辅助的合适的列顺序。
尾注
*系统分配的代理在 1979 年题为“扩展数据库关系模型以捕获更多含义”的论文中进行了评估,该论文由关系范式的创建者Edgar Frank Codd 博士撰写。在该论文中,规定不得向数据库用户显示代理值,即使在我看到的大多数数据库中都没有遵循该规则。目前的答案是基于这样一个假设,即在审议的场景中,代理就像普通的业务上下文值一样公开。
†在概念层面上,当实体类型(或实体原型)的每一个出现(即行,当保留在 SQL 表中时)都由它自己的一个或多个属性的值唯一标识时,实体类型(或实体原型)是独立的(即,列) 单独。甲依赖之一是,它需要一个(或多个)属性(一个或多个)属于其他实体类型,使得其每个的使用值的(一个或多个)的实例可以被唯一标识。
‡ ALTERNATE KEY 是一列(或列的组合),其中包含唯一标识相关表的每一行但未被选为 PRIMARY KEY 的值;每个表可以有零个、一个或多个备用键。
§要分析为什么会这样,看的真正定义,正常形态和标准化的数据的关系模型的大型共享数据银行(1970),并在连续的正常形式(如乔尔·布朗随后的回答表明)的进一步正常化数据库关系模型(1971),两者都自然地由 EF Codd 博士工作。值得一提的是,原始关系模型(1970)不包括代理。
归档时间: |
|
查看次数: |
2720 次 |
最近记录: |