使用循环外键删除



我有两个相互引用的实体:一个引用defaultUrlPage实体和一个引用pageUrl实体。

这是循环的,所以一旦我添加了一个页面和一个相互引用的url,我就不能删除它们。

我可以看到两种方法来修复它,但我不确定"原则"的方法。

  1. 使其中一个关系仅为索引,而不是外键约束
  2. 删除时,关闭外键约束检查

我不知道怎么做这些…你知道吗??

谢谢!

这是Doctrine的设置方法。如前所述,您需要将至少一个外键设置为可空的。

还考虑将onDelete级联设置为SET NULL。这将使删除过程更加简单——您不必在删除记录之前将键更新为NULL。

你的模式。Yml看起来像这样:

Url:
  columns:
    page_id: { type: integer, notnull: true }
  relations:
    Page: { local: page_id, foreign: id }
Page:
  columns:
    default_url_id: { type: integer, notnull: false }  # ALLOWS NULL foreign key here
  relations:
    DefaultUrl: { class: Url, local: default_url_id, foreign: id, onDelete: SET NULL }

根据经验,在制作外键时,总是让一个外键定义为空或省略一个外键定义。

允许循环中断。

最简单的情况(SQL语法,但适用抽样原则):

CREATE TABLE Employee (
    EmployeeId INTEGER NOT NULL IDENTITY(1,1)
    ManagerId INTEGER NOT NULL
    --...
    PRIMARY KEY EmployeeId NONCLUSTERED
    FOREIGN KEY FK_Manager REFRENCES Employee(EmployeeId)
)

可以按如下方式断开循环:

CREATE TABLE Employee (
    EmployeeId INTEGER NOT NULL IDENTITY(1,1)
    ManagerId INTEGER NOT NULL
    --...
    PRIMARY KEY EmployeeId NONCLUSTERED
)

或如下:

CREATE TABLE Employee (
    EmployeeId INTEGER NOT NULL IDENTITY(1,1)
    ManagerId INTEGER NULL
    --...
    PRIMARY KEY EmployeeId NONCLUSTERED
    FOREIGN KEY FK_Manager REFRENCES Employee(EmployeeId)
)

在声明外键时,我更喜欢始终跟踪关系图并确保没有循环。我将省略最不危险的键,直到所有循环都被打破。这确保了所有表都可以批量导出,然后批量导入到另一个数据库。

编辑:我发现当你问一个书籍专家这个问题时,你得到的答案是在删除时关闭外键。这是错误的,原因有二。首先,正常的事务操作不应该改变模式定义。其次,代码的其余部分期望外键在那里,因此不在应用程序代码中处理它;然而,模式修改有一个坏习惯,即跨事务流血或锁定整个表。

最新更新