Reputation: 3
I have a database which stores information about a game world. Specifically, I have a table to store all the different maps, and another to store the buildings in each map. A map can have 0-n buildings and I store the information as follows:
maps (map_id (PK), map_name)
buildings (building_id (PK), building_name, map_id (FK))
My problem is how to efficiently query the database to obtain the name of a map and all of its buildings. For example, I want to get 10 maps and their buildings.
SELECT * FROM maps JOIN buildings USING (map_id) limit 10
The above query could return 10 rows or 100, but it seems rather wasteful having so much duplication within the result table due to the map_name being repeated for each answer.
Alternatively, I could just get the map_ids first and then perform individual queries for each map. eg.:
SELECT map_id from maps limit 10
foreach map+id: SELECT * FROM buildings WHERE map_id = x
However, this again seems wasteful as I'm performing 11 separate SQL queries?
So to sum up, the first method seems memory/bandwidth inefficient, the second seems CPU inefficient. Am I right and is there a better way?
Upvotes: 0
Views: 115
Reputation: 79969
I think you are looking for this:
SELECT *
FROM buildings
WHERE map_id IN (SELECT map_id from maps limit 10)
Edit: Try this instead:
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)
Upvotes: 2
Reputation: 7986
I wouldn't worry about the memory/bandwidth being inefficient in your first query, this is what a relational database is designed for. Your tables are properly normalized so you are going to need to use a join to pull data from both tables. The fact that the map name and ID gets repeated on each row is trivial until you start having tens of thousands of maps and even then, it's probably not a big deal.
Now if you are going to display this information in a GUI so that the user could view it you might want to go with two separate queries - one to get the list of maps and then a separate query to get the list of buildings once the user has selected a map. If you give us an idea of what exactly you are trying to do we might be able to give better advice.
Upvotes: 1