Database design 删除数据库表中的外键引用

Database design 删除数据库表中的外键引用,database-design,foreign-keys,relational-database,foreign-key-relationship,database-table,Database Design,Foreign Keys,Relational Database,Foreign Key Relationship,Database Table,鉴于这个问题: 考虑一个表示“大于或等于”的关系geq, 也就是说,(x,y)E geq仅当yy的元组(z,w) (b) 删除z>x的元组(z,w) 这就是我试图解决它的方法:- 由于ub(上限)是外键,因此在元组(x,y)中,y是外键。 给定表geq本身上的外键(y)引用,geq中必须有一个元组(y,y') 现在,y>=x和y'>=y。因此,y'>=x 所以我没有使用(z,w),而是使用了(y,y') 那么,答案不应该是,一个w>x的元组(z,w)被删除了吗 (我正在尝试解一张旧的浇口纸)如果

鉴于这个问题:

考虑一个表示“大于或等于”的关系
geq
, 也就是说,(x,y)E geq仅当y
create table geq
( lb integer not null 
, ub integer not null
, primary key lb
, foreign key (ub) references geq on delete cascade )
如果元组(x,y)被删除,下列哪项是可能的

(a) 删除z>y的元组(z,w)
(b) 删除z>x的元组(z,w)

这就是我试图解决它的方法:-

由于ub(上限)是外键,因此在元组(x,y)中,y是外键。 给定表
geq
本身上的外键(y)引用,geq中必须有一个元组(y,y')

现在,y>=x和y'>=y。因此,y'>=x

所以我没有使用(z,w),而是使用了(y,y')

那么,答案不应该是,一个w>x的元组(z,w)被删除了吗

(我正在尝试解一张旧的浇口纸)

如果(x,y)∈
geq
当且仅当x>y。将这种关系称为“大于或等于”是一种用词不当的说法,其原因我将在下面进行讨论

外键是上界(
ub
)是正确的,这意味着x是外键,y是元组(x,y)中的主键。外键声明中的
on delete cascade
选项意味着每当删除记录时,引用已删除记录的所有子记录也将被删除

对于您的情况,如果删除tuple(x,y),则引用(x,y)的任何记录也将被删除

由于外键是ub,因此记录(z,w)是(x,y)的子项当且仅当:z=y

因此,为了使(x,y)的删除导致(z,w)的级联删除,必须满足以下条件:

x≥ y=z≥ w(这不太正确,我稍后会解释。)

因此,你的问题的答案是(a)和(b)都不可能是真的。此外,您的结论(不在所列选项中)也不正确,w必须是≤ x、 不是w>x

事实上,因为下限是主键,所以关系(a,a)不可能有子记录,因为这需要违反主键。因此,要使记录具有任何子记录,上界必须严格大于下界。这意味着上面的关系语句更合适:

x≥ y=z>w因为y≠ w


这意味着当一个元组(x,y)被删除时,你所能说的就是一个元组(z,w)可以被级联删除,使得z=y或z≤ x、

问题在于不可为空的外键,再加上“y 有两种方法可以为没有父节点的节点创建sentinel值:

  • 将链接指针设置为空
  • 将其设置为与id相同的值
代码示例:

CREATE TABLE geq_one
    ( id INTEGER NOT NULL PRIMARY KEY
    , parent_id INTEGER  NOT NULL REFERENCES geq_one(id) ON DELETE CASCADE
    , CONSTRAINT younger_than_parent_one CHECK (parent_id <= id)
    )
        ;
INSERT INTO geq_one(id,parent_id) VALUES
(1,1) -- sentinel
, (2,1)
, (3,1)
        ;

CREATE TABLE geq_two
    ( id INTEGER NOT NULL PRIMARY KEY
    , parent_id INTEGER  REFERENCES geq_two(id) ON DELETE CASCADE
    , CONSTRAINT younger_than_parent_two CHECK (parent_id < id)
    )
        ;
INSERT INTO geq_two(id,parent_id) VALUES
(1,NULL) -- sentinel
, (2,1)
, (3,1)
        ;

DELETE FROM geq_one WHERE id = 1;
SELECT * FROM geq_one;

DELETE FROM geq_two WHERE id = 1;
SELECT * FROM geq_two;
创建表geq\u one
(id整数不是空主键
,parent_id INTEGER NOT NULL引用删除级联上的geq_one(id)

,约束比父约束年轻一次检查(父约束id y(a,a)是必要的
若要拥有子记录,假设我们在
lb ub
处插入记录?由于这是一个自引用的不可为null的键,第一次插入必须是
(a,a)
引用回自身。后续插入必须采用
(b,a)
(b,b)的形式
@ChrisSaxon-也许我应该更清楚。不可能(a,a)有一个单独的子记录(a,a),因为这会违反PK。因为问题是关于级联删除,级联删除不会两次删除父记录,所以我不觉得(a,a)这个事实自我参照对这个问题很重要。