这种类型的“one-of”建模很棘手。一些数据库内置了对此类功能的支持,例如继承。
一种方法是创建一个attachments 表并将所有表合并到一个表中。这将具有以下列:
attachments_id
type check type in ('video', 'audio', . . .)
- 其中任何一个都需要列。
更常见的是,它们中的每一个都是一个单独的实体,因为描述它们的列会完全不同——而且通常有它们自己的关系。在这种情况下,针对少数类型的一个简单方法是为每个类型设置一个单独的列,以及最多一个不是NULL 的约束:
check ( (case when video_id is not null then 1 else 0 end) +
(case when audio_id is not null then 1 else 0 end) +
. . . <= 1
)
这允许正确声明外键关系。
另一种方法是对此的一种变体。假设所有 id 列都具有相同的类型,则使用列:
attachment_type varchar(255) check (attachment_type in ('video', 'audio', . . .),
attachment_id int
类型将确定id 的类型,但数据库不会对此进行验证。
另一种方法是更复杂的继承模式,它涉及为每个实体设置单独的表,以及每个表中的类型。然后设置一个attachments 表。这看起来像:
attachments_id int generated always as identity primary key,
attachment_type varchar(255) check (attachment_type in ('video', 'audio', . . .),
unique (type, attachments_id)
然后:
video_id int primary key,
type varchar(255) generated always as
foreign key video_id references (type, attachments_id)
其他表以此类推。这将建立与attachments 的外键关系并确保类型匹配。