TGViewer
C# Short Posts 🔞 C# Short Posts 🔞 @dimasshortposts · 306 subscribers
Post #420 635
В жизни каждого шарписта наступает момент, когда надо разобраться, наконец, как работает СУБД, которой он каждый день пользуется.
Прежде чем написать этот короткий пост, я погрузился в тему баз данных и в какой-то степени они стали для меня открытой книгой, буквально, потому что в них слишком много аналогий с книгами. Оказывается, что концепция, на которой стоит вообще всё хранение данных, одна и та же что в PostgreSQL, в MySQL, и даже в MongoDB — страницы 📄

📖 Что такое страница и зачем она
Когда ты делаешь INSERT INTO users (...), в голове картина обычно простая: «строчка просто легла куда-то в таблицу». Физически — нет. Ни одна нормальная СУБД (что реляционная, что документная) не пишет каждую строку или документ отдельно. Вместо этого данные складываются в страницы (pages) — блоки фиксированного размера.
У PostgreSQL и SQL Server страница — 8 KB, у MySQL/InnoDB — 16 KB, у MongoDB через WiredTiger — настраивается, но того же порядка. Любая операция чтения или записи — это работа с целой страницей, а не с одной строкой.
Почему так? Потому что диск и RAM физически работают блоками, а не байтами. Один поход на диск всё равно вытаскивает целый блок килобайт на восемь — хочешь ты того или нет. СУБД этим пользуется: складывает в одну страницу столько строк или документов, сколько влезет. Берёшь одну строку — получаешь рядом «соседей» бесплатно 💋

🔬 Давай потрогаем руками
Самое классное — это всё можно пощупать, если поднять, например, PostgreSQL в Docker. Полный список команд для последовательного выполнения сможешь найти 👉вот здесь👈 (а то пост получится уже не таким коротким) 🥖

На пояснительном дикпике 1 можно увидеть, где физически лежит созданная таблица и сколько весит: файл занимает ровно 409600 байт = 50 × 8192, то есть страницы ровно по 8 KB. И таких страниц в одном файле подряд — 50 штук, это и есть вся таблица.

На дикпике 2 можно увидеть, как заглянуть внутрь файла прямо из контейнера и что записи лежат сырыми байтами в одной из 50 страниц.

📍 Где какая строка лежит
В Postgres у каждой строки есть служебный «адрес» — ctid, пара (номер страницы, номер слота на странице).

На дикпике 3 запрос, который покажет адреса выбранных строк, и там же видно, что в нулевую страницу 8 KB у нас влезла 121 строка, в первую — следующие 120, и так далее. На 6000 строк ушло 50 страниц — ровно то, что мы видели по размеру файла. Когда СУБД хочет прочитать запись с id = 5999, она не «ищет в таблице» — она поднимает с диска страницу №49 и достаёт из неё нужный слот.

🧑‍💻 Что с этим знанием делать в работе
1. Чтение одной строки = чтение целой страницы. Запросом за одной строчкой ты всё равно поднимаешь с диска 8 (или 16) KB. Если в WHERE id IN (...) много значений и они физически рядом — это почти бесплатно. Если разбросаны по таблице — каждое чтение отдельная страница.
2. Узкие таблицы — это не только про место. Чем шире строка, тем меньше их влезает в страницу. Большое поле text на килобайт-другой может уронить плотность в 20 раз — и для того же количества строк понадобится в 20 раз больше страниц.
3. shared_buffers / buffer pool — это кэш страниц, не строк. Когда тюнят память под СУБД, имеют в виду «сколько страниц влезет в RAM». И именно поэтому случайные чтения по большой таблице болят: каждая страница приходит с диска заново.
4. В Postgres UPDATE — это DELETE + INSERT. Старая версия строки помечается мёртвой и продолжает лежать на той же странице, новая дописывается рядом. Поэтому после массовых апдейтов файл таблицы пухнет, пока не пройдёт VACUUM. Та же логика — ctid после UPDATE меняется, потому что физически это уже другая запись на другом слоте.

А если в таблице миллионы записей, как БД так быстро находит нужную? Для этого нужны индексы, но о них — в другом посте👉

🧑‍💻dp 🥁
#бд #postgresql #инженерныештучки #heavywednesday
  • ❤ 2
More from @dimasshortposts
  1. Sep 26, 2026🧵 Тредик для вопросов по докладу про MAF на дотнексте В докладе многие подробности опусти…
  2. Sep 23, 2026Даже самым хардкорным ребятам надо отдыхать, так что отдыхаем, мои чюваки 🕺 🧑‍💻dp🥁 #he…
  3. Sep 16, 2026🎯 Instrumented Tier0: профилирование кода В прошлый раз мы разобрали два уровня компиляци…
  4. Sep 15, 2026🔜 Готовлюсь к DOTNEXT 2026 В прошлом году за две недели до выступления я зачитывал свой д…
  5. Sep 9, 2026C# Short Posts 🔞 pinned «🐸 О чём этот канал? Кажется, я уже достаточно давно веду этот к…
  6. Sep 9, 2026🐸 О чём этот канал? Кажется, я уже достаточно давно веду этот канальчик, и пора бы описат…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →