Vij*_*ale 2 normalization database-design
我正在设计一个数据库,其中有不同的产品和供应商。例如,我有一个产品“手机”,比如说苹果 5S。这将通过我的网站从 Mapple、Mango 等不同供应商处出售。
我无法为每个供应商存储数据,因为这会导致数据冗余。我一直在考虑产品表的以下列:
我们可以看到产品名称每次都重复,导致数据冗余。
我主要关心的是如何避免数据冗余?如何设计Product表?
MDC*_*CCL 10
根据 (a) 我们通过评论进行的一些讨论和 (b) 问题的内容,我们定义了您的业务环境的以下特征:
因此,除其他点外,存在涉及称为供应商和产品的实体类型的多对多 (M:N) 关联或关系。这是一个非常基本的——但同时,在准确建模时非常强大——构造通常用于塑造数据库概念模型的某些组件。
IDEF1X型号
因此,我创建了一个说明性的 IDEF1X 1图,它将先前制定的业务规则整合到一个图形设备中,如图 1所示:
如您所见,ProductSupplier
是描绘连接和的 M:N 关联的关联实体。Product
Organization
每个ProductSupplier
都由两个不同属性或属性的值的组合唯一标识,即,
SupplierId
(我分配给的角色名称Organization.OrganizationId
是为了表达这种属性在将2迁移到ProductSupplier
实体类型时所持有的含义)和
ProductId
,
所以它们被描述为一个复合 PRIMARY KEY。这些属性分别是对Organization
和 的FOREIGN KEY 引用Product
。
通过这种布局,我将与每个实体类型相关的属性排列在适当的位置:
出现的有关之间的关联性Product
和Organization
(让我们说,这表示该属性的时间点当给定的Organization
开始suppliying一定Product
)专门在关联实体类型包括在内。
仅与Organization
实体类型相关的属性放在相应的框中,属于Product
实体类型的属性也是如此。
我根据上面讨论的概念定义编写了后面的 DDL 语句,以便您可以更好地了解如何设计数据库的这一部分:
-- You should determine which are the most fitting
-- data types and sizes for all your table columns
-- depending on the exact business context characteristics.
-- As one would expect, you are free to make use of
-- your preferred (or required) naming conventions.
CREATE TABLE Organization (
OrganizationId INT NOT NULL,
Name CHAR(30) NOT NULL,
FoundingDate DATE NOT NULL,
Etcetera CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Organization_PK PRIMARY KEY (OrganizationId),
CONSTRAINT Organization_AK UNIQUE (Name) -- ALTERNATE KEY.
);
CREATE TABLE Product (
ProductId INT NOT NULL,
Name CHAR(30) NOT NULL,
SKU CHAR(30) NOT NULL,
Price INT NOT NULL, -- Retains an amount in Cents, but there are other options.
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT Product_PK PRIMARY KEY (ProductId),
CONSTRAINT Product_AK1 UNIQUE (Name), -- ALTERNATE KEY.
CONSTRAINT Product_AK2 UNIQUE (SKU), -- ALTERNATE KEY.
CONSTRAINT PriceIsValid_CK CHECK (Price > 0)
);
CREATE TABLE ProductSupplier ( -- Represents the conceptual M:N association.
SupplierId INT NOT NULL,
ProductId INT NOT NULL,
Etcetera CHAR(30) NOT NULL,
CreatedDateTime DATETIME NOT NULL,
--
CONSTRAINT ProductSupplier_PK PRIMARY KEY (SupplierId, ProductId), -- Composite PRIMARY KEY.
CONSTRAINT ProductSupplierToOrganization_FK FOREIGN KEY (SupplierId)
REFERENCES Organization (OrganizationId),
CONSTRAINT ProductSupplierToProduct_FK FOREIGN KEY (ProductId)
REFERENCES Product (ProductId)
);
Run Code Online (Sandbox Code Playgroud)
在这个逻辑结构中,如图所示:
所有这些因素都有助于防止在通过单个表的方式表示多个实体类型时可能出现的歧义。
衍生信息
随后,您可以从三个不同的基表中获取数据(例如,通过 JOIN 的 dint),以便利用逻辑结构并生成新表,其中包含您在问题中包含的图片中显示的信息。
在遵循关系模型原则设计的数据库中,列中包含的值的重复不仅是可以接受的,而且是预期的,同时严格禁止重复的行。
对于上面阐述的逻辑结构,所有表都是声明式约束的,以防止重复行的插入,因此很好地解决了避免这种有害冗余的问题。
关系规范化——一个值得一提的主题,因为你添加了规范化标签——是一个逻辑级别的过程,其目的是
通过第一范式分解其类型接受非原子值的表列,以便数据操作和压缩更容易被使用的数据子语言(例如,SQL)处理,以及
凭借连续的范式摆脱表的列之间的不良依赖关系,以避免引入其他类型危险冗余的更新异常。
当然,必须考虑所讨论的表和列所承载的含义。
我建议你花点时间测试一下我在前面的逻辑结构中呈现的表,这样你就可以确定它是否符合每个范式。
1 信息建模集成定义( IDEF1X ) 是一种非常值得推荐的数据建模技术,美国国家标准与技术研究院(NIST)于 1993 年 12 月将其定义为标准。它完全基于 (a)关系模型的创始人,即EF Codd 博士撰写的理论工作;关于 (b)实体关系视图,由PP Chen 博士开发;以及 (c) 逻辑数据库设计技术,由 Robert G. Brown 创建。
2 IDEF1X 将键迁移定义为“将父实体或通用实体的主键作为外键放置在其子实体或类别实体中的建模过程”。