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

StackOverflow https://stackoverflow.com/questions/554750

Вопрос

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

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

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

Это было полезно?

Решение

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

Пример:Допустим, у вас есть таблица поиска штатов США с первичным ключом, состоящим из двухбуквенной аббревиатуры.Затем у вас есть таблица почтовых адресов, которая ссылается на нее.Кто-то говорит вам, что вы по ошибке дали Монтане аббревиатуру «МО» вместо «МТ», поэтому вам нужно изменить ее в справочной таблице.

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 (предположим, что для штата Миссури нет записей, где на самом деле используется аббревиатура «МО»).

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. Корректность – это ключ к успеху

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top