17
0
0
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
Назад

Реляционные базы данных в книге «Двенадцать стульев»: как устроен архив Коробейникова

Время чтения 12 минут
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
17
0
0
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники

Меня зовут Екатерина Петрова, я автор медиа «вАЙТИ» и аналитик. Перечитывая свой любимый роман И. Ильфа и Е. Петрова «Двенадцать стульев», а именно сцену с архивариусом Коробейниковым, я вдруг поняла: его бумажный архив ордеров на имущество бывших дворян не что иное, как идеальный пример реляционной базы данных. Алфавитные указатели — это индексы, книги учета — таблицы с первичными ключами, ордера — настоящие транзакции.

Мне сразу захотелось пофантазировать, как бы выглядела СУБД Варфоломея Коробейникова спустя сто лет. Так и возникла идея этой статьи о структуре реляционных баз данных и базовых SQL-запросах. Начинающим знакомиться с базами данных будет полезно и интересно рассмотреть тему под таким углом. 

Стулья умершей тещи Кисы Воробьянинова будем искать через SELECT. Начнем!

Реляционные базы данных в книге «Двенадцать стульев»: как устроен архив Коробейникова

Бумажный прототип реляционной СУБД конфискованных стульев

В 1927 году архивариус Коробейников из романа «Двенадцать стульев» создал систему учета данных об имуществе, конфискованном у бывших дворян после революции. «Дивная канцелярия! Полная механизация — архив на дому!» — сказал бы Остап, увидев PostgreSQL. Давайте спроектируем эту систему в SQL и напишем ключевые DDL. 

Из отрывка видно, что у архивариуса есть:

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

Это напоминает реляционную базу данных с несколькими связанными таблицами.

Таблица 1 — Бывшие владельцы (owners)

Коробейников сортирует их по алфавиту — это первичный ключ + индекс:


```sql
CREATE TABLE owners (
    owner_id INT PRIMARY KEY,
    last_name VARCHAR(255) NOT NULL,
    first_name VARCHAR(255),
    patronymic VARCHAR (255),
    social_status VARCHAR(100)
);
 
-- Индекс для быстрого поиска по фамилиям:
CREATE INDEX idx_owners_last_name ON owners(last_name);
```

 

По правилам нормализации БД, а именно третьей нормальной формы, в записи не должно быть столбцов с неключевыми значениями, которые зависят от других неключевых значений. Поле `social_status` нарушает 3НФ. То есть по-хорошему данные о социальном статусе надо бы вынести в отдельную таблицу estates. 

Таблица 2 — Изъятые предметы (confiscated_items)

Пример записи:

«Рояль „Беккер“ №97 012, табурет к нему мягкий, бюро две штуки…»

```sql
CREATE TABLE confiscated_items (
    item_id INT PRIMARY KEY,
    owner_id INT REFERENCES owners(owner_id),
    item_name VARCHAR(255) NOT NULL,
    quantity INT,
    description TEXT,
    taken_at DATE,
);
```

 

Таблица 3 — Распределение (кому досталась мебель) (distribution)

«Шифоньер — в горвоенком, гардероб — в интернат „Жаворонок“…»

```sql
CREATE TABLE distribution (
    distribution_id INT PRIMARY KEY,
    item_id INT REFERENCES confiscated_items(item_id),
    recipient VARCHAR(255) NOT NULL,
    distribution_date DATE,
    warrant_number INT 
);
```

 

Для оптимизации можно добавить индекс для поиска по получателям:

```sql
CREATE INDEX idx_distribution_recipient ON distribution(recipient);
```

 

Таблица 4 — Ордера на конфискованную мебель (warrants)

«На корешках все адреса прописаны и собственноручная подпись получателя» 

```sql
CREATE TABLE warrants (
    warrant_id INT PRIMARY KEY,
    item_id INT REFERENCES confiscated_items(item_id),
    recipient_signature TEXT,
    issued_at DATE
)
```

 

ERD для базы данных 

Между таблицами работает связь «один ко многим», так как у одного владельца может храниться множество изъятых предметов. Например, у Воробьянинова было изъято 13 предметов. 

OWNERS → CONFISCATED_ITEMS (1:N)

Один изъятый предмет может быть распределен в несколько мест. Например, тот самый гостиный гарнитур со стульями распределен частями. Десять стульев Гамбса → музей мебельного мастерства, 1 стул → Грицацуеву.

CONFISCATED_ITEMS → DISTRIBUTION (1:N)

На каждый предмет может быть несколько ордеров (например, на разные части гарнитура).

CONFISCATED_ITEMS → WARRANTS (1:N)

SQL-запросы, которые cэкономили бы Остапу Бендеру время на поиск стульев 

Чтобы найти, «куда девали все сокровища убиенной тещи» бывшего предводителя дворянства Ипполита Матвеевича Воробьянинова, в БД можно сделать такой запрос: 


SELECT 
    o.last_name, 
    o.first_name,
    ci.item_name,
    ci.description,
    d.recipient,
    d.distribution_date
FROM owners o
JOIN confiscated_items ci ON o.owner_id = ci.owner_id
LEFT JOIN distribution d ON ci.item_id = d.item_id
WHERE o.last_name = 'Воробьянинов'

 

Чтобы найти те самые стулья, в которых запрятаны сокровища, сделаем такой запрос: 


SELECT 
    ci.item_name AS "Название предмета",
    ci.description AS "Описание",
    d.recipient AS "Текущее местонахождение",
    d.distribution_date AS "Дата распределения"
FROM 
    confiscated_items ci
LEFT JOIN  
    distribution d ON ci.item_id = d.item_id
WHERE 
    ci.owner_id = 48238 
    AND (
        ci.item_name LIKE '%стул%' 
        OR ci.item_name LIKE '%Стул%'
        OR ci.description LIKE '%стул%'
        OR ci.description LIKE '%Стул%'
    )

 

Чтобы проверить ордера на гостиный гарнитур тещи Воробьянинова, сделаем запрос: 


SELECT 
    w.warrant_id,
    ci.item_name,
    w.recipient_signature,
    w.address
FROM warrants w
JOIN confiscated_items ci ON w.item_id = ci.item_id
WHERE ci.owner_id = 48238 AND ci.item_name LIKE '%гарнитур%'

Вместо заключения: найдите стулья тещи Кисы Воробьянинова быстрее Остапа Бендера

Система архивариуса Варфоломея Коробейникова — это идеальный пример реляционной модели на бумаге, но с некоторыми ошибками с точки зрения DBA:

  • Нарушение 1НФ. В поле description хранятся списки конфискованного имущества («2 бюро, 4 гардероба»).
  • Отсутствие транзакционности. Нет механизма отката, если ордер потерян (аналог ROLLBACK).
  • Ручной поиск. Алфавитный указатель работает медленнее, чем B-tree-индекс.
  • Нет бэкапов. Пожар в Старкомхозе равен полной потере данных.

Эту базу вполне можно пересобрать на PostgreSQL с соблюдением всех нормальных форм. Что я сделала: создала интерактивную демоверсию БД конфискованной мебели, добавила туда фамилии раскулаченных, упомянутые авторами в книге, а также придумала еще фамилии бывших дворян, чтобы список стал больше.

Вы можете сделать запросы в базу данных Коробейникова самостоятельно, вот что для этого нужно: 

  1. Скачайте демоархив Коробейникова (сохранится файл БД Korobeynikov.db, 40 KB). 
  2. Зайдите в SQL-песочницу https://sqliteonline.com/ (или в DBeaver).
  3. Нажмите» «+» в левом верхнем углу → нажмите Open SQLite DB → выберите и откройте из загрузок скачанный файл Korobeynikov.db.
  4. Слева должна открыться демоверсия СУБД с названием Korobeynikov, а также четыре таблицы с фамилиями и мебелью.
  5. Попробуйте написать SQL-запрос, который найдет те самые стулья с сокровищами, и нажмите на треугольник (RUN), чтобы получить результат.

Экспериментируйте и пишите в комментариях, что вам удалось найти 🙂

Комментарии0
Тоже интересно
Комментировать
Поделиться
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники