Найти тему
Библиотека программиста

😮 SQL: от Тетриса до ИИ – неожиданные возможности языка баз данных

Рекурсивные общие табличные выражения (CTE) превратили SQL в полный по Тьюрингу язык. Разберемся, как энтузиасты создают на нем сложные алгоритмы – от визуализации фракталов до полноценных игр.

Этот материал взят из нашей еженедельной email-рассылки, посвященной бэкенду. Подпишитесь, чтобы быть в числе первых, кто получит дайджест.

📧 Подписаться

(function () { let link = document .getElementById ("e8a9edae-1e82-4589-aa15-2e335e3dd466-https://proglib.io/w/5af939e0-2"); if (! link) return; let href = link .getAttribute ("href"); if (! href) return; let prefix = link .dataset .prefix; let action = link .dataset .action; link .addEventListener ("click", function (e) { let data = new FormData (); data .append ("url", href); apiFetch (action, { method: "POST", body: data }) .then (function (res) {}) .catch (function (err) { console .error (err); }); }) })();

Долгое время SQL использовали лишь для запросов и изменения записей в базах данных – для полноценного программирования в привычном смысле слова он не подходил. Однако добавление рекурсивных общих табличных выражений (CTE) сделало SQL полным по Тьюрингу. Рекурсивные CTE состоят из двух частей:

  • Нерекурсивная часть (базовый случай) – создает начальные данные.
  • Рекурсивная часть – может выполняться много раз, каждый раз используя результат предыдущего шага.
   Пример генерации чисел от 1 до 5 с помощью СТЕ
Пример генерации чисел от 1 до 5 с помощью СТЕ

Благодаря CTE на SQL можно при желании реализовать любой алгоритм. Энтузиасты уже сделали:

  • Визуализацию множества Мандельброта с помощью ASCII-графики.
  • 3D-движок для рисования объемных фигур.
  • GPT на 500 строках SQL-кода. Подробная статья о реализации этого проекта опубликована здесь.
  • Трассировку лучей (это метод создания реалистичных изображений).
   Результат трассировки лучей на SQL
Результат трассировки лучей на SQL

Статья по теме

🐬🐘 PostgreSQL или MySQL: что лучше подойдет для вашего проекта

На прошлой неделе коллекция крутых SQL-проектов пополнилась еще одной интересной разработкой – версией «Тетриса».

   «Тетрис» на SQL
«Тетрис» на SQL

Эта реализация демонстрирует несколько нестандартных SQL-техник, о которых стоит знать, даже если вы используете SQL только по прямому назначению:

  • Игровой цикл. В основе игры – рекурсивное общее табличное выражение (CTE). Оно создает бесконечный цикл, который инициализирует состояние игры, обновляет его на основе ввода пользователя и отрисовывает игру. Цикл продолжается, пока игра не закончится.
  • Вывод игры. Поскольку SQL-запрос обычно возвращает результат только после завершения, для отображения игры в реальном времени используется команда RAISE NOTICE. Эта команда выводит информацию в стандартный вывод, позволяя отображать игровое поле и другую информацию в процессе игры.
  • Пользовательский ввод. Обработка пользовательского ввода реализована через отдельную таблицу в базе данных. Эта таблица служит коммуникационной шиной между игрой и пользователем. Пользователь добавляет команды в эту таблицу, а игра их считывает.
  • Решение проблемы изоляции данных. Чтобы игра могла видеть новые команды, добавленные в таблицу ввода во время выполнения запроса, используется расширение dblink. Оно позволяет создавать новое подключение к базе данных с новым снимком данных, что дает возможность считывать самые последние команды пользователя.
  • Предотвращение кэширования. Чтобы PostgreSQL не кэшировал результаты запроса к таблице ввода, к запросу добавляется уникальный идентификатор итерации. Это заставляет базу данных выполнять запрос заново на каждой итерации игрового цикла.

💻 Библиотека программиста

Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека программиста»

Для управления состоянием игры и обработки игровых событий используются подзапросы и агрегатные функции:

  • Подзапросы позволяют вычислить новое состояние игры после каждого хода, включая позицию фигуры, состояние поля, счет и т. д. К примеру, рекурсивный подзапрос используется для вычисления максимального количества линий, на которые может упасть текущая фигура.
  • Агрегации применяются для подсчета очищенных линий, выбора фигуры с наименьшим рангом, обновления счета и уровня игры. Например, BOOL_OR() применяется для определения, есть ли хотя бы одно столкновение между фигурой и занятыми клетками на поле.

***

Какой самый необычный проект на SQL вы встречали или реализовывали сами?

Тетрис
602 интересуются