2009-02-16 5 views
4

La performance est la clé: est-il préférable de mettre en cascade les suppressions/mises à jour dans la base de données ou de laisser Hibernate/JPA s'en charger?Cascades de suppressions/mises à jour en utilisant JPA ou à l'intérieur de la base de données?

Est-ce que cela affectera la capacité à interroger les données si des cascades sont à l'intérieur du SGBD? J'utilise HSQLDB si cela est important.

+0

Je rencontre à peu près le même problème. Jusqu'à présent, il semble que personne ne peut vraiment dire quelle est la corrélation entre les cascades JPA/DB en termes de performance. –

Répondre

2

Dans le cas de mises à jour en cascade, vous ne pouvez simplement pas le faire dans l'espace application si vous avez des contraintes de clé étrangère dans la base de données. Exemple: disons que vous avez une table de recherche pour les états américains, avec une clé primaire de l'abréviation à deux lettres. Ensuite, vous avez une table pour les adresses postales qui le référence. Quelqu'un vous dit que vous avez donné par erreur à Montana l'abréviation "MO" au lieu de "MT". Vous devez donc le changer dans la table de recherche.

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'); 

Maintenant, vous allez corriger l'erreur, sans l'aide de mises à jour en cascade de la base de données. Voici un test utilisant MySQL 5.0 (supposons qu'il n'existe aucun enregistrement pour Missouri, qui utilise l'abréviation "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`)) 

Aucune requête côté application ne peut résoudre cette situation. Vous avez besoin de mises à jour en cascade dans la base de données pour effectuer la mise à jour dans les deux tables de manière atomique, avant que la contrainte d'intégrité référentielle ne soit appliquée.

+0

Vraiment? Que diriez-vous: 'INSÉRER DANS les États VALEURS ('MT', 'Montana'); UPDATE Adresses SET st = 'MT' O WH ST = 'MO'; SUPPRIMER des états où st = 'MO''. Vous pouvez argumenter que ce n'est pas aussi efficace que fait par RDBMS (ce qui est vrai), mais prétendre que ce n'est pas possible dans l'espace d'application est tout simplement faux. –

+0

@JacekPrucia, la question portait sur les mises à jour en cascade. Bien sûr, vous pouvez le faire manuellement en plusieurs étapes, et vous pouvez utiliser une transaction pour rendre le changement multi-étapes atomique. Mais l'avantage d'utiliser les mises à jour en cascade est qu'il trouve automatiquement les 37 autres tables qui référencent 'States' et les met à jour aussi. Ce serait embarrassant si vous le faites dans plusieurs instructions comme vous le montrez, et si vous ajoutez une 38e table, vous devrez modifier votre code. Alors que les mises à jour en cascade le feraient implicitement. –

0
  1. Correctness est la clé

Cela dit dans cette correction d'instance et la performance ira presque certainement la main dans la main depuis la base de données est le bon endroit pour mettre (et appliquer) des contraintes dures sur l'intégrité des données et sera plus rapide sur une mesurablement cascade grave suppression puisqu'il:

  • Evite multiples allers-retours à la base de données
  • Réduit le temps au cours de laquelle une transaction peut avoir qui se tiendra
  • Peut utiliser des structures internes liées à l'index de clé étrangère pour le faire sans avoir à entraînement/réutiliser un plan d'exécution
0

MISE À JOUR: ressemble question similaire était déjà répondu ici When/Why to use Cascading in SQL Server?

IMO la réponse correcte à votre question sera comme d'habitude "ça dépend". Si vous utilisez une base de données comme stockage d'informations sensibles (financières, médicales, etc.) ou si quelqu'un d'autre en dehors de votre application peut avoir accès à la base de données, je voterai pour l'approche Hibernate/JPA. Si votre base de données est destinée à la journalisation (par exemple, le trafic sur un site Web, etc.) ou si vous développez un logiciel avec une base de données intégrée, vous pouvez relativement utiliser en toute sécurité les opérations en cascade.

2. Dans la plupart des cas, je voterai pour l'approche Hibernate/JPA car elle est plus gérable et prévisible.

Je vous raconte une histoire. Il y a quelques temps, le jeune pays a décidé de changer la monnaie nationale (cela s'est passé avec les pays jeunes). Quelques années plus tard, le nouveau DBA a vu dans une rangée de la table de monnaie avec la devise obsolète et a décidé de le supprimer (qui sait pourquoi). Devinez ce qui est arrivé? 30% de la base de données a été supprimée à cause des opérations de suppression en cascade. OMI avec des opérations en cascade vous devez être très prudent avec toutes les instructions de suppression/mise à jour d'une part et vous perdez la puissance des contraintes (c'est-à-dire les clés étrangères) pour la validation de la base de données d'autre part.

+2

Je signale simplement que les changements de monnaie nationale sont susceptibles de se produire beaucoup de temps dans les années à venir, et pas seulement pour les jeunes pays, il suffit de penser à la zone euro. – snowflake

+0

La "suppression d'une ligne, perte de 30% de la base de données" n'est pas un argument contre la mise en cas de SGBDR, mais plutôt la preuve que cet administrateur n'est pas familliar avec sa structure de base de données. Vous avez également manqué l'aspect principal de la question - «La performance est la clé» car rien dans votre réponse ne se rapporte à cela. Résiste à la tentation de downvote si :) –

Questions connexes