Мы используем MySQL для хранения данных без схемы (см. Использование реляционной базы данных для данных без схемы для решения, вдохновленного тем, как FriendFeed использует MySQL для хранения данных без схемы).
Одна большая таблица содержит все сущности для нашего приложения:
CREATE TABLE entities (
added_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
, id BINARY(16) NOT NULL
, body MEDIUMBLOB
, UNIQUE KEY (id)
) ENGINE=InnoDB ;
Немного подробностей:
Единственное обязательное свойство хранимых объектов - это
id
, 16-байтовый UUID. Остальная часть объекта непрозрачна для базы данных. Мы можем изменить «схему», просто сохранив новые свойства вbody
.Столбец
added_id
присутствует, потому что InnoDB физически хранит строки данных в порядке первичного ключа. Первичный ключ AUTO_INCREMENT гарантирует, что новые сущности записываются на диск последовательно после старых сущностей, что помогает для локальности чтения / записи (новые сущности читаются чаще, чем старые).Наша база данных хранит наши бессхемные данные в
body
. ‹- Это тема этого вопроса.Множество других интересных деталей, таких как "доступ" к данным
body
для построения асинхронных материализованных представлений (индексы - это просто таблицы, которые создаются в автономном режиме), но они не имеют отношения к текущему обсуждению ...
Как мы должны сериализовать структурированные данные (пары ключ-значение) в body
?
JSON или BSON были бы простыми, поскольку имена полей повторяются для каждой строки. Это дает ему преимущество в гибкости, но также и большой недостаток в эффективности использования пространства (накладные расходы для каждой строки для имен полей в сериализованных данных). Мы стараемся хранить вещи в памяти, и здесь важно минимизировать объем памяти и сети. Чем больше записей мы поместим в одно и то же пространство, тем быстрее будут выполняться наши запросы. Мы предпочитаем относительно длинные описательные имена полей, и сокращать их, чтобы моя база данных работала быстрее, неправильно!
В конце концов, JSON / BSON неприменим для наших целей, если мы не сделаем более сложным и не сопоставим маленькие ключи с более описательными ключами в драйвере приложения, который общается с базой данных. Что заставило нас задуматься ...
Хотя наша база данных не имеет схемы, на самом деле: 1) не так много разных типов сущностей, 2) версии одного и того же типа сущностей не часто меняются и 3) когда они меняются, обычно просто добавляется другое поле. JSON / BSON не имеют встроенной поддержки управления версиями.
Буферы протоколов и экономия средств намного сложнее, когда дело доходит до управления версиями и изменений определения данных. И Thrift, и Protocol Buffers являются отличными кандидатами для сериализации данных в базы данных, а Thrift спроектирован таким образом, что формат кодирования является расширяемым.
Буферы протоколов выглядят как отличный выбор для сериализации данных в бессхемной базе данных.
CouchDB и MongoDB (две самые популярные базы данных без схемы?) Используют JSON и BSON соответственно, но мы не можем найти ничего об использовании чего-то более продвинутого, например протокольных буферов, в качестве формата сериализации для хранения данных без схемы. . Существуют продукты, которые хранят версию объектов определенного языка (например, хранят внешние объекты Java в сетке данных или выполняют NoSQL с MySQL в Ruby), но это проблема (попробуйте получить к ним доступ с других платформ или даже из самого MySQL, и забудьте о версиях).
Кто-нибудь хранит более функционально совместимые буферы протоколов в своей базе данных или какой-либо другой расширенный формат сериализации в своей базе данных без схемы? Это вопрос о том, есть ли другие варианты, кроме простой сериализации для каждой строки JSON / BSON / XML или сериализации объектов определенного языка. Это вообще возможно? Мы что-то упускаем? извините за повествование в стиле потока сознания!