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

食物有两种:

  • 常规食品/饮料(例如:汉堡,唐纳烤肉,薯片,可乐,百事可乐等)
  • 披萨食品(例如:玛格丽特比萨,肉比萨等)

  • 如果他们从列表中选择披萨-他们可能需要选择基本(薄皮,深皮),其他和披萨尺寸/选项。

    在这种情况下如何设计表格?

    注意:每个项目都有1个或更多选项。一个选项可能有额外的(1个或更多)或没有额外的。如果项目是披萨型-那么它可能有底料( shell )

    屏幕截图原型(prototype)

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

    披萨定制:

    牛肉汉堡定制:

    附加功能(下拉/勾选框)

    在临时演员上,有时我需要为下拉菜单而不是复选框添加多个额外演员。这意味着客户只能从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表:
    (您是否认为应该为披萨toppin和其他设置单独的表格?)
    +-----------+--------------+------+-----+---------+----------------+
    | 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 |
    

    正如您可以在一张桌子上看到的汉堡和披萨的额外内容..应该分开吗?
    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。每个披萨也会有不同的额外费用。

    数据库设计正确还是可以改进的?

    最佳答案



    如果需要进行下拉菜单,请将下拉菜单的值放在表中。
    只要可以在下拉菜单中轻松分离出所需的值,就可以在其中放置其他值。

    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字段上添加索引。
    请勿将索引放在基数较低的字段上,因此不要在 bool(boolean) 或枚举字段上添加索引!
    索引减慢插入速度并加快选择速度。

    10-01 08:32