Открыть сервис

Rowstore

Rowstore (от англ. row — строка и store — хранилище) — это форма организации хранения данных в реляционных базах данных, при которой записи (строки) таблицы физически располагаются на диске последовательно, одна за другой. В такой модели все атрибуты (столбцы) одной строки хранятся в одном блоке или наборе смежных блоков, что обеспечивает высокую скорость операций, работающих с целыми записями (вставка, обновление, удаление, выборка по первичному ключу). Rowstore является традиционным и наиболее распространённым способом хранения данных в системах управления базами данных (СУБД), ориентированных на обработку транзакций (OLTP).

История

Концепция rowstore восходит к ранним коммерческим СУБД 1960–1970-х годов, таким как IBM IMS (иерархическая) и System R (реляционная). В этих системах физическая модель хранения была естественным образом построена вокруг строк, поскольку основной задачей была обработка транзакций — операций, затрагивающих небольшое количество записей. С развитием реляционной модели (Э. Кодд, 1970) и появлением SQL в 1970-х годах rowstore стал стандартом де-факто для всех ведущих СУБД, включая Oracle, DB2, Microsoft SQL Server, PostgreSQL и MySQL.

Долгое время rowstore оставался единственным способом хранения данных. Однако с ростом объёмов данных и появлением аналитических нагрузок (OLAP) в 1990-х годах начали разрабатываться альтернативные форматы, такие как columnstore (столбцовое хранение), оптимизированные для агрегаций и сканирования большого количества строк. Тем не менее, rowstore сохраняет доминирующее положение в транзакционных системах благодаря своей эффективности для операций с отдельными записями.

Принцип работы

В rowstore данные каждой строки таблицы хранятся в виде непрерывной последовательности байтов. Когда СУБД считывает блок данных (обычно размером 4–16 КБ), она получает все столбцы одной или нескольких строк целиком. Это минимизирует количество операций ввода-вывода при работе с целыми записями.

Например, для таблицы: `` id | name | age | city 1 | Иван | 30 | Москва 2 | Мария | 25 | Санкт-Петербург ` Физически на диске данные могут быть записаны как: ` [1, Иван, 30, Москва][2, Мария, 25, Санкт-Петербург] `` Каждая строка занимает смежную область, и для её извлечения достаточно одного чтения.

Архитектура и компоненты

Страничная организация

Большинство СУБД используют страничную организацию памяти. Страница (блок) — минимальная единица обмена с диском. В rowstore страница содержит одну или несколько полных строк. Каждая строка имеет заголовок, хранящий метаданные (длину, флаги, версию), за которым следуют значения столбцов.

Индексы

Для ускорения поиска по столбцам, не являющимся первичным ключом, в rowstore создаются индексы. Индексы могут быть:

  • B-деревья (B-tree) — наиболее распространённый тип, поддерживающий быстрый поиск, вставку и удаление.
  • Хеш-индексы — для точного поиска по равенству.
  • Битовые индексы — редко используются в rowstore из-за низкой эффективности для транзакционных нагрузок.

Индексы хранят копии ключей и ссылки на строки (например, RID — row identifier), что позволяет быстро находить нужные записи без полного сканирования таблицы.

Буферный кеш

СУБД использует буферный кеш (shared buffers) для хранения часто запрашиваемых страниц в оперативной памяти. В rowstore кеширование целых строк позволяет ускорить повторные обращения к тем же записям.

Преимущества

  • Высокая скорость операций с отдельными строками: вставка, обновление, удаление и выборка по первичному ключу выполняются за минимальное количество операций ввода-вывода.
  • Простота реализации и поддержки: rowstore является стандартным форматом для большинства СУБД, что упрощает администрирование и миграцию.
  • Эффективность для транзакционных систем: OLTP-нагрузки, характерные для банковских, торговых и ERP-систем, хорошо ложатся на rowstore.
  • Поддержка ACID: rowstore обеспечивает целостность транзакций благодаря блокировкам на уровне строк и журналированию.

Недостатки

  • Низкая производительность для аналитических запросов: при сканировании большого количества строк (например, для агрегаций SUM, AVG) rowstore вынужденно считывает все столбцы, даже если нужны только один-два. Это приводит к избыточному вводу-выводу.
  • Плохая сжимаемость: данные разных типов (числа, строки, даты) хранятся вперемешку в одной строке, что затрудняет эффективное сжатие.
  • Фрагментация: при частых вставках и обновлениях строки могут разбиваться на несколько фрагментов, что снижает производительность и требует периодической дефрагментации (REINDEX, VACUUM).

Сравнение с columnstore

ХарактеристикаRowstoreColumnstore
Основная нагрузкаOLTP (транзакции)OLAP (аналитика)
Скорость чтения одной строкиВысокаяНизкая (требует сборки из колонок)
Скорость агрегацийНизкаяВысокая
СжатиеСлабоеСильное (за счёт однотипности)
Вставка/обновлениеБыстроеМедленное (требует перестроения)
ИндексацияРазвитая (B-tree, hash)Ограниченная

Применение

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

  • Банковские системы: обработка платежей, переводов, выписки по счетам.
  • Электронная коммерция: управление заказами, корзинами, пользователями.
  • ERP и CRM: учёт товаров, контактов, сделок.
  • Системы управления контентом (CMS): хранение статей, комментариев, пользователей.
  • Медицинские информационные системы: запись пациентов, назначения, результаты анализов.

В современных СУБД, таких как Microsoft SQL Server, PostgreSQL и MySQL, rowstore является форматом по умолчанию. Некоторые СУБД (например, SQL Server, ClickHouse) поддерживают гибридные режимы, позволяя создавать как rowstore-, так и columnstore-таблицы в одной базе данных.

Примеры реализации

PostgreSQL

В PostgreSQL rowstore реализован через механизм «кучи» (heap). Каждая строка хранится в странице, а для поиска используются индексы (B-tree, GiST, GIN). СУБД поддерживает MVCC (многоверсионное управление параллельным доступом), что позволяет одновременно читать и записывать данные.

MySQL (InnoDB)

Движок InnoDB в MySQL использует кластеризованные индексы: строки хранятся в порядке первичного ключа. Вторичные индексы содержат ссылки на первичный ключ, что ускоряет поиск.

Microsoft SQL Server

SQL Server поддерживает rowstore как стандартный формат. Для аналитических нагрузок можно создавать columnstore-индексы поверх rowstore-таблиц, что позволяет комбинировать преимущества обоих подходов.

Интересные факты

  • Термин «rowstore» стал активно использоваться в 2000-х годах после появления columnstore-систем, чтобы отличать традиционный подход от нового.
  • В некоторых СУБД (например, SAP HANA) данные могут храниться одновременно в rowstore и columnstore, а выбор формата определяется типом таблицы.
  • Rowstore-таблицы обычно имеют более высокую стоимость хранения по сравнению с columnstore из-за слабой сжимаемости.

Критика

Основная критика rowstore связана с его неэффективностью для аналитики. В эпоху Big Data и массового внедрения OLAP-систем rowstore часто называют «узким местом» производительности. Однако для транзакционных систем альтернативы ему практически нет, и попытки заменить rowstore columnstore в OLTP приводят к серьёзному падению скорости вставки и обновления.

Источники

  • Ramakrishnan, R., Gehrke, J. — «Database Management Systems» (3rd edition), 2003.
  • Garcia-Molina, H., Ullman, J. D., Widom, J. — «Database Systems: The Complete Book» (2nd edition), 2008.
  • Документация PostgreSQL: «Chapter 68. Database Physical Storage».
  • Документация Microsoft SQL Server: «Rowstore vs. Columnstore Indexes».
  • Статья «What is a Rowstore?» на сайте IBM Knowledge Center.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →