3

我需要帮助以使我的数据库设计更好。

db 设计来自老开发人员,现在我试图通过放置外键来更好地设计,这样就不会有任何孤儿表。

情况1:

这是故事:

我有表格ProductGroup(PG),ProductType(PT),Brand(B),Design(D)来保留项目的所有具体细节。然后将所有四个表组装成一个表ProductMaster(PM),它们将在其中连接并生成一个ProdCd.

当删除任何一行时PG,PT,B,G,PM 中的所有相关行也将被删除。

有表格的示例(代码将被简化):

CREATE TABLE [dbo].[ProductMaster](
    [ProdCd] [varchar](25) NOT NULL,
    [GCd] [varchar](15) NULL,
    [ACd] [varchar](15) NULL,
    [BCd] [varchar](15) NULL,
    [CCd] [varchar](15) NULL,
    [ProdType] [varchar](50) NULL,
    [BrandCd] [varchar](25) NULL,
    [Design] [varchar](150) NULL,
 CONSTRAINT [PK_ProductMaster] PRIMARY KEY CLUSTERED 
(
    [ProdCd] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[ProductGroup](
    [GCd] [varchar](15) NOT NULL,
    [GroupDesc] [varchar](150) NULL,
 CONSTRAINT [PK_ProductGroup] PRIMARY KEY CLUSTERED 
(
    [GCd] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[ProductType](
    [GCd] [varchar](1) NOT NULL,
    [ACd] [varchar](15) NOT NULL,
    [ProdType] [varchar](50) NOT NULL,
    [TypeDesc] [varchar](150) NULL,
 CONSTRAINT [PK_ProductType] PRIMARY KEY CLUSTERED 
(
    [GCd] ASC,
    [ACd] ASC,
    [ProdType] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[Brand](
    [GCd] [char](1) NOT NULL,
    [BCd] [varchar](15) NOT NULL,
    [BrandCd] [varchar](25) NOT NULL,
    [BrandName] [varchar](75) NULL,
 CONSTRAINT [PK_Brand] PRIMARY KEY CLUSTERED 
(
    [GCd] ASC,
    [BCd] ASC,
    [BrandCd] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[Design](
    [GCd] [char](1) NOT NULL,
    [CCd] [varchar](15) NOT NULL,
    [DesignCd] [varchar](25) NOT NULL,
    [DesignDesc] [varchar](150) NULL,
 CONSTRAINT [PK_Design] PRIMARY KEY CLUSTERED 
(
    [GCd] ASC,
    [CCd] ASC,
    [DesignCd] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

样本是:

  • ProductMaster( 100010010001, 1, 0001, 001, 0001, PC-10 A, ZEN, PLAIN WHITE)
  • ProductGroup( 1, Finished Goods)
  • ProdType( 1, 0001, PC-10 A, Dinner Plate 10 Inch)
  • Brand( 1, 001, ZEN, ZEN)
  • Design( 1, 0001, PLAIN WHITE, NO DECAL PLAIN WHITE)

如果我删除 的Design(1, 0001, PLAIN WHITE, NO DECAL PLAIN WHITE),整个行都ProductMaster将被删除。

案例二:

我有一个包含标题和详细信息的交易表。明细只保留表“ProductType”中的“ACd”,其中“GCd”始终为 1。当修改 PG、PT、B、G 时,事务上的记录也被修改为“GCd”=1。

表是这样的:

CREATE TABLE [dbo].[PFHdr](
    [FNO] [varchar](25) NOT NULL,
    [FMO] [varchar](6) NULL,
    [FDate] [datetime] NULL,
    [GCd] [int] NULL, *This is group related to the transcation not with the PM
    [IQtyc] [float] NULL,
    [RQtyc] [float] NULL,
    [TQtyc] [float] NULL,
 CONSTRAINT [PK_PFrmHdr] PRIMARY KEY CLUSTERED 
(
    [FNO] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[PFDtl](
    [FNO] [varchar](25) NOT NULL,
    [ACd] [varchar](15) NOT NULL,
    [Input] [float] NULL,
    [Reject] [float] NULL,
    [Transfer] [float] NULL,
 CONSTRAINT [PK_PFrmDtl] PRIMARY KEY CLUSTERED 
(
    [FNO] ASC,
    [ACd] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

样本是:

  • PFHdr(201211-00001,00001,2012-11-26,1,10,0,10)
  • PFDtl(201211-00001,0001,5,0,5)
  • PFDtl(201211-00001,0002,5,0,5)

ProdType如果( )的 ProductType 记录1, 0001, PC-10 A, Dinner Plate 10 Inch被删除,PFDtl 上的记录也被删除。但是如果记录ProdType7, 0001, PC-12 A, Dinner Plate 12 Inch)被删除,PFdtl 上的记录并没有改变。

请帮助我,对设计发表评论,

  1. 如何让它变得更好?
  2. 如何应用外键是可能的?
  3. 对数据库设计有什么建议吗?
  4. 在 CASE 2 中,我应该添加列“GCd”以便能够使用外键吗?
  5. 如果 ProductType 上的 ProdType 必须是唯一的,我应该将其用作主键(使用 GCd 和 ACd)还是只需要设置 UNIQUE 或不设置任何限制

笔记:

  1. 旧设计没有任何外键,都是应用受限的
  2. 我添加第二种情况
4

1 回答 1

1

这里真的有两个问题。是否存在外键?如果存在外键,是否声明了它们?当我阅读您的架构时,其中有一些外键,例如 ProductMaster.GCd。他们只是没有被宣布。

声明外键的优点是它限制数据以防止丢失“引用完整性”,即外键实例引用不存在的主键的情况。这称为“孤立引用”。一般来说,强制引用完整性的优势远远大于在插入时让 DBMS 检查完整性的成本,以及处理被拒绝数据所需的额外编程。

如果您想向现有数据库添加引用完整性约束,您可能必须在 DBMS 允许您放入约束之前找到并处理“孤立引用”。这通常会涉及大量使用“WHERE NOT EXISTS”构造。

太糟糕了,以前的开发人员一开始就没有声明外键。

于 2012-11-26T11:55:36.327 回答