SQL 两个不同表的外键
SQL Foreign key to two different tables
我有这样的问题
Table答:
-- TableBCId
Table乙:
-- 编号
Table C:
-- 编号
我正在寻找一种创建外键 table A 的方法,其中条目可以在 table B 或 table C
中
示例条目:
Table答:
-- TableBCId: 1
-- TableBCId: 2
Table乙:
-- 编号:1
Table C:
-- 编号:2
我想尽可能避免:
- table A
中的两列
- 默认值
- 附加 tables
- 无法创建基础实体
欢迎每个想法
您可以在 Table_A 上使用 insert/update 触发器。
也许是这样的:
CREATE TRIGGER Table_a_trgr
BEFORE INSERT OR UPDATE
on Table_a
FOR EACH ROW
DECLARE
c_row NUMBER;
BEGIN
SELECT count(*)
INTO c_row
FROM (
SELECT ID FROM table_b WHERE id = :NEW.TableBCId
UNION ALL
SELECT ID FROM table_c WHERE İd = :NEW.TableBCId
)
;
IF c_row < 2 THEN
raise_application_error(-20000, 'Error, Foreign Key');
END IF;
END;
/
实现此要求的正常方法是使用 2 列、2 个外键约束和一个检查约束以确保准确填充的列(如果这是一个要求):
create table a
( ...
, b_id references b
, c_id references c
, constraint <name> check ( (b_id is null and c_id is not null)
or (b_id is not null and c_id is null)
)
);
如果对您的 UI 有帮助,您可以在 table 上创建一个视图,将 B_ID 和 C_ID 合并到一个列中。
但是你说你不想要 2 列,这是为什么呢?
之所以难,是因为数据模型不对。一个外键只引用一个 table。 table 可以有多个外键,但每个外键都是独立的。撇开其他不说,你怎么知道 bc_id
引用的是 b.id
还是 c.id
?
对这种情况的一种解释是 table A
实际上应该是两个 table,BA
引用 B
和 CA
引用 C
。或者 A
应该引用超类型 table,其中 B
和 C
是子类型。在不知道实际业务领域的情况下很难确定。
无论如何,变化最少的路径是两列。
如果您不想在 table A 中创建新的列。
那你可以做一个parenttable给B和C
tableBC:
id
然后与 tables B 和 C 建立 1-1 关系到 table BC。
tableB:
id,
parent -- 1-1 foreign key to tableBC
tableC:
id,
parent -- 1-1 foreign key to tableBC
现在,在table一个
tableA:
id,
TableBCId -- foreign key to tableBC
我们已经使用这种方法解决了类似的问题。
我有这样的问题
Table答:
-- TableBCId
Table乙:
-- 编号
Table C:
-- 编号
我正在寻找一种创建外键 table A 的方法,其中条目可以在 table B 或 table C
中示例条目:
Table答:
-- TableBCId: 1
-- TableBCId: 2
Table乙:
-- 编号:1
Table C:
-- 编号:2
我想尽可能避免:
- table A
中的两列
- 默认值
- 附加 tables
- 无法创建基础实体
欢迎每个想法
您可以在 Table_A 上使用 insert/update 触发器。
也许是这样的:
CREATE TRIGGER Table_a_trgr
BEFORE INSERT OR UPDATE
on Table_a
FOR EACH ROW
DECLARE
c_row NUMBER;
BEGIN
SELECT count(*)
INTO c_row
FROM (
SELECT ID FROM table_b WHERE id = :NEW.TableBCId
UNION ALL
SELECT ID FROM table_c WHERE İd = :NEW.TableBCId
)
;
IF c_row < 2 THEN
raise_application_error(-20000, 'Error, Foreign Key');
END IF;
END;
/
实现此要求的正常方法是使用 2 列、2 个外键约束和一个检查约束以确保准确填充的列(如果这是一个要求):
create table a
( ...
, b_id references b
, c_id references c
, constraint <name> check ( (b_id is null and c_id is not null)
or (b_id is not null and c_id is null)
)
);
如果对您的 UI 有帮助,您可以在 table 上创建一个视图,将 B_ID 和 C_ID 合并到一个列中。
但是你说你不想要 2 列,这是为什么呢?
之所以难,是因为数据模型不对。一个外键只引用一个 table。 table 可以有多个外键,但每个外键都是独立的。撇开其他不说,你怎么知道 bc_id
引用的是 b.id
还是 c.id
?
对这种情况的一种解释是 table A
实际上应该是两个 table,BA
引用 B
和 CA
引用 C
。或者 A
应该引用超类型 table,其中 B
和 C
是子类型。在不知道实际业务领域的情况下很难确定。
无论如何,变化最少的路径是两列。
如果您不想在 table A 中创建新的列。
那你可以做一个parenttable给B和C
tableBC:
id
然后与 tables B 和 C 建立 1-1 关系到 table BC。
tableB:
id,
parent -- 1-1 foreign key to tableBC
tableC:
id,
parent -- 1-1 foreign key to tableBC
现在,在table一个
tableA:
id,
TableBCId -- foreign key to tableBC
我们已经使用这种方法解决了类似的问题。