mysql – Pizza&Food – 数据库设计

我想创建一个允许客户从网站订购食物的网站。

有两种食物类型:

>常规食物/饮料(例如:汉堡,不含烤肉串,薯片,焦炭,pepsi等)
>比萨食品(例如:玛格丽特比萨,肉类比萨等)

如果他们从列表中选择比萨饼,那么他们可能需要选择Base(薄外壳,软硬壳),Extras以及比萨尺寸/选项。

在这种情况下如何设计桌面?

注意:每个项目都有一个或多个选项。一个选项可能有额外的(1个或更多)或没有额外的。如果物品是比萨饼类型 – 那么它可能有基地(地壳)

截图原型

看到我试图实现的两个截图,我在数据库设计的正确路径上或者可以做得更好?

比萨定制:

牛肉汉堡定制:

附加功能(下拉菜单/刻录机)

在额外的时候,有时候我需要添加多个额外的下拉菜单,而不是tickboxes。这意味着客户只能从1,2或3个下拉列表中选择1个。

数据库设计

您将如何设置数据库模式来实现类似于上述定制选项?
这是我想出的:

类别表:

+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| cat_id   | int(11)      | NO   | PRI | NULL    | auto_increment |
| cat_name | varchar(100) | NO   |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

物品表:

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| item_id   | int(11)      | NO   | PRI | NULL    | auto_increment |
| cat_id    | int(11)      | NO   |     | NULL    |                |
| item_name | varchar(100) | NO   |     | NULL    |                |
| item_type | int(11)      | NO   |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+

– item_type(0 =正常,1 =比萨饼,2 =套餐)

item_options表:

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| option_id   | int(11)      | NO   | PRI | NULL    | auto_increment |
| item_id     | int(11)      | NO   |     | NULL    |                |
| option_name | varchar(100) | NO   |     | NULL    |                |
| price       | decimal(6,2) | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+

item_extras表:
(你认为应该有独立的表,比萨饼顶级和额外的?)

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| extra_id  | int(11)      | NO   | PRI | NULL    | auto_increment |
| option_id | int(11)      | NO   |     | NULL    |                |
| name      | varchar(50)  | NO   |     | NULL    |                |
| cost      | decimal(6,2) | NO   |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+

item_pizza_base表:

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| base_id   | int(11)      | NO   | PRI | NULL    | auto_increment |
| option_id | int(11)      | NO   |     | NULL    |                |
| base_name | varchar(50)  | NO   |     | NULL    |                |
| cost      | decimal(6,2) | NO   |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+

SQL结果:

mysql> select * from categories;
+--------+----------+
| cat_id | cat_name |
+--------+----------+
|      1 | Pizzas   |
|      2 | Burgers  |

mysql> select * from items;
+---------+--------+------------------+-----------+
| item_id | cat_id | item_name        | item_type |
+---------+--------+------------------+-----------+
|       1 |      1 | Vegetarian Pizza |         1 |
|       2 |      2 | Beef Burger      |         0 |

mysql> select * from item_options;
+-----------+---------+-------------+-------+
| option_id | item_id | option_name | price |
+-----------+---------+-------------+-------+
|         1 |       1 | 12 Inches   |  5.60 |
|         2 |       1 | 14 Inches   |  7.20 |
|         3 |       2 | 1/4lb       |  1.80 |
|         4 |       2 | 1/2lb       |  2.50 |

mysql> select * from item_extras;
+----------+-----------+-----------+------+
| extra_id | option_id | name      | cost |
+----------+-----------+-----------+------+
|        1 |         1 | Mushroom  | 1.00 |
|        2 |         1 | Pepperoni | 1.00 |
|        3 |         2 | Mushroom  | 1.00 |
|        4 |         2 | Pepperoni | 1.00 |
|        5 |         3 | Chips     | 0.50 |
|        6 |         4 | Chips     | 0.50 |

正如你可以看到额外的汉堡和比萨在1表..应该分开吗?

mysql> select * from item_pizza_base;
+---------+-----------+------------+------+
| base_id | option_id | base_name  | cost |
+---------+-----------+------------+------+
|       1 |         1 | Thin Crust | 0.00 |
|       2 |         1 | Deep Crust | 0.00 |
|       3 |         2 | Thin Crust | 0.00 |
|       4 |         2 | Deep Crust | 0.00 |
+---------+-----------+------------+------+

请记住,每个项目的价格附加功能并不总是相同的。例如:比萨尺寸10“将为每个额外费用1.00,12”比萨饼为0.50。每个比萨饼也会有不同的额外费用。

数据库设计是否正确或可以改进?

Im stuck with Extras functionality – how to design table and fields for the dropdown extras? See my question “Extras functionality (Dropdown / tickboxes)”

如果您需要下拉菜单,请将下拉列表的值放在表格中。
只要在下拉列表中轻松分离出所需的值,就可以在其中添加额外的值。

Example

table option_labels
-------------------
id    integer auto_increment PK
name  varchar(40)

table toppings
--------------
id               integer  auto_increment PK
option_label_id  integer  foreign key references option_labels(id)
item_id          integer  foreign key references items(item_id)
price            decimal(10,2)

一旦您知道该项目,您可以使用以下方式填充下拉列表:

SELECT ol.name, t.price FROM toppings t
INNER JOIN option_labels ol ON (t.option_label_id = ol.id)
WHERE t.item_id = '$item_id'

规范化这些表
这个表有一个很大的缺陷:

mysql> select * from item_extras;
+----------+-----------+-----------+------+
| extra_id | option_id | name      | cost |
+----------+-----------+-----------+------+
|        1 |         1 | Mushroom  | 1.00 |
|        2 |         1 | Pepperoni | 1.00 |
|        3 |         2 | Mushroom  | 1.00 |
|        4 |         2 | Pepperoni | 1.00 |
|        5 |         3 | Chips     | 0.50 |
|        6 |         4 | Chips     | 0.50 |
+----------+-----------+-----------+------+

它没有正常化,将名称放在一个单独的标签表中,就像上面的例子。如果一行(不包括id)不是唯一的,那么您的数据不会正常化,并且您的错误。

因为你正在使用很多的连接,所以IMHO最好使用InnoDB,它有一些很酷的功能来加速使用PK的联接。

不管人说什么
慢慢开始之前不要进行非规范化。

使用索引
将索引放在名为* _id的所有字段上。
还可以在where子句中常用的alls字段中设置一个索引。
不要在低基数的字段上放置索引,所以在布尔值或枚举字段上没有索引!
索引减慢插入并加快选择。

http://stackoverflow.com/questions/7284687/pizza-food-database-design

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:mysql – Pizza&Food – 数据库设计