当主键也是外键时,在 Postgres

Bas*_*que 8 postgresql foreign-key primary-key

在 Postgres 12 中,我正在跟踪照片。每个都很大,每个大约 6 到 8 兆。为了快速浏览,我将与完整图像一起存储缩略图。full 和thumbnail 都是 BYTEA 类型的列。

为了性能,我想避免在只需要缩略图时加载完整图像。据我了解,访问一行时,所有 BYTEA 字段值都将加载到内存中。因此,即使在查询中没有明确请求,向用户显示缩略图列表也必然会在服务器上加载完整的照片。

因此,我将把照片表分成两部分,将缩略图存储在主表中,并将缩略图存储在单独的子表中,以一对一的方式。

在这种情况下,子全图表携带其父缩略图行的 ID 作为外键。该外键列在逻辑上也可以用作主键。

我可以指定子项的一列既是外键又是主键吗?如果是这样,是否有任何需要注意的注意事项?

a_h*_*ame 10

主键和外键

我可以指定子项的一列既是外键又是主键吗?

是的,一点没错:

create table photo 
(
  id integer primary key, 
  ... other columns ...
);

create table thumbnail 
(
  id integer primary key references photo, 
  ... other columns ...
);
Run Code Online (Sandbox Code Playgroud)

吐司

bytea列存储在普通列数据之外(在所谓的“toast 表”中)并且不会被检索,除非您将它们包含在 SELECT 列表中。

从手册中引用

TOASTed 属性的大值只会在结果集发送到客户端时被拉出(如果选择了的话)。

这仅意味着即使查询被强制执行 Seq Scan,也不会检索 bytea 列,直到识别出需要发回的行。因此,如果您的查询对 100 万行进行了 seq 扫描,但只返回了 1 行,则只会读取一个字节值并将其发送到客户端。

请注意,如果缩略图足够小,则它们实际上可能会被内联存储(而不是在 toast 表中)(仅当大小低于约 2k 时才会触发 TOAST)