6 сентября 2014 г. · 2 минуты чтения
Во время недавнего копания кроличьей норы в PostgreSQL я открыл для себя концепцию нотации функциональных запросов, и она слегка поразила меня.
Вопрос
Предположим, у нас есть две таблицы:
- таблица контактов, имеющая столбцы: идентификатор и имя
- таблица разговоров со столбцами: 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 г.