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

时间:2009-02-16 22:02:12

标签: sql hibernate jpa hsqldb cascade

性能是关键:在数据库中级联删除/更新或让Hibernate / JPA处理它是否更好?

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

如果重要的话,我正在使用HSQLDB。

3 个答案:

答案 0 :(得分:2)

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

示例:假设您有一个美国州的查找表,主键是两个字母的缩写。然后你有一个表引用它的邮件地址表。有人告诉你,你错误地给了蒙大拿缩写“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');

现在你去修复错误,没有数据库端级联更新的帮助。下面是使用MySQL 5.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`))

没有应用程序端查询可以解决这种情况。您需要在数据库中进行级联更新,以便在强制执行参照完整性约束之前以原子方式在两个表中执行更新。

答案 1 :(得分:0)

  1. 正确是关键
  2. 在这种情况下说的正确性和性能几乎肯定是齐头并进的,因为数据库是对数据完整性施加(并强制执行)硬约束的正确位置,并且在严重的删除级联上它会明显更快,因为它:

    • 避免多次往返数据库
    • 减少交易可能需要的时间
    • 可以利用与外键索引相关的内部结构来执行此操作而无需锻炼/重用某些执行计划

答案 2 :(得分:0)

更新:看起来类似问题已在此处得到解答When/Why to use Cascading in SQL Server?

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

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

我告诉你一个故事。不久之前,年轻的国家决定改变国家货币(它发生在年轻国家)。几年后,新的DBA在货币表行中看到了过时的货币并决定删除它(谁知道原因)。猜猜发生了什么?由于级联删除操作,删除了30%的数据库。使用级联操作的IMO,您必须非常小心地从一只手中删除/更新所有语句,并且您从另一只手中失去了约束力(即外键)以进行数据库验证。