假设我有这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;
然而,这是执行此操作的最佳方式,因为它涉及检索完整的数据树并将其过滤掉?如果有一百万行或者这是最好的方法会有更好的方法吗?
答案 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