MySQL - 为此分层模型选择数据的最佳方法?

时间:2016-12-27 23:07:56

标签: mysql database

假设我有这4个表,包括各种外键关系(例如,某个区域必须属于某个位置,商店必须属于某个区域,商品价格必须属于商店等)。

----------------------------------
|Location Name | Location ID     | 
|              |                 | 
----------------------------------

-------------------------------------------------
|Area Name     |      Area ID    |  Location ID |
|              |                 |              |
-------------------------------------------------

-------------------------------------------------
|  Shop Name   |      Shop ID    |  Area ID     |
|              |                 |              |
-------------------------------------------------

----------------------------------
|  Item Price  |      Shop ID    |
|              |                 |
----------------------------------

我想要'项目价格'属于特定位置ID 。因此,所有地区和商店的商品价格总计为地点ID' x'。

我发现这样做的一种方法是将所有表连接到一个位置并获得金额,例如:

  SELECT SUM(Item Price) FROM
        items
        left join shops  ON (items.shop id = shops.shop id)
        left join areas  ON (shops.area id = areas.area id)
        left join locations  ON (areas.location id = location.location id)
  WHERE Location Id = 4; 

然而,这是执行此操作的最佳方式,因为它涉及检索完整的数据树并将其过滤掉?如果有一百万行或者这是最好的方法会有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

您可以尝试子查询 -

SELECT SUM(物品价格)FROM         项目         left join shops ON(items.shop id = shops.shop id)         左连接(从位置ID = 4的区域中选择区域ID)为Ar ON(shops.area id = areas.area id)

答案 1 :(得分:0)

如果您定义了正确的索引,那么查询不会读取每个表的所有数百万行。

想想电话簿以及如何查找姓名。你是否阅读了整本书的封面以寻找名字?不,你利用了这本书按姓氏,名字排序的事实,你直接去了名字。只需几次尝试即可找到合适的页面。事实上,对于一个有N个名字的书,平均需要大约log 2 N次尝试。

每次加入都会进行相同类型的搜索。如果您有索引,则每个比较表达式使用类似的查找来查找联接表中的匹配行。这很快。

但如果这还不够快,你也可以使用非规范化,在这种情况下,将所有数据存储在一个表中,列数很多。

----------------------------------------------------------------------
|Location Name  | Area Name  | Shop Name  | Item Name  | Item Price  |
|               |            |            |            |             |
----------------------------------------------------------------------

非规范化的优点是它避免了某些连接。它存储行就像您从示例连接SQL查询的结果集中获得的行之一。您只需从表中读取一行,即可获得所需的所有信息。

非规范化的缺点是数据的冗余存储。据推测,每个商店都有很多商品。但是每个项目都存储在一行中,这意味着该行必须重复商店,区域和位置的名称。

通过反复存储这些数据,您可以创建“异常”的机会,例如,如果您更改了某个商店的名称,但是您错误地仅在几行而不是商店名称出现的任何地方更改它。现在你有两个同名商店的名字,而另一个查看数据库的人无法知道哪一个是正确的。

一般情况下,维护多个规范化表格更为可取,因为每个“事实”只存储一次,因此不会出现异常。

创建索引以帮助您的查询足以满足大多数应用程序。

您可能会喜欢我的演示文稿How to Design Indexes, Really和视频:https://www.youtube.com/watch?v=ELR7-RdU9XU