在多个其他 table 中包含一个 table 的值并允许 FK 引用
Include one table's values in multiple other tables and allow FK references
在设计 SQL 数据库方面,我仍然是一个相对的新手,如果这是我遗漏的明显问题,我深表歉意。
我有一些 tables 的受控词汇表用于某些值,我表示为引用受控词汇表 tables 的 FK(我试图表示的不同词汇表很少).我的模式规范允许这些词汇表中的每一个还允许一组受控的“未知”信息值(来自 DataCite)。下面是一个使用 table dates
的示例,它必须指定 date_type
,它应该是 date_types
或 unknown_values
中的值。我还有一些关于这个模型的 tables,每个都有自己特定的受控词汇表,但也应该允许来自 unknown_values
的值。因此 unknown_values
中的值应该在许多 table 具有与 date_types
.
相似结构的受控词汇表中共享
CREATE TABLE dates (
date_id integer NOT NULL PRIMARY KEY autoincrement ,
date_value date NOT NULL DEFAULT CURRENT_DATE ,
date_type text NOT NULL ,
FOREIGN KEY ( date_type ) REFERENCES date_types( date_type )
);
CREATE TABLE date_types (
date_type text NOT NULL PRIMARY KEY ,
definition text
);
CREATE TABLE unknown_values (
code text NOT NULL PRIMARY KEY ,
definition text
);
INSERT INTO date_types (date_type, definition)
VALUES
('type_a', 'The first date type'),
('type_b', 'The second date type');
INSERT INTO unknown_values (code, definition)
VALUES
(':unac', 'Temporarily inaccessible'),
(':unal', 'Unallowed, suppressed intentionally'),
(':unap', 'Not applicable, makes no sense'),
(':unas', 'Value unassigned (e.g., Untitled)'),
(':unav', 'Value unavailable, possibly unknown'),
(':unkn', 'Known to be unknown (e.g., Anonymous, Inconnue)'),
(':none', 'Never had a value, never will'),
(':null', 'Explicitly and meaningfully empty'),
(':tba', 'To be assigned or announced later'),
(':etal', 'Too numerous to list (et alia)');
我的第一个想法是创建 date_types
和 unknown_values
的并集的视图,但是您不能对视图进行 FK 引用,所以这不是 suitable。
“最简单”的解决方案是在每个受控词汇表 table(date_types
等)中复制来自 unknown_values
的值,但感觉有重复值是不正确的。
我还考虑了一个 table 用于所有具有第三个字段的受控词汇表(类似于 vocabulary_category
,值类似于 'date'
),所以我所有的 tables 可以引用那个 table,但是我可能需要一个函数和一个 CHECK
约束来确保该值具有正确的“类别”。这感觉不雅和凌乱。
我对继续进行的最佳方式或搜索内容以寻求帮助感到困惑。我无法想象这种要求太罕见了,但我似乎无法在网上找到任何解决方案。我的目标数据库是 SQLite,但我也对 PostgreSQL 中可能的解决方案感兴趣。
您要求的是 FK 具有可选引用的能力 table。还发现 Postgres 和 SQLite(?) 都提供了这个选项(afaik 也没有任何其他 RDBMS)。 Postgres at lease 提供了一个解决方法,我不知道它在 SQLite 中是否可行。您需要:
- 删除当前定义的 FK 的非空约束
- 添加引用
unknown_values
table 的 FK 列
- 添加
check
约束,在列上恰好需要 1
date_type
并且新 FK 列为空。请参阅 num_nulls 函数。
您需要的更改:(参见 demo )
alter table dates
alter column date_type
drop not null;
alter table dates
add unknown_value text
references unknown_values(code);
alter table dates
add constraint one_null
check (num_nulls(date_type, unknown_value ) = 1);
注意:Postgres 不支持 autoincrement
关键字。使用生成的列 generated always as identity
(对于旧版本使用 serial
)也是如此。
在设计 SQL 数据库方面,我仍然是一个相对的新手,如果这是我遗漏的明显问题,我深表歉意。
我有一些 tables 的受控词汇表用于某些值,我表示为引用受控词汇表 tables 的 FK(我试图表示的不同词汇表很少).我的模式规范允许这些词汇表中的每一个还允许一组受控的“未知”信息值(来自 DataCite)。下面是一个使用 table dates
的示例,它必须指定 date_type
,它应该是 date_types
或 unknown_values
中的值。我还有一些关于这个模型的 tables,每个都有自己特定的受控词汇表,但也应该允许来自 unknown_values
的值。因此 unknown_values
中的值应该在许多 table 具有与 date_types
.
CREATE TABLE dates (
date_id integer NOT NULL PRIMARY KEY autoincrement ,
date_value date NOT NULL DEFAULT CURRENT_DATE ,
date_type text NOT NULL ,
FOREIGN KEY ( date_type ) REFERENCES date_types( date_type )
);
CREATE TABLE date_types (
date_type text NOT NULL PRIMARY KEY ,
definition text
);
CREATE TABLE unknown_values (
code text NOT NULL PRIMARY KEY ,
definition text
);
INSERT INTO date_types (date_type, definition)
VALUES
('type_a', 'The first date type'),
('type_b', 'The second date type');
INSERT INTO unknown_values (code, definition)
VALUES
(':unac', 'Temporarily inaccessible'),
(':unal', 'Unallowed, suppressed intentionally'),
(':unap', 'Not applicable, makes no sense'),
(':unas', 'Value unassigned (e.g., Untitled)'),
(':unav', 'Value unavailable, possibly unknown'),
(':unkn', 'Known to be unknown (e.g., Anonymous, Inconnue)'),
(':none', 'Never had a value, never will'),
(':null', 'Explicitly and meaningfully empty'),
(':tba', 'To be assigned or announced later'),
(':etal', 'Too numerous to list (et alia)');
我的第一个想法是创建 date_types
和 unknown_values
的并集的视图,但是您不能对视图进行 FK 引用,所以这不是 suitable。
“最简单”的解决方案是在每个受控词汇表 table(date_types
等)中复制来自 unknown_values
的值,但感觉有重复值是不正确的。
我还考虑了一个 table 用于所有具有第三个字段的受控词汇表(类似于 vocabulary_category
,值类似于 'date'
),所以我所有的 tables 可以引用那个 table,但是我可能需要一个函数和一个 CHECK
约束来确保该值具有正确的“类别”。这感觉不雅和凌乱。
我对继续进行的最佳方式或搜索内容以寻求帮助感到困惑。我无法想象这种要求太罕见了,但我似乎无法在网上找到任何解决方案。我的目标数据库是 SQLite,但我也对 PostgreSQL 中可能的解决方案感兴趣。
您要求的是 FK 具有可选引用的能力 table。还发现 Postgres 和 SQLite(?) 都提供了这个选项(afaik 也没有任何其他 RDBMS)。 Postgres at lease 提供了一个解决方法,我不知道它在 SQLite 中是否可行。您需要:
- 删除当前定义的 FK 的非空约束
- 添加引用
unknown_values
table 的 FK 列
- 添加
check
约束,在列上恰好需要 1date_type
并且新 FK 列为空。请参阅 num_nulls 函数。
您需要的更改:(参见 demo )
alter table dates
alter column date_type
drop not null;
alter table dates
add unknown_value text
references unknown_values(code);
alter table dates
add constraint one_null
check (num_nulls(date_type, unknown_value ) = 1);
注意:Postgres 不支持 autoincrement
关键字。使用生成的列 generated always as identity
(对于旧版本使用 serial
)也是如此。