PostgreSQL: незмінний, летючий, стабільний


11

Мені незрозуміло справжнє значення у визначеннях функцій IMMUTABLE, VOLATILE та STABLE.

Я читав документацію, конкретно визначення кожної.

IMMUTABLE вказує на те, що функція не може змінювати базу даних і завжди повертає той самий результат, коли даються однакові значення аргументу ; тобто він не здійснює пошук баз даних або іншим чином використовує інформацію, яка безпосередньо не присутня в його списку аргументів. Якщо ця опція задана, будь-який виклик функції з незмінними аргументами можна негайно замінити значенням функції.

STABLE вказує на те, що функція не може змінювати базу даних, і що в межах однієї сканування таблиці вона послідовно повертає той самий результат для одних і тих же значень аргументу , але що його результат може змінюватися в операторах SQL. Це відповідний вибір для функцій, результати яких залежать від пошуку в базі даних, змінних параметрів (таких як поточний часовий пояс) тощо (недоцільно для ПІСЛЯ тригерів, які бажають запитувати рядки, змінені поточною командою.) Також зауважте, що Сімейство функцій current_timestamp кваліфікується як стабільне, оскільки їх значення не змінюються в межах транзакції.

VOLATILE вказує на те, що значення функції може змінюватися навіть у межах одного сканування таблиці, тому оптимізації не можна проводити. Відносно мало функцій бази даних є мінливими в цьому сенсі; деякі приклади - випадкові (), currval (), timeofday (). Але зауважте, що будь-яку функцію, яка має побічні ефекти, слід класифікувати нестабільною, навіть якщо її результат є досить передбачуваним, щоб запобігти оптимізації викликів; приклад - setval ().

Моя плутанина виникає з умовою для НЕМАТИЧНОГО та СТАБІЛЬНОГО, що функція ЗАВЖДИ чи ПОСЛІДНО повертає той самий результат, даючи ті самі аргументи.

Визначення IMMUTABLE зазначає, що функція не здійснює пошуку в базі даних або іншим чином використовує інформацію, яка безпосередньо не присутня в її списку аргументів. Отже, для мене це означає, що такі функції використовуються для маніпулювання даними, що надаються клієнтом, і не повинні мати операторів SELECT ... хоча це просто звучить для мене трохи дивно.

Щодо STABLE, визначення є аналогічним тим, що воно говорить, що воно повинно послідовно повертати той самий результат. Отже, для мене це означає, що кожен раз, коли функція викликається одними і тими ж аргументами, вона повинна повертати однакові результати (однакові точні рядки, кожен раз).

Отже, для мене ... це означає, що будь-яка функція, яка виконує SELECT на таблиці або таблицях, які можна оновити, повинна бути лише мінливою.

Але, знову ж таки ... це не здається мені правильним.

Повертаючи це до свого використання, я записую функції, які виконують оператори SELECT з кількома JOIN на таблицях, до яких постійно додаються, тому очікується, що виклики функцій будуть повертати різні результати кожного разу, коли вона викликається, навіть при однакових аргументах .

Отже, чи означає це, що мої функції повинні бути ВОЛОТИЛЬНИМ? Навіть незважаючи на те, що документація вказує на відносно мало функцій бази даних в цьому сенсі є мінливими ?

Дякую!

Відповіді:


15

IMMUTABLEповинна бути чистою функцією, результати якої залежать лише від її входів. Це дуже сувора вимога; вони не можуть викликати інші незмінні функції, вони не можуть отримати доступ до таблиць, вони не можуть отримати доступ до значення властивостей конфігурації тощо.

STABLEможе використовувати будь-які самі входи STABLE: інші STABLEабо IMMUTABLEфункції та SELECTзапити таблиць. Запитувати таблиці можна безпечно, оскільки представлення функцій цих таблиць не зміниться в поточному знімку запиту. Ви можете отримати доступ до значень GUC ( current_setting(...)), якщо ви знаєте, що вони також не будуть призначені в поточному операторі.

VOLATILE функції - це все, що не відповідає перерахованому:

  • Все, що має побічні ефекти
  • Все, що робить, пише
  • Все, що запитує зовнішні дані, якими не керує знімок PostgreSQL
  • ...

Загалом, просто залиште все, VOLATILEякщо у вас немає вагомих причин цього не зробити.

Основна причина використання IMMUTABLE- це при написанні функцій, які повинні використовуватися як частина виражень індексу.


1
"вони не мають доступу до таблиць." Чесно кажучи, вони можуть і робити. Я думаю, що більш загальне правило полягає в тому, що таблиці не повинні змістовно мутувати без перезавантаження бази даних.
Еван Керролл

Якщо STABLE дозволяє доступ до таблиці, чи є оптимізації над / над VOLATILE ...?
Брукс

Не пам’ятаю, що в моїй голові, доведеться перевіряти документи / код.
Крейг Рінгер

4

Для STABLE частина, яку потрібно виділити жирним шрифтом, полягає в тому, що "результат може змінюватися через SQL заяви"

Незмінні речі не повинні змінюватися ніколи. Навіть якщо ви перезавантажте ваш сервер бази даних, запустіть yum update(але, звичайно, можуть бути помилки!), Змінити конфігурацію (як datestyle, timezone, default_text_search_config, extra_float_digitsі т.д.), або замінити серверне обладнання повністю (з тієї ж архітектури, що і старе обладнання, так бінарні файли все ще сумісні).

Функції, які ви описуєте, звучать як такі: СТАБІЛЬНІ, тому що в одному операторі SQL вони будуть виконувати свої запити, використовуючи той самий знімок, що і зовнішній запит, і тому будь-які паралельні зміни, внесені до цих інших таблиць, не були б видні. Тепер, якщо ваші функції відкрили нове підключення до сервера і запустили їх запити в рамках цього незалежного з'єднання, це зробило б функцію мінливою, оскільки вони використовували різні знімки.


Я вважаю, що я розумію передумови для НЕМАТИЧНОГО (нічого не може змінитися .... ніколи, між запитами, з'єднаннями, перезавантаженнями, планетарним руйнуванням та реконструкцією, НАДІЛЬКО, якщо база даних буде змінена) та ВОЛОТИЛЬНО (функція стрибає поза контексту в що його називали). Це правильно? Отже, тоді, здається, STABLE просто означає, що функція не змінює базу даних і не має доступу до бази даних поза її контекстом? Визначення STABLE відчуває, що це ШЛЯХО складніше, ніж це насправді повинно бути ... Або я щось залишаю?
Брукс

PostgreSQL насправді має деякі проблеми IMMUTABLEта порівняння. Він сподівається, що glibc(або, в нових версіях Pg, iconv) не буде змінювати визначення зіставлення. Насправді вони так і не дають можливості виявити такі зміни. Це може призвести до мовчазної корупції індексу :(. Це здебільшого проблема при реплікації між різними версіями ОС тощо.
Крейг Рінгер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.