Je ne suis pas clair sur le vrai sens dans les définitions des fonctions IMMUTABLE, VOLATILE et STABLE.
J'ai lu la documentation, en particulier les définitions de chacun.
IMMUTABLE indique que la fonction ne peut pas modifier la base de données et renvoie toujours le même résultat lorsqu'elle reçoit les mêmes valeurs d'argument ; c'est-à-dire qu'il n'effectue pas de recherche dans la base de données ni n'utilise autrement les informations qui ne sont pas directement présentes dans sa liste d'arguments. Si cette option est donnée, tout appel de la fonction avec des arguments tous constants peut être immédiatement remplacé par la valeur de la fonction.
STABLE indique que la fonction ne peut pas modifier la base de données et que dans une seule analyse de table, elle retournera systématiquement le même résultat pour les mêmes valeurs d'argument , mais que son résultat pourrait changer dans les instructions SQL. Il s'agit de la sélection appropriée pour les fonctions dont les résultats dépendent des recherches dans la base de données, des variables de paramètres (telles que le fuseau horaire actuel), etc. (Cela ne convient pas aux déclencheurs AFTER qui souhaitent interroger des lignes modifiées par la commande actuelle.) Notez également que le La famille de fonctions current_timestamp est considérée comme stable, car leurs valeurs ne changent pas dans une transaction.
VOLATILE indique que la valeur de la fonction peut changer même au sein d'une seule analyse de table, donc aucune optimisation ne peut être effectuée. Relativement peu de fonctions de base de données sont volatiles dans ce sens; quelques exemples sont random (), currval (), timeofday (). Mais notez que toute fonction qui a des effets secondaires doit être classée comme volatile, même si son résultat est tout à fait prévisible, pour éviter que les appels ne soient optimisés; un exemple est setval ().
Ma confusion vient avec la condition pour IMMUTABLE et STABLE que la fonction renvoie TOUJOURS ou CONSTAMMENT le même résultat étant donné les mêmes arguments.
La définition IMMUTABLE indique que la fonction n'effectue pas de recherches dans la base de données ni n'utilise autrement les informations qui ne sont pas directement présentes dans sa liste d'arguments. Donc, pour moi, cela signifie que de telles fonctions sont utilisées pour manipuler les données fournies par le client, et ne devraient pas avoir d'instructions SELECT ... bien que cela me semble un peu étrange.
Avec STABLE, la définition est similaire en ce sens qu'elle indique qu'elle devrait toujours renvoyer le même résultat. Donc, pour moi, cela signifie que chaque fois que la fonction est appelée avec les mêmes arguments, elle devrait retourner les mêmes résultats (mêmes lignes exactes, à chaque fois).
Donc, pour moi ... cela signifie que toute fonction qui effectue un SELECT sur une table ou des tables qui peuvent être mises à jour, ne devrait être volatile.
Mais, encore une fois ... cela ne me semble pas juste.
Pour en revenir à mon cas d'utilisation, j'écris des fonctions qui exécutent des instructions SELECT avec plusieurs JOIN sur des tables qui sont constamment ajoutées, de sorte que les appels de fonction devraient renvoyer des résultats différents à chaque appel, même avec les mêmes arguments .
Alors, cela signifie-t-il que mes fonctions devraient être VOLATILES? Même si la documentation indique que relativement peu de fonctions de base de données sont volatiles dans ce sens ?
Je vous remercie!
la source
Pour STABLE, la partie que vous devez mettre en gras est «le résultat peut changer dans les instructions SQL»
Les choses IMMUTABLES ne sont jamais censées changer. Même si vous redémarrez votre serveur de base de données, exécutez
yum update
(mais bien sûr , il peut y avoir des bugs!), Changer votre configuration (commedatestyle
,timezone
,default_text_search_config
,extra_float_digits
, etc.), ou remplacer votre matériel de serveur entièrement (de la même architecture que l'ancien matériel, donc les fichiers binaires sont toujours compatibles).Les fonctions que vous décrivez semblent être STABLES, car dans une seule instruction SQL, elles exécuteront leurs requêtes en utilisant le même instantané que la requête externe, et donc toutes les modifications simultanées que vous avez apportées à ces autres tables ne seront pas visibles. Maintenant, si vos fonctions ouvraient une nouvelle connexion au serveur et exécutaient leurs requêtes dans cette connexion indépendante, cela rendrait la fonction volatile, car elles utiliseraient des instantanés différents.
la source
IMMUTABLE
et des classements. Il espère queglibc
(ou, dans la Pg plus récente, iconv) ne changera pas les définitions de classement. En réalité, ils le font et ne fournissent aucun moyen de détecter de tels changements. Cela peut conduire à une corruption d'index silencieuse :(. C'est principalement un problème lors de la réplication entre différentes versions de système d'exploitation, etc.