Pourquoi certains SGBD n'autorisent-ils pas la restauration de certaines instructions DDL?

21

Récemment, j'ai découvert que MySQL ne supporte pas la restauration de DDL comme "alter table" ... Étant habitué à PostgreSQL, cela m'a paru étrange, mais un de mes amis m'a dit que même Oracle ne le permettait pas .. Y a-t-il des raisons techniques de ne pas l'appuyer? S'agit-il simplement d'une fonctionnalité "inintéressante" pour eux?

Edit: vient de trouver cette comparaison . Il semble que de nombreux SGBD prennent en charge la DDL transactionnelle.

Joril
la source
3
MySQL n'autorise pas DDL dans une transaction. Avant d'exécuter les instructions DDL, il valide la transaction en cours (toutes les instructions DML en cours dans cette transaction!) Sans aucun avertissement.
Frank Heikens
Exactement, assez ennuyeux OMI :)
Joril
Je suis personnellement surpris que Postgres le permette - pouvez-vous même annuler un DROPou un RENAME?
Joe
1
Tant que vous ne supprimez pas la base de données entière, oui :) Voir le lien que je viens d'ajouter
Joril
Ainsi, seuls Oracle et MySQL n'autorisent pas les instructions DDL dans les transactions. Cette fonctionnalité permet vraiment des déploiements de schémas faciles.
Marian

Réponses:

19

La raison pour laquelle cela fonctionne dans PostgreSQL est que les catalogues système sont des tables régulières. Ainsi, la création d'une nouvelle fonction, par exemple, nécessite simplement l'insertion d'une ligne dans le pg_proctableau, la modification de la valeur par défaut d'une colonne nécessite simplement la mise à jour d'une ligne pg_attrdef, et ainsi de suite. Étant donné que les tables sont transactionnelles de toute façon, vous devrez presque faire tout votre possible pour ne pas le faire fonctionner de cette façon. (Beaucoup de détails d'implémentation douloureux omis ici. ;-))

Je suppose, sans connaître le code source, que d'autres moteurs de base de données utilisent des structures internes personnalisées pour représenter leurs informations de catalogue système. Et donc ils devraient faire des efforts supplémentaires, beaucoup d'efforts supplémentaires probablement, pour faire fonctionner DDL transactionnel, et ce n'est apparemment pas une priorité pour eux.

Le revers de la médaille est que c'est la raison pour laquelle les mises à niveau majeures de PostgreSQL sont si douloureuses. D'autres produits peuvent vraisemblablement concevoir leurs structures de métadonnées internes en tenant compte des changements et des mises à jour, et il n'y a donc aucun problème avec la mise à niveau vers une nouvelle version majeure. Dans PostgreSQL, il n'y a aucun moyen de changer une table de catalogue système pour ressembler soudainement à une version plus récente d'une table de catalogue système, du moins pas tout en gardant le système en ligne, car cela nécessiterait l'accès aux catalogues système. Urgh.

Peter Eisentraut
la source
1
Eh bien, je préférerais ma base de données dans un état cohérent tout le temps plutôt que la facilité de mise à niveau de la version de la base de données, mais je suppose que c'est une question d'opinion :) Merci pour votre explication!
Joril
Cela peut expliquer le problème pour certaines bases de données, mais les catalogues système sont des tables régulières sur Oracle.
Leigh Riffel
10

La plupart ne le font pas? Bummer.

J'utilise principalement SQL Server et c'est le cas. Je sais qu'Oracle ne le fait pas mais je pensais qu'Oracle pourrait être une aberration.

Dans SQL Server, je suis certain que vous pouvez exécuter plusieurs instructions DDL en une seule transaction, même si je pense également qu'il existe quelques restrictions (que j'ai toutes oubliées). Vous pouvez faire une création ou une modification ou une baisse de la plupart des choses et les faire reculer, si vous le souhaitez. Red-Gate SQL Compare (un outil que j'adore) en profite.

Le problème avec cela est que la portée de votre transaction devient assez intéressante ... Lorsque vous impliquez les catalogues système dans une transaction de mise à jour (DDL), vous courez le risque de prendre des verrous vraiment importants et vous pouvez bloquer l'accès aux catalogues système. Les utilisateurs ne peuvent pas faire grand-chose si leurs requêtes ne trouvent pas leurs tableaux dans les catalogues!

Dans l'ensemble, cependant, il est pratique de pouvoir inclure DDL dans une transaction multi-instructions.

Plus utilement, la commande SQL Server DDL TRUNCATE peut également être un élément d'une transaction à instructions multiples . Vous pouvez tronquer une table cible (très rapidement), la construire, puis faire un commit si vous aimez le résultat. Si quelque chose se passe mal, vous reculez et le tour est joué !, c'est comme si vous n'aviez jamais dérangé la table. L'espace journal est également minimisé. J'en profite assez souvent.

KillerDBA
la source
2
Voici une réponse qui montre un exemple de DDL lié aux transactions dans SQL Server. De plus, j'ai toujours pensé TRUNCATEqu'on ne pouvait pas revenir en arrière. J'avais tort.
Nick Chammas
5

Dans SQL Server, nous pouvons annuler les instructions DDL, il n'utilise pas la validation automatique à la fin de l'instruction. Dans d'autres SGBD, je ne sais pas, mais je me souviens que dans Oracle, on ne peut pas faire de même. Je crois que c'est spécifique à chaque SGBD, je ne sais pas ce que le standard SQL en dirait, mais je suis sûr qu'aucun producteur n'implémente 100% du standard.

Il y a une question similaire sur SO: est-il possible d'exécuter plusieurs instructions DDL dans une transaction (dans SQL Server)?

Marian
la source
5

Oracle a partagé l'analyse des requêtes, donc un SELECT * FROM table_a effectué par une session est (normalement) le même que celui d'une autre session. Cela casserait si une session pensait qu'il y avait dix colonnes dans le tableau et une autre pensait qu'il y en avait onze.

Gary
la source
Il est intéressant de noter que j'ai eu un problème similaire l'autre jour, l'application était censée être déployable à chaud, mais en changeant la structure de la table pour la nouvelle version, elle n'avait aucun moyen de recompiler JDBC PreparedStatements à part le redémarrer. , tellement pour ça!
Gaius
2
En passant, la version 11gR2 introduit le concept des éditions pour aider aux mises à jour à chaud. Les connexions existantes utilisent effectivement une édition (avec cinq colonnes). Vous démarrez une nouvelle édition, ajoutez une colonne et démarrez de nouvelles connexions en utilisant la nouvelle édition pour les nouvelles sessions. Une fois toutes les sessions en suspens terminées, l'ancienne édition est coupée et tout utilise la nouvelle édition. Pas de retour en arrière, mais vous ne mettez pas de nouvelle activité sur votre nouvelle édition jusqu'à ce que tout fonctionne.
Gary