我有一个存储游戏世界信息的数据库。具体来说,我有一个表来存储所有不同的地图,另一个用于存储每个地图中的建筑物。地图可以有0-n建筑物,我按如下方式存储信息:
地图(map_id(PK),map_name)
建筑物(building_id(PK),building_name,map_id(FK))
我的问题是如何有效地查询数据库以获取地图及其所有建筑物的名称。例如,我想获得10张地图及其建筑物。
SELECT * FROM maps JOIN buildings USING (map_id) limit 10
上面的查询可以返回10行或100行,但由于每个答案都重复了map_name,因此在结果表中有如此多的重复似乎相当浪费。
或者,我可以先获取map_ids,然后对每个地图执行单独查询。例如:
SELECT map_id from maps limit 10
foreach map + id:SELECT * FROM buildings WHERE map_id = x
然而,由于我正在执行11个单独的SQL查询,这似乎又浪费了吗?
总而言之,第一种方法似乎内存/带宽效率低下,第二种方法似乎CPU效率低下。我是对的,还有更好的方法吗?
答案 0 :(得分:2)
我认为你正在寻找这个:
SELECT *
FROM buildings
WHERE map_id IN (SELECT map_id from maps limit 10)
修改:请改为尝试:
SELECT b.*, (SELECT map_name FROM maps m WHERE m.map_id = p.map_id) 'Map Name'
FROM buildings b
WHERE map_id NOT IN (SELECT map_id from maps limit 10)
答案 1 :(得分:1)
我不担心第一个查询中的内存/带宽效率低下,这就是关系数据库的设计目的。您的表已正确规范化,因此您将需要使用连接从两个表中提取数据。地图名称和ID在每一行上重复这一事实是微不足道的,直到你开始拥有成千上万的地图,即便如此,这可能也不是什么大问题。
现在,如果您要在GUI中显示此信息以便用户可以查看它,您可能需要使用两个单独的查询 - 一个用于获取地图列表,然后是单独的查询以获取建筑物列表一旦用户选择了地图。如果你让我们知道你究竟想做什么,我们可以提供更好的建议。