6 сентября 2014 г. · 2 минуты чтения

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

Вопрос

Предположим, у нас есть две таблицы:

  1. таблица контактов, имеющая столбцы: идентификатор и имя
  2. таблица разговоров со столбцами: id и contact_id (от FK к contact.id)

Следующие два запроса возвращают одни и те же данные:

точечная запись (довольно типичная):

SELECT contacts.name, contacts.id, conversations.id
FROM contacts
INNER JOIN conversations
ON contacts.id = conversations.contact_id;

и

функциональная нотация (довольно нетипичная):

SELECT contacts.name, contacts.id, conversations.id
FROM contacts
INNER JOIN conversations
ON id(contacts) = contact_id(conversations);

Этот второй подход вызвал некоторые вопросы:

  • Почему и как работает второй подход?
  • Этот синтаксис в стандарте SQL или только в PostgreSQL?
  • Это производительно? Если да, то почему он не используется более широко?

Я задал эти вопросы на StackOverflow и подытожу свои выводы здесь.

Почему и как?

Во-первых, это работает. Этот момент интересен сам по себе. Следующая идея, которую стоит обдумать, состоит в том, что при использовании функциональной нотации имена столбцов (id и contact_id в приведенном выше примере) рассматриваются как функции. Почему есть смысл в том, что мы можем использовать имена столбцов как функции?

Мы можем думать о функциях как об операции (или запросе), которая при заданном вводе X гарантированно возвращает Y (при условии, что базовые данные не изменились). Подумайте о СУММЕ(). Добавление 1 плюс 2 всегда равно 3. То же самое и со столбцами (опять же при условии постоянных данных). Если я запрошу все разговоры с contact_id равным 1, я всегда буду получать один и тот же набор записей. Бам, столбцы — это функции. Ознакомьтесь с этой статьей из документации для примера того, как написать пользовательскую функцию.

Этот синтаксис в стандарте SQL или только в PostgreSQL?

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

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

Подведение итогов

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

Первоначально опубликовано на сайте blog.simontaranto.com 6 сентября 2014 г.