Каскадное удаление / обновление с использованием JPA или внутри базы данных? - PullRequest
4 голосов
/ 17 февраля 2009

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

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

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

Ответы [ 3 ]

2 голосов
/ 22 февраля 2009

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

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

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

0 голосов
/ 17 февраля 2009

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

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

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

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

0 голосов
/ 17 февраля 2009
  1. Корректность - это ключ

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

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