【发布时间】:2018-03-23 02:39:19
【问题描述】:
我有 3 张桌子:
-
NETWORK_OPERATORs; -
NETWORK_CELLs:每个人都属于一个NETWORK_OPERATOR; -
IRIs:他们每个人都可以有任何一个:- 网络运营商 或
- 一个网络单元
但 1) 和 2) 之一是强制性的。
在 1) 的情况下,netOpId 必须存在于 NETWORK_OPERATOR 表中;
在 2) 的情况下,cellId+netOpId 必须存在于 CELL 表中;
这是一个示例 DDL 代码:
CREATE TABLE "NETWORK_OPERATOR" (
"NETOPID" INTEGER NOT NULL,
"NAME" VARCHAR2(20),
CONSTRAINT "NETWORK_OPERATOR_PK" PRIMARY KEY ("NETOPID")
)
CREATE TABLE "NETWORK_CELL" (
"CELLID" INTEGER NOT NULL,
"NETOPID" INTEGER NOT NULL,
"NAME" VARCHAR2(20),
CONSTRAINT "NETWORK_CELL_PK" PRIMARY KEY ("CELLID"),
CONSTRAINT "CELL_NETOPS_FK" FOREIGN KEY ("NETOPID") REFERENCES "NETWORK_OPERATOR" ("NETOPID")
)
CREATE TABLE "IRI" (
"IRIID" INTEGER NOT NULL,
"NETOPID" INTEGER,
"CELLID" INTEGER,
"NAME" VARCHAR2(20),
CONSTRAINT "IRI_PK" PRIMARY KEY ("IRIID"),
CONSTRAINT "IRI_NETOPS_FK" FOREIGN KEY ("NETOPID") REFERENCES "NETWORK_OPERATOR" ("NETOPID")
)
换句话说,
NETWORK_CELL 本身总是绑定到 NETWORK_OPERATOR,因此 IF IRI 有一个 netOpId 它应该被强制为现有的netOpId,ELSE IF 一个IRI 有一个cellId+netOpId 它应该被强制为一个现有的cellId+netOpId
我看到了 2 个选项:
选项 1:
只制作IRI.NETOPID NOT NULLable 并添加复合外键
CREATE TABLE "IRI" (
...
"NETOPID" INTEGER NOT NULL,
"CELLID" INTEGER,
...
CONSTRAINT "IRI_CELL_FK" FOREIGN KEY ("CELLID", "NETOPID") REFERENCES "NETWORK_CELL" ("CELLID", "NETOPID")
)
(当然"NETWORK_CELL" ("CELLID", "NETOPID")上会有唯一键)
换句话说,IRI 将与网络运营商具有强制性的 FK 关系,与网络单元具有可选的 FK 关系。
“可疑”的事情是这个“可选”FK 是由 IRI 方面的一个必填字段和一个可选字段组成的。
Oracle RDBMS 接受这一点(我刚刚尝试过),但这是一个好习惯吗?
选项 2:
与选项 1 中相同的 FK,但保留 IRI.NETOPID 可为空并添加一个自定义约束以强制执行 either netOpId or netOpId+cellId
我觉得这个解决方案更便携,但也许我错了。
问题
还有更好的选择吗?
处理这种情况的最佳做法是什么?为什么? 我也在考虑移植到其他 RDBMS...
谢谢
【问题讨论】:
-
嗨。这是一个常见问题解答。谷歌 sql/数据库子类型/继承/多态。还有许多/多个 FK 到许多/多个表(反模式)。你应该找到这些谷歌搜索——总是用谷歌搜索你的问题/问题/目标的许多清晰、简洁和具体的版本/措辞,并阅读许多答案。将您发现的相关关键字添加到搜索中。如果您没有找到答案,请发布,使用一个变体搜索您的标题和关键字作为您的标签。 PS 几乎总是最简单和最直接的设计是从没有 NULL 开始的。您始终可以通过左连接到新的基表来使用 NULL。
-
@philipxy 我的问题与继承无关。我仔细 google 寻找关于这种关系的最佳实践,但找不到答案。顺便说一句,谢谢你的建议。我会尽量解释清楚。
-
请给minimal reproducible example。您的 if-elseif 没有意义,因为如果 IRI 没有 netOpId 则它没有 cellId+netOpId 所以 elseif 永远不会满足。 “有”和“+”似乎隐藏了一些语言。例如,您在评论中说“如果它只是 有一个操作...”。同样,“总是绑定到”也不清楚,它只是您立即尝试给出结果的模糊事物。 (我猜这应该是一个定义?但你开始“so”而不是“ie”。) PS FK 默认 MATCH SIMPLE 的工作方式,满足具有 NULL 的 FK。所以你可以有 FKs (netid), (cellid) & (netid, cellid)。
-
子类型是这里的一个问题。 IRI 可以“拥有”事物的 type 事物有两种 types。 Here's another link。我同意这可能不是这里唯一的设计问题。
标签: oracle foreign-keys rdbms