【问题标题】:How to link multiple tables to a single ID如何将多个表链接到一个 ID
【发布时间】:2013-05-21 01:20:56
【问题描述】:

我正在尝试创建一个数据库(使用 PHP 和 MYSQL,使用 XAMPP)存储有关各种快餐店及其分店的信息,以及他们分店提供的菜单。我在我的数据库中创建了一些表详细介绍了快餐店、他们的分店、他们的菜单的类别和子类别以及他们在表格中提供的项目。表格的摘录/示例如下所示。

Restaurants
+-------------+----------------+
| RestaurantID| RestaurantName | 
+-------------+----------------+
|     1       | PizzaHut       |
|     2       | BurgerKing     |
|     3       | KFC            | 
|     4       | SubWay         |
+-------------+----------------+

Branches
+---------------+----------------+
| RestaurantName| BranchAddress  | 
+---------------+----------------+
|   KFC         | XXX-1234       |
|   KFC         | AAA-1234       |
|   KFC         | YYY-1234       | 
|   BurgerKing  | DDD-1234       |
+---------------+----------------+

Categories
+---------------+----------------+
| BranchAddress | Categories     | 
+---------------+----------------+
|   XXX-1234    | Fries          |
|   AAA-1234    | Burgers        |
|   YYY-1234    | Drinks         | 
|   DDD-1234    | Burgers        |
+---------------+----------------+

SubCategories
+---------------+----------------+
| Categories    | SubCategories  | 
+---------------+----------------+
|   Fries       | Cheese         |
|   Burgers     | Chicken        |
|   Drinks      | Carbonated     | 
|   Burgers     | Beef           |
+---------------+----------------+

Items
+---------------+----------------+
| SubCategories | Items          | 
+---------------+----------------+
|   Cheese      | CheeseFries    |
|   Chicken     | Zinger         |
|   Carbonated  | Pepsi          | 
|   Beef        | Whopper        |
+---------------+----------------+

从上面可以看出,每个餐厅可以有几个分店,每个分店可以有几个类别,每个类别可以有几个子类别,然后可以有几个项目。分店可能有相同的类别和/或子类别类别但里面有不同的项目。

我不认为集中的类别、子类别和项目表在这种情况下会起作用,因为每个餐厅的每个分店都是自己独立的个体实体,这需要自己的类别、子类别和项目集表。如果是这样,我该如何创建表以及设置必要的外键?

Categories
+----------------+
|  Categories    |
+----------------+
|  Drinks        |
|  Burgers       | 
|  Fries         | 
|  SetMeals      |  
+----------------+

SubCategories
+----------------+----------------+
| Category       |  SubCategories |
+---------------+-----------------+
| Drinks         | Carbonated     |
| Drinks         | Carbonated     |
| Drinks         | Carbonated     |
| Drinks         | Non-Carbonated |
| Burgers        | Beef           |
| Burgers        | Beef           |
| Burgers        | Chicken        |
+----------------+----------------+

SubCategories
+----------------+----------------+-------------+
| Category       |  SubCategories | Items       |
+---------------+-----------------+-------------+
| Drinks         | Carbonated     | Pepsi        |
| Drinks         | Carbonated     | Root Beer    |
| Drinks         | Carbonated     | Cola         |
| Drinks         | Non-Carbonated | Orange Juice |
| Burgers        | Beef           | Whopper      |
| Burgers        | Beef           | Cheese Burger|
| Burgers        | Chicken        | McChicken    |
+----------------+----------------+--------------+

当然,我可能是错的,在这种情况下,集中式表格可能会起作用。如果是这样,我可以提供一些示例和/或说明如何继续/或着手设置表格吗?

我想到了以下解决方案:

Restaurants
+-------------+----------------+
| RestaurantID| RestaurantName | 
+-------------+----------------+
|     1       | PizzaHut       |
|     2       | BurgerKing     |
|     3       | KFC            | 
|     4       | SubWay         |
+-------------+----------------+

Branches
+---------------+----------------+
| RestaurantName| BranchAddress  | 
+---------------+----------------+
|  KFC          | XXX-1234       |
|  KFC          | AAA-1234       |
|  KFC          | YYY-1234       | 
|  BurgerKing   | DDD-1234       |
+-------------+------------------+

Categories
+----------------+----------------+----------------+
| RestaurantName | BranchAddress  | Category       | 
+----------------+-----------------+----------------+
|  KFC           |     XXX-1234   | Fries          |
|  KFC           |     AAA-1234   | Burgers        |
|  KFC           |     YYY-1234   | Drinks         | 
|  BurgerKing    |     DDD-1234   | Burgers        |
+----------------+----------------------------------+

SubCategories
+----------------+----------------+----------------+----------------+
| RestaurantName | BranchAddress  | Category       |  SubCategories |
+----------------+-----------------+---------------+----------------+
|  KFC           |     XXX-1234   | Fries          | Cheese         |
|  KFC           |     AAA-1234   | Burgers        | Chicken        |
|  KFC           |     YYY-1234   | Drinks         | Carbonated     |
|  BurgerKing    |     DDD-1234   | Burgers        | Beef           |
+----------------+---------------------------------+----------------+

Items
+----------------+----------------+----------------+----------------+-------------+
| RestaurantName | BranchAddress  | Category       |  SubCategories | Items       |
+----------------+-----------------+---------------+----------------+-------------+
|  KFC           |     XXX-1234   | Fries          | Cheese         |CheeseFries  |
|  KFC           |     AAA-1234   | Burgers        | Chicken        |Zinger       |
|  KFC           |     YYY-1234   | Drinks         | Carbonated     |Pepsi        |
|  BurgerKing    |     DDD-1234   | Burgers        | Beef           |Whopper      |
+----------------+---------------------------------+----------------+-------------+

虽然上面的表格为每家餐厅及其分店提供了各自的类别、子类别、项目,但它一开始就违背了将它们分开的整个目的,而且非常愚蠢。

编辑:我试图对上面的表进行非规范化,以便我可以使用

查询它
$query="SELECT * FROM Items WHERE Restaurantname='BurgerKing' AND 
BranchAddress='XXX-1234' AND Category='Fries';
$result=mysqli_query($cxn,$query) or die("Error");
while($row=mysqli_fetch_assoc)
{
extract($row);
echo "$Item";
}

注意:我计划将来扩展数据库以包括非快餐店甚至非餐饮相关的商店,因此各种表(类别/子类别和项目)将不得不能够包含非餐饮相关商店的类别(例如电子产品/书籍等)

对于很长的问题,我深表歉意,如果我能得到任何建议和帮助,我将不胜感激。

谢谢!

【问题讨论】:

  • 你为什么要这样非规范化它。为什么你有分支地址的子类别。谁知道这也许是合法的。你是什​​么意思它违背了整个目的并且很愚蠢?
  • @Drew Pierce 我已经编辑了我的问题,以说明为什么我将其非规范化。我只是认为这很愚蠢,因为与其将其非规范化,我还不如将所有东西都放在一张大桌子上,然后像 Excel 表一样使用它,使用过滤器等查询。例如(SELECT * FROM Item WHERE RestaurantName='KFC';) 不必在我的查询中使用 JOINS,尽管这样做会破坏关系数据库的全部目的。 @yvytty

标签: php mysql database database-design normalization


【解决方案1】:

也不确定为什么要进行非规范化。您可以将与分支相关的列从类别和子类别中取出,将类别名称从子类别中取出,等等。将它们留在里面,您会复制大量数据,这不是您使用关系数据库的传统方式!您还应该通过 ID 而不是名称来关联这些表,因为加入时的比较更快。

您可以考虑使用多对多链接表将项目链接到分支。这样,您就可以满足您的要求,即能够将类别/子类别的特定项目与分支相关联,而无需关联整个类别/子类别。

CREATE TABLE item_link (
  id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  branch_id INT(11) NOT NULL,
  item_id INT(11) NOT NULL,
  KEY composite (`branch_id`, `item_id`)
);

请参阅我为您制作的fiddle,其中详细说明了我对您的架构提出的更改,并举例说明了您将如何使用这个新表来显示分支的菜单/库存。

【讨论】:

  • 我对表进行了非规范化处理,这样我就可以在不使用任何 JOINS 的情况下使用查询。关键字 KEY 在您的小提琴中做了什么?我尝试用谷歌搜索它,但我得到的只是复合主键,这没有意义,因为您在使用 KEY 关键字之前已经设置了主键。(我指的是 item_link 表以及其他表,例如(链))。
  • 应该只在极少数情况下使用非规范化,通常是当表很大(数十亿条记录)并且索引无法通过性能获得您。有关更多信息,请参阅 Jeff Atwood 的 this article。关键字 key 添加一个索引。如果你看一下fiddle中查询的执行计划,你会看到在加入item_link时使用复合键来检索记录。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-25
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
相关资源
最近更新 更多