代码之家  ›  专栏  ›  技术社区  ›  Adarsh Madrecha

如何更新链接到多个表的FK-更新时级联

  •  0
  • Adarsh Madrecha  · 技术社区  · 5 年前

    我有三张相互连接的桌子

    1. 任务
    2. 客户

    关系如下图所示 relationship

    compliance 表的外键如下所示 compliance table

    这个 task 表的外键如下所示 task table

    问题: 当我编辑/更新 clientno client 桌子,我明白了

    1452: Cannot add or update a child row: a foreign key constraint fails
    (`task`, CONSTRAINT `task_ibfk_1` FOREIGN KEY (`officeid`, `clientid`) REFERENCES `client` (`officeid`, `clientno`) ON UPDATE CASCADE)
    

    客户编号 已在中更改 客户 表,两个表中的内容都将更新 complaince 任务 桌子。

    客户编号

    编辑1:

    编辑2:

    create table client
    (
      officeid     char(6)                 not null,
      clientno     char(10)                not null,
      fname        varchar(40)             not null,
      primary key (officeid, clientno)
    );
    
    create index officeid_clientno
      on client (officeid, clientno);
    
    
    create table compliance
    (
      officeid    char(6)                   not null,
      id          smallint(5) unsigned      not null,
      clientid    char(10)                  not null,
      primary key (officeid, id),
      constraint compliance_ibfk_2
      foreign key (officeid, clientid) references client (officeid, clientno)
        on update cascade
        on delete cascade
    );
    
    create index officeid_clientid
      on compliance (officeid, clientid, id);
    
    
    create table task
    (
      officeid        char(6)                      not null,
      taskno          char(10)                     not null,
      clientid        char(10)                     not null,
      taskname        varchar(50)                  not null,
      complianceid    smallint(5) unsigned         null,
      primary key (officeid, taskno),
      constraint task_ibfk_1
      foreign key (officeid, clientid) references client (officeid, clientno)
        on update cascade,
      constraint task_ibfk_4
      foreign key (officeid, clientid, complianceid) references compliance (officeid, clientid, id)
        on update cascade
    );
    
    create index officeid_clientid_complianceid
      on task (officeid, clientid, complianceid);
    

    2 回复  |  直到 5 年前
        1
  •  3
  •   GMB    5 年前

    问题与关系的声明方式有关。

    首先,正如@Nick所评论的,没有必要在 task client ,因为这已经包含在 compliance . 注释这个多余约束的声明就足以使错误消失,如中所示 this db fiddle

    create table task
    (
      officeid        char(6)                      not null,
      ...
      primary key (officeid, taskno),
      -- constraint task_ibfk_1
       -- foreign key (officeid, clientid) references client (officeid, clientno)
       -- on update cascade,
      constraint task_ibfk_4
      foreign key (officeid, clientid, complianceid) references compliance (officeid,     clientid, id)
        on update cascade
    ); 
    

    另一个建议是在所有表中使用自动递增的主键(可以使用 UNIQUE 索引以强制复合引用完整性规则)。这是处理MySQL最常用的方法,处理关系非常困难。

        2
  •  0
  •   Arth    5 年前

    您可以通过使用代理不可变主键并向可变字段添加唯一键来减轻这种情况。您应该能够在不影响数据完整性的情况下应用与以前相同的约束

    例如:

    CREATE TABLE client (
      id INT(10) UNSIGNED NOT NULL AUTO-INCREMENT PRIMARY,
      officeid CHAR(6) NOT NULL,
      clientno CHAR(10) NOT NULL,
      fname VARCHAR(40) NOT NULL
    );
    
    CREATE UNIQUE INDEX uq-client-officeid-clientno IN client (officeid, clientno);
    
    CREATE TABLE compliance (
      id SMALLINT(5) UNSIGNED NOT NULL AUTO-INCREMENT PRIMARY,
      client_id INT(10) UNSIGNED NOT NULL,
      CONSTRAINT fk-compliance-client-id FOREIGN KEY id 
        REFERENCES client (id)
    );
    
    CREATE INDEX ix-compliance-id-client_id IN compliance (id, client_id);
    
    CREATE TABLE task (
      id INT(10) UNSIGNED NOT NULL AUTO-INCREMENT PRIMARY,
      client_id INT(10) UNSIGNED NOT NULL,
      compliance_id SMALLINT(5) UNSIGNED NULL,
      taskno CHAR(10) NOT NULL,
      taskname VARCHAR(50) NOT NULL,
      CONSTRAINT fk-task-client-id FOREIGN KEY id 
        REFERENCES client (id),
      CONSTRAINT fk-task-compliance-id-client_id FOREIGN KEY (compliance_id, client_id) 
        REFERENCES compliance (id, client_id)
    );
    

    clientno 不需要瀑布

    外键 fk-task-compliance-id-client_id 确保任务引用的符合性包含正确的 client_id

    officeid . 然后可以由客户机表引用