代码之家  ›  专栏  ›  技术社区  ›  mainstringargs

使用JPA或数据库内部进行级联删除/更新?

  •  4
  • mainstringargs  · 技术社区  · 15 年前

    性能是关键:是在数据库内部级联删除/更新,还是让hibernate/jpa来处理它?

    如果级联在DBMS中,这会影响查询数据的能力吗?

    如果这很重要的话,我正在使用hsqldb。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Bill Karwin    15 年前

    在级联更新的情况下,如果数据库中有外键约束,则无法在应用程序空间中执行此操作。

    例如:假设您有一个美国各州的查找表,其主键是两个字母的缩写。然后,您有一个引用它的邮寄地址表。有人告诉您,您错误地将缩写“mo”而不是“mt”给了蒙大拿,因此您需要在查阅表格中更改它。

    CREATE TABLE States (st CHAR(2) PRIMARY KEY, state VARCHAR(20) NOT NULL);
    INSERT INTO States VALUES ('MO', 'Montana');
    
    CREATE TABLE Addresses (addr VARCHAR(20), city VARCHAR(20), st CHAR(2), zip CHAR(6),
      FOREIGN KEY (st) REFERENCES States(st));
    INSERT INTO Addresses VALUES ('1301 East Sixth Ave.', 'Helena', 'MO', '59620');
    

    现在,您可以在不借助数据库端级联更新的情况下修复错误。下面是一个使用MySQL5.0的测试(假设密苏里州没有记录,实际上使用缩写“mo”)。

    UPDATE States SET st = 'MT' WHERE st = 'MO';
    
    ERROR 1451 (23000): Cannot delete or update a parent row: 
     a foreign key constraint fails (`test/addresses`, 
     CONSTRAINT `addresses_ibfk_1` FOREIGN KEY (`st`) REFERENCES `states` (`st`))
    
    UPDATE Addresses SET st = 'MT' WHERE st = 'MO';
    
    ERROR 1452 (23000): Cannot add or update a child row: 
     a foreign key constraint fails (`test/addresses`, 
     CONSTRAINT `addresses_ibfk_1` FOREIGN KEY (`st`) REFERENCES `states` (`st`))
    
    UPDATE Addresses JOIN States USING (st)
    SET Addresses.st = 'MT', States.st = 'MT'
    WHERE States.st = 'MO';
    
    ERROR 1451 (23000): Cannot delete or update a parent row: 
     a foreign key constraint fails (`test/addresses`, 
     CONSTRAINT `addresses_ibfk_1` FOREIGN KEY (`st`) REFERENCES `states` (`st`))
    

    没有应用程序端查询可以解决这种情况。在执行引用完整性约束之前,需要在数据库中进行级联更新,以便在两个表中自动执行更新。

        2
  •  0
  •   ShuggyCoUk    15 年前
    1. 正确性是关键

    也就是说,在这种情况下,正确性和性能几乎肯定是齐头并进的,因为数据库是对数据完整性施加(和实施)硬约束的正确位置,而且在严重的删除级联上,它会更快,因为它:

    • 避免多次往返数据库
    • 缩短交易可能必须进行的时间
    • 可以使用与外键索引相关的内部结构来执行,而无需制定/重用某些执行计划。
        3
  •  0
  •   Community kgiannakakis    7 年前

    更新: 看起来类似的问题已经在这里回答了 When/Why to use Cascading in SQL Server?

    依我所见 关于你的问题的正确答案 会像往常一样 “这取决于” . 如果您使用数据库存储敏感信息(如财务、医疗等),或者如果应用程序以外的其他人可以访问数据库,我将投票支持Hibernate/JPA方法。如果您的数据库用于日志记录(例如网站流量等),或者您正在使用嵌入式数据库开发软件,则可以相对安全地使用级联操作。

    2.第2条。在大多数情况下,我会投票支持Hibernate/JPA方法,因为它更易于管理和预测。

    我给你讲个故事。一些时候以前,年轻的国家决定改变本国货币(这发生在年轻的国家)。几年后,新的DBA在货币表行中看到了过时的货币,并决定删除它(谁知道为什么)。猜猜怎么回事?由于级联删除操作,30%的数据库被删除。在使用级联操作时,一方面必须非常小心地删除/更新所有语句,另一方面也会失去用于数据库验证的约束(即外键)的能力。