首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Server数据库设计与外键混淆

Server数据库设计与外键混淆
EN

Stack Overflow用户
提问于 2012-11-26 09:06:58
回答 1查看 446关注 0票数 3

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

db的设计是从老的开发人员,现在我试图得到更好的设计,试图把外键周围,这样就不会有任何孤儿表。

案例1:

下面是一个故事:

我有表格ProductGroup (PG)、ProductType (PT)、Brand (B)、Design (D)来保持项目的所有细节。然后,所有四个表都组装成一个表ProductMaster (PM),在那里它们将被连接并生成一个ProdCd

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

下面是表的示例(代码将简化):

代码语言:javascript
复制
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中的整行。

案例2:

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

桌子是这样的:

代码语言:javascript
复制
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-0001,0001,5,0,5)
  • PFDtl(201211-0001,0002,5,0,5)

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

请帮我,评论一下设计,

  1. 怎样才能做得更好?
  2. 如何应用外键是可能的?
  3. 对DB设计有什么建议吗?
  4. 在第二种情况下,我应该添加列"GCd“才能使用外键吗?
  5. 如果ProdType on ProductType必须是唯一的,我应该使用它作为主键(带有GCd和ACd)还是只需要放置唯一或不设置任何限制

注:

  1. 旧的设计没有外键,所有的应用都受到限制。
  2. 我加上第二种情况
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-26 11:55:36

这里真的有两个问题。外键在吗?如果外键是存在的,他们是申报的?当我阅读您的模式时,其中有一些外键,如ProductMaster.GCd。他们只是没有被宣布。

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

如果要向现有数据库添加引用完整性约束,则在DBMS允许输入约束之前,可能必须找到并处理“孤立引用”。这通常涉及大量使用“哪里不存在”构造。

可惜的是,上一个开发人员一开始就没有声明外键。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13561622

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档