如何在 postgresql 中表示元组数组?

问题描述 投票:0回答:1

这是我能想到的最简单的解释方法。想象一下,用户想要为一堆网页添加书签。有一个带有 UrlID 和实际 url 的 url 表。我希望用户有一个唯一的 UrlID 列表(但我不需要约束)和一个 32 位 int 值,例如纪元日期。我唯一关心的两件事是 1) 检查 UrlID 是否在此列表中 2) 获取整个列表并按日期(或第二个值)对其进行排序

如果有帮助,我预计不会超过 8K 书签,但很可能会 <128

postgresql
1个回答
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)
);
© www.soinside.com 2019 - 2024. All rights reserved.