我有3张桌子:
GetData
S; NETWORK_OPERATOR
s:每个属于一个NETWORK_CELL
; NETWORK_OPERATOR
s:每个人都可以 :
但1)和2)中的一个是强制性的。
如果1)IRI
必须存在于netOpId
表中;
如果是2)NETWORK_OPERATOR
+ cellId
必须存在于netOpId
表中;
以下是DDL代码示例:
CELL
换句话说,
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
,因此 IF a NETWORK_OPERATOR
的{{1}}应该强制为IRI
现有netOpId
, ELSE IF ,netOpId
有IRI
+ cellId
,应强制其为现有netOpId
+ cellId
我看到两个选项:
选项1:
仅使netOpId
能够并添加复合FK
IRI.NETOPID NOT NULL
)
(当然 CREATE TABLE "IRI" (
...
"NETOPID" INTEGER NOT NULL,
"CELLID" INTEGER,
...
CONSTRAINT "IRI_CELL_FK" FOREIGN KEY ("CELLID", "NETOPID") REFERENCES "NETWORK_CELL" ("CELLID", "NETOPID")
上有一个唯一键)
换句话说,IRI将与网络运营商建立强制性的FK关系,并与网络单元建立可选的FK关系。
“可疑”的事情是,这个“可选的”FK由IRI方面的必填字段和可选字段组成。
Oracle RDBMS接受了这个(我刚试过),但这是一个好习惯吗?
选项2:
与选项1中的FK相同,但保留"NETWORK_CELL" ("CELLID", "NETOPID")
可空,并添加一个自定义约束,强制执行 IRI.NETOPID
或 {{1 }} + netOpId
我觉得这个解决方案更便携,但也许我错了。
问题
有更好的选择吗?
处理这种情况的最佳做法是什么?为什么? 我也在考虑其他RDBMS的可移植性......
谢谢
答案 0 :(得分:2)
您的选项1没问题。默认FK(外键)声明模式MATCH SIMPLE(通常是唯一实现的)工作方式,带有任何NULL的FK子行值满足其约束。所以你可以拥有IRI FK(netid)& (netid,cellid) - 加上netid NOT NULL。 (您似乎已经忘记了第一个IRI中的NOT NULL,但不是第二个。)
然后列对的唯一情况是(非null,null)& (非null,非null)。必须存在一个netid;一个非null的cellid必须与那个netid&一个NULL cellid就可以了。
答案 1 :(得分:0)
根据我的理解,一个解决方案可能是这个:
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),
CONSTRAINT IRI_CELLS_FK FOREIGN KEY (CELLID) REFERENCES NETWORK_CELL (CELLID),
CONSTRAINT IRI_CELL_OR_NETOP CHECK ( NVL(NETOPID, CELLID) IS NOT NULL )
)
如果您希望强制只设置值,则可以使用
CHECK ( NVL(NETOPID, CELLID) IS NOT NULL AND NOT (NETOPID IS NOT NULL AND CELLID IS NOT NULL) )
或
CHECK ( NVL(NETOPID, CELLID) IS NOT NULL AND NETOPID||CELLID IN (NETOPID, CELLID) )
或
CHECK ( (NETOPID IS NULL AND CELLID IS NOT NULL) OR (NETOPID IS NOT NULL AND CELLID IS NULL) )