我正在努力让我的数据库设计正确。这是一大套酒精饮料,包括啤酒,白酒,葡萄酒等。我可以将它们保存在一个表中,如下所示:
id category brand type price quantity description
1 Beer Heineken bottle $2.00 100 some description...
2 Beer Calsburg bottle $3.00 200 some description
3 Beer Heineken can $1.00 300 some description....
4 Liquor JWalker bottle $30.00 100 some descri...
似乎这是一个糟糕的设计,考虑到类别和品牌的重复将会发生。因此,我将其分为3个表格如下:
类别表
id name(pk)
1 Beer
2 Liquor
品牌表
id name(pk) category_name(FK)
1 Heineken Beer
2 Carlsburg Beer
3 Lindemans Wine
4 JWalker Liquor
产品表
id(PK) type price quantity description category_name(FK) brand_name(FK)
1 Bottle $2.00 100 some description Beer Heineken
认为这会更好地规范化,但我看到它的方式,与第一张表几乎没有区别。我也以类型repeatnig结束,因为我可以重复瓶子,罐头等等。那我应该拿到第4张桌子吗?
尝试规范化并尽可能保持合理。有没有更好的方法来做这个?
答案 0 :(得分:0)
Brand Table
brandID(PK) BrandName
Category table
BrandID(FK) CategoryID(PK) Categoryname
Product table
ProductID(PK) CategoryID(FK) description price quantity
答案 1 :(得分:0)
规范化需要了解功能依赖(FD)和连接依赖(JD)。你没有给他们。所以我们无法正常化。但是猜测你的应用程序和你的桌子,它在5NF。
据推测,id是一个独特的列。因此它在功能上确定每个列集。由于{id}的较小子集不是唯一的,因此它是候选密钥(CK)。据推测,由于那个CK,其他FD不会持有其他FD。因此该表位于5NF。
但是假设还有一个FD持有:一个给定的品牌只出现在同一类别。然后要标准化为5NF列类别应该删除,并且应该添加一个新的表格,品牌和&类别列和CK {品牌}。
或者假设一个品牌有一个或多个类别,而不是一行说明该类别是其产品的类别,它表明该类别是其产品品牌的一个类别。 (很奇怪,从那以后,对于有多个类别的品牌,表格不会给出产品类别。)然后规范化也给出了这两个表格,新的CK {category,brand}。但在这种情况下,这是因为多值依赖(MVD),即因为二进制JD。
PS介绍ID与规范化无关。
PPS您似乎认为重复的子行值意味着需要进行标准化。他们没有。规范化有时用于总是连接到表的表替换表。
答案 2 :(得分:-1)
通过BCNF进行规范化是基于功能依赖性。它不是基于列是包含文本还是数字。您似乎认为,因为类别列不止一次包含单词 Beer ,所以它需要“规范化”。事实并非如此。
那么这里的功能依赖是什么?
第二个FD可能是错的。可能是{品牌,类型}是决定因素。但我认为可能有一家公司在同一品牌下生产啤酒和白酒。所以我认为决定因素可能是{category,brand,type}。
那已经是5NF了。 “拆分”不会改善此表。
答案 3 :(得分:-2)
表创建看起来像这样:
create table product (
product_id int not null identity,
brand_id int not null,
category_id int not null,
primary key(product_id),
foreign key brand_id references brand(brand_id),
foreign key category_id references category(category_id)
);
create table brand (
brand_id int not null identity,
name varchar(80),
primary key(brand_id)
);
create table category (
category_id int int not null identity,
name varchar(80),
primary key(category_id)
);
你做一个JOIN来取回记录:
select p.product_id, c.name as category_name, b.name as brand_name
from product as p
join category as c on p.category_id = c.category_id
join brand as b on p.brand_id = b.brand_id