Вопрос: Каскадные удаления / обновления с использованием JPA или внутри базы данных?


Важна производительность. Лучше ли каскадировать удаление / обновление внутри базы данных или позволить Hibernate / JPA позаботиться об этом?

Поможет ли это возможность запрашивать данные, если каскады находятся внутри СУБД?

Я использую HSQLDB, если это имеет значение.


4


источник


Ответы:


В случае каскадных обновлений вы просто не можете сделать это в пространстве приложения, если у вас есть ограничения внешнего ключа в базе данных.

Пример: скажем, что у вас есть таблица поиска для штатов США с первичным ключом двухбуквенной аббревиатуры. Затем у вас есть таблица для почтовых адресов, которая ссылается на нее. Кто-то говорит вам, что вы ошибочно дали Монтане аббревиатуру «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`))

Никакой запрос на стороне приложения не может решить эту ситуацию. Вам необходимо использовать каскадные обновления в базе данных, чтобы выполнить обновление в обеих таблицах атомарно, до того, как принудительное ограничение ссылочной целостности будет принудительно выполнено.


2



  1. Правильность

При этом в этом случае правильность и производительность почти наверняка будут идти рука об руку, поскольку база данных является правильным местом для установки (и обеспечения) жестких ограничений целостности данных, и она будет значительно быстрее на серьезном каскаде удаления, поскольку она:

  • Избегает многократных обращений к базе данных
  • Сокращает время, в течение которого может потребоваться сделка
  • Может использовать внутренние структуры, связанные с индексом внешнего ключа, чтобы сделать это без необходимости тренировки / повторного использования некоторого плана выполнения

0



ОБНОВИТЬ:  похоже, что подобный вопрос уже был дан здесь Когда / Зачем использовать Cascading в SQL Server?

IMO правильный ответ на ваш вопрос  будет как обычно "это зависит" , Если вы используете базу данных в качестве хранилища конфиденциальной информации (например, финансовой, медицинской и т. Д.), Или если у кого-то, кроме вашего приложения, может быть доступ к базе данных, я буду голосовать за подход Hibernate / JPA. Если ваша база данных предназначена для ведения журнала (например, трафик веб-сайта и т. Д.), Или если вы разрабатываете программное обеспечение со встроенной базой данных, вы можете относительно безопасно использовать каскадные операции.

2. В большинстве случаев я буду голосовать за подход Hibernate / JPA, потому что он более управляемый и предсказуемый.  

Я рассказываю вам историю. Несколько раз назад молодая страна решила изменить национальную валюту (это случилось с молодыми странами). Через пару лет новый администратор баз данных увидел в строке таблицы валют устаревшую валюту и решил удалить ее (кто знает, почему). Угадайте, что случилось? 30% базы данных было удалено из-за операций удаления каскадов. IMO с каскадными операциями вы должны быть очень осторожны с тем, что вы удаляете или обновляете операторы с одной стороны, и теряете силу ограничений (например, внешние ключи) для проверки базы данных с другой стороны.


0