【问题标题】:Understanding Header and Detail tables了解标题和详细信息表
【发布时间】:2018-06-12 08:14:39
【问题描述】:

我已经在各种数据库中看到了这一点,但我将使用最新的示例。 在AdventurWorks2012 DB中,有

  • PurchaseOrderHeader
  • PurchaseOrderDetail

  • SalesOrderHeader
  • SalesOrderDetail

我试图理解当您可以将所有信息放在一个表中而不是两个表中时,为什么会有此设置的概念。对不起,我对这种类型的设置缺乏了解。我想确保当我创建新表时,我想知道这种类型的设计,这将如何工作类似于我可能合并以使用 Header 和 Detail 将数据输入捕获到表中以及原因。

例如

  1. 当前日期
  2. 当前月份
  3. 当前财政年度
  4. 公司编号
  5. 修订号
  6. 服务产品1金额
  7. 服务产品2金额
  8. 服务产品3金额
  9. 服务产品4金额
  10. 服务产品5金额
  11. 总金额(以上 6-10 项总和)
  12. 认证日期
  13. 认证官
  14. 提交日期

希望我的问题很清楚。

=======================

通过我对@Szymon 的回复编辑了使用 Header/Detail 设置的详细示例

在我上面的示例中,将其布局为 Header/Detail 设置。提交记录时,它会生成一个 ID 所以我的 Header Table 如下所示:

标题表

1, '11/13/13',11,2013,'000001',0,10.00,'11/12/13','总统','查克','11/12/13'

然后在我的详细信息表中,它也会生成一个 ID,但使用以前的记录作为 FK,它看起来像这样...... 1(新 ID),1(以前的 Header Table 的 FK),2(作为服务产品 1)、2(作为服务产品 2)、2(作为服务产品 3)、2(作为服务产品 4)、2(作为服务产品 5)

明细表

1,1,2.00,2.00,2.00,2.00,2.00

================================================ ===

再次修订:提供更好的后续示例。

WKS_Header 表:(PK 为 WKS_Header_ID)

WKS_Header_ID [int] IDENTITY(1,1) NOT NULL,
Company_ID [varchar](6) NOT NULL,
Current_Date [DateTime] NOT NULL, 
Current_Month [int] NOT NULL, 
Current_Fiscal_Year [int] NOT NULL,
Revision_Number [int] NOT NULL,
Worksheet_ID [varchar] (13) NOT NULL,
Total_Amt [money] NOT NULL,
Certification_Date [DateTime] NOT NULL,
Certification_Officer [varchar] (50) NOT NULL,
Submission_Date [DateTime] NOT NULL

WKS_Header 表的样本记录:

1,'000001','11/5/13',11,2013,0,'0000001111300',20.00,'11/1/13','Chuck','11/2/13'
2,'000001','11/7/13',11,2013,1,'0000001111301',10.00,'11/4/13','Chuck','11/5/13'
3,'000500','11/10/13',11,2013,0,'0005001111300',50.00,'11/5/13','Bob','11/7/13'

WKS_LineItems 表:(PK 为 WKS_LineItems_ID)

WKS_LineItems_ID [int] IDENTITY(1,1) NOT NULL,
LineItem_Description [varchar] (50) NOT NULL,
Create_User_ID [varchar] (50) NOT NULL,
Create_Date [datetime] NOT NULL,
Modify_User_ID [varchar] (50) NOT NULL,
Modify_Date [datetime] NOT NULL

WKS_LineItems 表示例

1,'Service Product Widget A Amount','Admin','10/1/13',Null,Null
2,'Service Product Widget B Amount','Admin','10/1/13',Null,Null
3,'Service Product Widget C Amount','Admin','10/1/13',Null,Null
4,'Service Product Widget D Amount','Admin','10/1/13',Null,Null
5,'Service Product Widget E Amount','Admin','10/1/13',Null,Null
6,'Final Total Widgets Amount','Admin','10/1/13',Null,Null

WKS_Details 表:(PK 是 WKS_Details_ID,FK 是 WKS_Header 表中的 WKS_Header_ID)

WKS_Details_ID IDENTITY(1,1) NOT NULL,
WKS_Header_ID [int] NOT NULL,
WKS_LineItems_ID [int] NOT NULL,
WKS_Amount [decimal] (18,2) NOT NULL,
Create_User_ID [varchar] (50) NOT NULL,
Create_Date [datetime] NOT NULL

WKS_Details 表示例

1,1,1,4.00,'Chuck','11/5/13'
2,1,2,0.00,'Chuck','11/5/13'
3,1,3,0.00,'Chuck','11/5/13'
4,1,4,5.00,'Chuck','11/5/13'
5,1,5,11.00,'Chuck','11/5/13'
6,1,6,20.00,'Chuck','11/5/13'
7,2,1,0.00,'Chuck','11/7/13'
8,2,2,0.00,'Chuck','11/7/13'
9,2,3,0.00,'Chuck','11/7/13'
10,2,4,0.00,'Chuck','11/7/13'
11,2,5,0.00,'Chuck','11/7/13'
12,2,6,10.00,'Chuck','11/7/13'
13,3,1,10.00,'Bob','11/10/13'
14,3,2,10.00,'Bob','11/10/13'
15,3,3,10.00,'Bob','11/10/13'
16,3,4,10.00,'Bob','11/10/13'
17,3,5,10.00,'Bob','11/10/13'
18,3,6,50.00,'Bob','11/10/13'

场景: 从表单输入信息。它在 WKS_Header 表中创建 3 条记录,并将相关的详细记录记录到 WKS_Details 表中。

记录 ID 1 是原始提交,然后该用户需要修改数字。该用户输入另一条记录。那就是记录 ID 2,一个修改后的提交以取代记录 ID 1。 记录 ID 3 是原始提交。

我是否正确标准化了这个?

【问题讨论】:

  • 如果您描述了这些表格的结构,这将有很大帮助,以便我们这些不立即熟悉该模式的人能够分析它。猜测一下,我会说“标题”和“详细信息”表之间可能存在一对多的关系,这样您在订单中的每个订单项都有一个“详细信息”条目,但看不到至少两个表的列名和类型,不可能肯定地说什么。
  • @AaronMiller,这有帮助吗?
  • 确实如此; @Szymon 的回答完全正确。
  • @CharlesBernardes:您的修订看起来像是添加了一个完全不同的问题。您最初的问题是关于订单等标题/详细信息表,而您的修订似乎与历史/修订表有关,因此完全混淆了水。最好删除添加并提出单独的问题。什么是 WKS?

标签: sql database-design database-normalization


【解决方案1】:

这种类型的关系称为一对多关系。当有一个父记录和多个子记录时使用它。你使用这种关系到normalise data

如果是采购订单,您有一个描述订单的标题,例如订单号和日期。一个订单只有一组此类信息。

然后是多个订单项,每个订单项都有自己的项目名称、数量和价格。每张桌子都有很多项目。

如果您只创建一个表,则必须为每个项目重复发票抬头中的信息。您将有相同的订单日期和编号在与您拥有的项目一样多的行中重复。

这很糟糕有几个原因,其中包括:

  • 您的冗余数据占用了不必要的空间并且难以维护(例如,如果您想更新标头中的一个信息,则必须更新多条记录)。
  • 查询表更复杂,例如当您想显示订单标题列表时,您必须使用DISTINCT
  • 结构不标准(未规范化),对于期望采用标准数据库设计方法的其他人来说难以阅读。

【讨论】:

  • 在我上面的示例中,将其布局为 Header/Detail 设置。提交记录时,它会生成一个 ID 所以我的 Header Table 看起来像:
  • 您问了一个问题,要求澄清使用 2 个表格,所以我给出了这个。你还有什么想要的吗?
  • 在我上面的示例中,将其布局为 Header/Detail 设置。提交记录时,它会生成一个 ID 所以我的 Header Table 看起来像:1, '11/13/13',11,2013,'000001',0,10.00,'11/12/13','President ','Chuck','11/12/13' 然后在我的详细信息表中它也会生成一个 ID,但使用以前的记录作为 FK,它看起来像这样...... 1(新 ID),1(FK之前的标题表)、2(作为服务产品 1)、2(作为服务产品 2)、2(作为服务产品 3)、2(作为服务产品 4)、2(作为服务产品 5)
  • 我列出了我的回复,以便更好地查看我的原始帖子。谢谢。
  • 再次思考这个问题。请参阅我对原始帖子的编辑。谢谢。
【解决方案2】:

我相信这是作为一个标准化过程来完成的,以便减少冗余数据。

http://support.microsoft.com/kb/283878

【讨论】:

    【解决方案3】:

    除了 Szymon 的回答,我想指出使用页眉/详细信息表的更多优势

    1. 订单(即明细表)中的行数未定义。因此,一个订单可以有一行或一百行。在给出的示例中,一行仅限于五行。
    2. 提取有关线条的数据非常容易,因为每条线条都独立存在。如果有一个查询来找出给定部分的存在顺序,标题/详细信息结构使这很容易做到,而单个表意味着查询必须检查 field1、field2、field3 等。没那么简单.

    【讨论】:

    • 我在原始帖子上再次进行了编辑。这是更好的布局示例吗?
    【解决方案4】:

    Header 和 Detail 表概念用于在 SQL 中执行规范化。规范化是减少数据冗余的过程。我们无法删除数据冗余。但是我们可以减少数据冗余。数据冗余正在复制项目。数据冗余存在一些问题,如下所示。 如果一个表没有正确规范化并且具有数据冗余,那么它不仅会占用额外的内存空间。但也会使数据库的处理和更新变得困难,而不会面临数据丢失。如果数据库未规范化,插入、更新和删除分析非常频繁。

    您可以参考这些链接来学习规范化。

    https://www.studytonight.com/dbms/database-normalization.php

    https://www.guru99.com/database-normalization.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多