这是我能想到的最简单的解释方法。想象一下,用户想要为一堆网页添加书签。有一个带有UrlID和实际网址的网址表。我希望用户有一个唯一的UrlID列表(但我不需要约束)和一个32位的int值,例如一个纪元日期。我关心的唯一两件事是:1)检查UrlID是否在此列表中; 2)获取整个列表并按日期(或第二个值)对其进行排序
如果它有帮助我预计不会超过8K书签,但最有可能是<128
答案 0 :(得分:0)
如果你真的想避免额外的表来表达这种关系,你可以这样做:
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
);
然后找到特定用户的所有书签(比如id
66)会涉及到这样的事情:
SELECT url,time
FROM (SELECT bookmarks FROM "user" WHERE id=66) u
JOIN url ON url.id=ANY(bookmarks)
ORDER BY TIME;
现在这就是我不喜欢这种架构的原因。首先,添加新书签需要重写书签数组,因此需要整个user
行(因此,一个接一个地添加n个书签需要Θ(n^2)
时间)。其次,您不能在数组的元素上使用外键。然而,许多查询将变得更复杂,例如,为了检索所有用户的所有书签,您必须执行以下操作:
SELECT "user".id,"user".name,url.val,url.time
FROM "user",
LATERAL unnest((SELECT bookmarks)) b
LEFT JOIN url ON b = url.id;
编辑:所以这是我将使用的架构,我认为最适合关系范式
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)
);