I have an application front end which speaks to a PostgreSQL database. I'm trying to find the most efficient way to extract a structure similar to the below.
CREATE TABLE people (
person_id SERIAL PRIMARY KEY,
fname VARCHAR
);
CREATE TABLE items (
person_id INTEGER REFERENCES people (person_id),
item_id SERIAL PRIMARY KEY,
title VARCHAR
);
INSERT INTO people (fname) VALUES
('Bob'),
('Jim'),
('Geoff');
INSERT INTO items (person_id, title) VALUES
(1, 'Cat'),
(1, 'Dog'),
(1, 'Monkey'),
(2, 'Elephant');
My current approach would be to list all of the items, then (within the application) iterate over each and run a SELECT
. Something similar to this Pseudo code:
items = db.Query(SELECT * FROM people);
for item in items
itemsub = db.Query(SELECT * FROM items WHERE id = item.person_id)
There are a number of reasons why I don't like this.
- It requires a minimum of
1 + N(People)
queries to extract a simple data structure. For a page containing 1000 items, this would produce a ton of network traffic. -
The application has to manually iterate over the list atleast twice more after the database, one to build the better structure and a second to render it.
-
It seems like something a database should be able to do
One other alternative would be to perform a JOIN
, but this would result in extra processing to remove duplicates in the application
The resulting structure should be relatively simple:
peopleItems{
array people{
array items{}
}
}
However, I can't for the life of me work out the best approach.
Best Answer
This is just an idea.
I don't know what application language you use (PHP, Ruby, or others), but all languages can easily parse this result.
I made dummy data and done EXPLAIN. The result is shown below:
This query uses Bitmap Index scan, so it can be run very fast.
Please don't forget to create index of person_id in the items table.