了解标题和详细信息表

时间:2013-11-13 20:31:43

标签: sql database-design database-normalization

我在各种数据库中都看过这个,但我会使用最新的例子。 在AdventurWorks2012数据库中,有

  • PurchaseOrderHeader
  • PurchaseOrderDetail

  • 的SalesOrderHeader
  • 的SalesOrderDetail

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

e.g。

  1. 当前日期
  2. 本月
  3. 当前财年
  4. 公司ID
  5. 修订号
  6. 服务产品1金额
  7. 服务产品2金额
  8. 服务产品3金额
  9. 服务产品4金额
  10. 服务产品5金额
  11. 总金额(上述项目6-10)
  12. 认证日期
  13. 认证官
  14. 提交日期
  15. 希望我的问题很明确。

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

    通过我对@Szymon的回复

    编辑了使用标题/详细设置的详细示例

    在上面的示例中,将其布局为Header / Detail设置。提交记录时,它会生成一个ID,因此我的标题表看起来像:

    标题表

    1,' 11/13/13',11,2013,' 000001',0,10.00,' 11/12/13',&# 39;总统''夹头'&#39 11/12/13 39#;

    然后在我的详细信息表中它也会生成一个ID但是使用前一个记录作为FK,它看起来像这样...... 1(新ID),1(先前的标题表的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是原始提交。

    我是否正确地将其标准化了?

4 个答案:

答案 0 :(得分:7)

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

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

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

如果您只创建一个表,则必须重复每个项目的发票标题中的信息。您可以使用相同的订单日期和数字重复与​​项目一样多的行。

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

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

答案 1 :(得分:0)

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

请参阅http://support.microsoft.com/kb/283878

答案 2 :(得分:0)

除了Szymon的回答,我还想指出使用标题/详细信息表的一些优点

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

答案 3 :(得分:0)

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

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

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

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