规范化数据库以减少依赖性

Normalising a database to reduce dependency

我正在努力使我的数据库设计正确。它是由啤酒、白酒、葡萄酒等组成的一大套酒类饮品。我可以将其全部保存在一个 table 中,如下所示:

id category brand     type    price  quantity  description  

1  Beer     Heineken  bottle  .00  100       some description...
2  Beer     Calsburg  bottle  .00  200       some description
3  Beer     Heineken  can     .00  300       some description....
4  Liquor   JWalker   bottle  .00 100       some descri...

考虑到类别和品牌的重复,这似乎是一个糟糕的设计。因此我将它分成 3 tables 如下:

类别Table

id   name(pk)

1    Beer
2    Liquor

品牌Table

id   name(pk)    category_name(FK)
1    Heineken    Beer
2    Carlsburg   Beer
3    Lindemans   Wine
4    JWalker     Liquor

产品Table

id(PK)     type    price    quantity    description       category_name(FK) brand_name(FK)
1          Bottle  .00    100         some description  Beer              Heineken

认为这会更好地规范化,但在我看来,与第一个 table 几乎没有区别。我也以类型 repeatnig 结尾,因为我可以在瓶子、罐头等上重复。那么我应该为此获得第 4 个 table 吗?

试图正常化并尽可能保持理智。有没有更好的方法去做这件事?

Brand Table
brandID(PK) BrandName

Category table
BrandID(FK) CategoryID(PK) Categoryname

Product table
ProductID(PK) CategoryID(FK) description price quantity

Table 创建看起来像这样:

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

规范化需要知道函数依赖关系 (FD) 和连接依赖关系 (JD)。你还没有给他们。所以我们不能正常化。但是猜测你的应用程序和你的 table,它是 5NF。

大概 id 是一个唯一的列。因此它在功能上确定了每个列集。由于 {id} 的较小子集不是唯一的,因此它是候选键 (CK)。据推测,除了因为那个 CK 而持有的 FD 之外,没有其他 FD 持有。所以 table 在 5NF 中。

但假设还有一个 FD 成立:给定品牌只出现在同一类别中。然后归一化为 5NF 列类别应该被删除,并且应该添加一个新的 table 与品牌 & 类别列和 CK {brand}。

或者假设一个品牌有一个或多个类别,而不是声明类别是其产品类别的行,而是声明类别是其产品品牌的类别。 (很奇怪,从那时起,对于具有多个类别的品牌,table 不会给出产品的类别。)然后归一化也会给出这两个 tables,以及新的 CK {category, brand}。但在这种情况下,这是因为多值依赖性 (MVD),即因为二进制 JD。

PS引入ids与规范化无关

PPS 您似乎认为重复的子行值意味着需要规范化。他们没有。规范化是为了有时用 table 替换 table,而 table 总是加入它。

通过 BCNF 的规范化基于函数依赖性。它不基于列是否包含文本或数字。您似乎认为,因为类别列不止一次包含单词 Beer,所以它需要是 "normalized"。事实并非如此。

那么这里的函数依赖是什么?

  • id -> 类别、品牌、类型、价格、数量、描述 [​​=24=]
  • 类别、品牌、类型 -> ID、价格、数量、描述 [​​=24=]

第二个 FD 可能是错误的。 {brand, type} 可能是决定因素。但我认为很可能某处有一家公司以同一品牌名称生产啤酒和白酒。所以我认为决定因素可能是{category, brand, type}。

那已经在 5NF 中了。 "Splitting" 不会改进这个 table。