If you really want to avoid the extra table to express the relationship, you can do something like that:
CREATE TABLE "user" (
id integer primary key,
name text not null,
bookmarks integer[] not null
);
CREATE TABLE url (
id integer primary key,
time timestamp with time zone not null,
val text not null
);
Then finding all bookmarks for a particular user (say with id
66) would involve doing something like that:
SELECT url,time
FROM (SELECT bookmarks FROM "user" WHERE id=66) u
JOIN url ON url.id=ANY(bookmarks)
ORDER BY TIME;
Now here's why I don't like this schema. First, adding a new bookmark would require to rewrite the bookmarks array and hence the entire user
row (so adding n bookmarks, one after the other, would require Θ(n^2)
time). Secondly, you cannot use foreign keys on the elements of the array. Thridly, many queries will become more complicated to write, e.g. in order to retrieve all bookmarks for all users, you have to do something like that:
SELECT "user".id,"user".name,url.val,url.time
FROM "user",
LATERAL unnest((SELECT bookmarks)) b
LEFT JOIN url ON b = url.id;
Edit: So here's the schema I would use and which I think fits best with the relational paradigm
CREATE TABLE "user" (
id integer primary key,
name text not null
);
CREATE TABLE url (
id integer primary key,
val text not null
);
CREATE TABLE bookmark (
user_id integer not null REFERENCES "user",
url_id integer REFERENCES url,
time timestamp with time zone not null,
UNIQUE (user_id,url_id)
);