了解标题和详细信息表

Cha*_*des 2 sql database-design database-normalization

我已经在各种数据库中看到了这个,但我将使用最新的例子.在AdventurWorks2012数据库中,有

  • PurchaseOrderHeader
  • PurchaseOrderDetail

  • SalesOrderHeader的
  • 的SalesOrderDetail

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

例如

  1. 当前的日期
  2. 这个月
  3. 本财政年度
  4. 公司ID
  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','President','Chuck','11/12/13'

然后在我的详细信息表中它也会生成一个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
Run Code Online (Sandbox Code Playgroud)

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'
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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'
Run Code Online (Sandbox Code Playgroud)

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

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

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

Szy*_*mon 7

这种关系称为一对多关系.当有一个父记录和多个子记录时使用它.您使用这种关系来规范化数据.

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

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

如果您只创建一个表,则必须重复每个项目的发票标题中的信息.您将拥有相同的订单日期和数字,与您拥有的项目一样多.

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

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