MySQL - 数据库规范化 - 我做错了吗?

时间:2013-04-23 23:58:46

标签: mysql database-normalization

我一直在寻找几个小时,但似乎仍然无法绕过这个。我不明白我是如何以规范化的方式填充这些内容的。

问题1 -

+----+------+------------+-------------+----------+------+------------+--------------+-----------------+-----+-------+----------+-------------+--------+--------+------------+-----------------+---------------+---------+----------+----------+--------+----------+---------+--------+-------+------+--------+---------+
| id | year | wholesaler | design_line | style_no | size | size_range | retail_price | wholesale_price | hue | color | illusion | iridescence | fabric | length | silhouette | bodice_cut_outs | back_cut_outs | closing | neckline | shoulder | sleeve | feathers | sequins | stones | beads | lace | ruches | updated |

^袍

我为其中许多列创建了单独的表。如,

+----+--------+
| id | type   |
+----+--------+
|  1 | no     |
|  2 | zipper |
|  3 | corset |
+----+--------+

^ closing_flag

我希望gown.closing唯一可能的选项是closing_flag.type的值。如果它只有两列,那么使用单独的表进行规范化是不合适的吗?


问题2-我有其他列,例如hue,我希望能够为其填充多个值 - 对于具有多个色调的礼服,而不是多个色调中可用的礼服样式。所以,我创建了

+----+---------+
| id | hue     |
+----+---------+
|  1 | yellow  |
|  2 | green   |
|  3 | blue    |
|  4 | violet  |
|  5 | fuschia |
|  6 | red     |
|  7 | orange  |
|  8 | brown   |
|  9 | black   |
| 10 | grey    |
| 11 | white   |
| 12 | print   |
+----+---------+

^ hue_flag

但是,如何将hue_flag中的多个值插入到礼服中?


问题3-我的礼服中有多列应具有相同的可能值。羽毛,亮片,宝石,珠子,花边和皱纹都是应包含描述其覆盖量的值的列。所以,我创建了

+----+---------+
| id | amount  |
+----+---------+
|  1 | no      |
|  2 | few     |
|  3 | some    |
|  4 | many    |
|  5 | totally |
+----+---------+

^ coverage_flag

如何在另一个表中为多列使用相同的值可能性?再说一次,有一个只有两列的表是不是很奇怪?我是否错过了正常化的观点?我试图尽可能地保持传统,但似乎我最终会以这种方式使用更多空间,而不是简单地将值存储在两个表,用户和礼服中。

当然,我不指望有人能够达到我提出的所有要点。我只想彻底解释我的问题。相信我还有其他人,但他们都属于这三种类型中的一种。我已经倾注[在这里输入链接描述] [这个]和其他类似的文章,但可以做出如何实际应用概念的头脑或尾巴。

为可读性而编辑。

3 个答案:

答案 0 :(得分:1)

问题1:我会在你的礼服表中使用closing_type_id列。这样,您可以告诉数据库确保没有不存在具有不存在的closing_type的礼服,并且在重命名closing_type时,您只需要在一个地方更改它。

我认为只有两列的表格没有任何问题。

此外 - close_type为none是否有意义?也许如果一件礼服没有closing_type,那么给它一个closing_type_id为0会更有意义吗?

问题2:你应该使用另一个表,也许是gown_hues,有gown_id和hue_id列。然后,您可以在该表中为每件礼服的每种颜色设置一行。设置它,以便您可以通过SELECT * FROM gown_hues WHERE gown_id = $gown_id检索与特定礼服相关的所有色调。一个经验法则:除了尝试让一个字段包含多个值之外,几乎总是有更好的方法。

问题3:这似乎是合理的。你的礼服表中的列是否包含字符串或coverage_flag的id?我会选择后者(因为没有重复的信息)。然后在其他表中执行相同的操作 - 任何其他可以被不同程度的东西覆盖的实体都可以包含coverage_flag表的外键。

答案 1 :(得分:0)

按顺序回答您的问题:

1)不,这不是问题。使gown.closing依赖于closing.id的外键

2)我的头顶有两种方式。您可以创建一个带有Id的hue表,以及一个链接Gown Id和Hue Id的Gown_Hue链接表。或者您可以将GownId添加到Hue表中并确保它没有唯一约束。这样你就不会在Gown中插入多个值。如果我这样做,我会使用Link表的第一种方法。

3)基本上这与问题二的答案相同。

在psuedo-code中给出一个例子,你将有3个表

table Gown
{
   id UniqueIdentifier primary Key
}

table Hue
{
   id UnqiueIdentifier primary key
   hueDescription ntext
}

table Gown_Hue_Link 
{
   gownId UniqueIdentifier foreignKey => Gown.id
   hueId UniqueIdentifier foreignKey => Hue.id
}

所以为你的礼服得到Hue:

SELECT g.Id, h.hueDescription
FROM Gown g
 INNER JOIN Gown_Hue_Link ghl on ghl.gownId = g.id
 INNER JOIN Hue h on ghl.hueId = h.Id
WHERE G.id = <gown id>

我更喜欢上述方法,因为这意味着你只需要有一个可以与许多礼服相关联的色调,但你也可以用两个表来做到这一点:

table Gown
{
   id UniqueIdentifier primary Key
}

table Hue
{
   id UnqiueIdentifier primary key
   gownId UniqueIdentifier foreignKey => Gown.id
   hueDescription ntext
}

SELECT g.Id, h.hueDescription
    FROM Gown g
     INNER JOIN Hue h on h.gownId = g.Id
    WHERE G.id = <gown id>

答案 2 :(得分:0)

听起来你走在正确的轨道上。

问题1:不,使用只有两列的表没有任何问题。

问题2:您需要一个中间表来将色调与礼服相关联。类似gown_hues的内容包含“gown_id”和“hue_id”列。

问题3:是的,您可以使用相同的coverage表格关联多个表中的“coverage”。每个表都应包含与coverage_id表中的值相关的coverage