Индексировать базы данных без схемы, имеющие определенные пользователем схемы? - PullRequest
1 голос
/ 23 февраля 2011

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

С другой стороны, допустим, нам действительно нужна открытая база данных, в которой несколько пользователей имеют свои собственные схемы для своих собственных проблемных областей. Пользователь будет определять свой собственный «домен». Этот домен (база данных на сервере RDBMS) будет иметь свои типы (таблицы в RDBMS), и эти типы будут иметь свои собственные свойства (столбцы в RDBMS). Как мне создать составные индексы для извлечения определенных объектов / документов / записей (что у вас есть) из данного домена? Мой запрос должен выбрать один или несколько доменов (предложение IN), только один тип темы (например, CalendarEvent), для определенных столбцов (start_date> = today, start_date <= today + 1 week, open_for_registration = true, calendar_name = 'Public' ). В базе данных с фиксированной схемой (подразумеваемой, даже если она не объявлена) это просто: вы создаете составной индекс для столбцов. </p>

Сложность состоит в том, что мы, по сути, сделали один экземпляр, скажем, MongoDB, действующий как сервер RDBMS со многими базами данных, где каждая база данных и связанная с ней схема является нашим "доменом".

После недолгого размышления над этой проблемой и просмотра различных баз данных (MongoDB, Neo4j, MySQL, PostgreSQL) я нашел только несколько возможных решений:

  • Индекс всех свойств. Свойство может быть представлено в таблице свойств или в виде внедренного документа в MongoDB. В СУБД значения свойств должны быть сериализованы в строки. Минусы: a) Можно выполнять поиск только по одному свойству за раз (без составных индексов), b) все получает индекс, поэтому мы получаем ненужные накладные расходы.
  • Индекс выбора свойств. В PostgreSQL это можно сделать с помощью фильтрованного индекса. По сути, запись свойства будет немного называться «проиндексированной», которую мне придется поддерживать. Этот бит будет определять, использует ли отфильтрованный индекс это конкретное свойство. Минусы: а) мы все еще можем искать только по одному свойству за раз. Это исключает "составные индексы" из использования. Единственный способ, которым я могу вообразить имитацию составного индекса, - это поиск по каждому отдельному индексируемому свойству и возврат пересечения PK.
  • Создание / поддержка конструкций базы данных для отражения рабочих индексов. В MongoDB я мог создать коллекцию «indexables». Документ в этой коллекции может выглядеть следующим образом: {domain_id: ObjectId (..), type_id: ObjectId (..), поля: {field1: «some int value», field2: «some date value», field3: «some битовое значение "}}. Затем я индексирую коллекцию «indexables» для {domain_id: 1, type_id: 1, «fields.field1»: 1, «fields: field2»: 1, «fields: field3», 1}. Затем каждый раз, когда я создаю / обновляю документ в своей коллекции «вещей», мне нужно будет вставлять его значения в слоты индексируемых полей field1, field2, field3. (Это прекрасно работает с MongoDB, потому что я могу вставлять значения любого типа данных в эти заполнители. В MySQL, используя тот же шаблон, мне пришлось бы сериализовать значения в строки.) Мне также пришлось бы поддерживать domain_id и type_id. По сути, это уровень индекса (которым я управляю сам), построенный поверх индексов, обрабатываемых базой данных. Минусы: есть дополнительные накладные расходы. В то время как база данных обычно управляла бы индексами от моего имени, теперь я должен позаботиться о том, чтобы сделать это сам. Поскольку MongoDB не имеет понятия транзакций, я не мог гарантировать, что документ и его различные индексы были зафиксированы за один шаг. ПРОФИ: У меня есть свои составные индексы обратно. Индексы поддерживаются на уровне домена.
  • Я рассмотрел возможность предоставления пользователям собственных экземпляров базы данных X. Или в MongoDB их собственных коллекций.Но мне было интересно, не создаст ли это больше проблем, особенно когда мы сталкиваемся с практическими ограничениями (разрешено количество баз данных или коллекций).Я отбросил эту идею, не слишком много думая.

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

Опять же, идея такова: разные пользователи управляют своими собственными доменами.Внутри домена могут быть предметы любого «типа».Для каждого набранного элемента у нас есть свойства.Я хочу, чтобы пользователи могли выполнять запросы к своим доменам, чтобы получать элементы типа, свойства которого соответствуют их условиям.(таким образом, составные индексы)

Последняя мысль.Домен сам по себе не предназначен быть огромным.Это может иметь 10-20 «типов».В каждом типе их может быть до 5000 записей (в большинстве случаев), а в крайних случаях - 20000.

К сожалению, это один из тех случаев, когда несмотря на совет Джоэла Спольски я пыталсяархитектура космонавтов.

1 Ответ

1 голос
/ 24 февраля 2011

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

Рассматривали ли вы Excel?Может быть, просто проиндексированные плоские файлы:)

Слушайте, основная проблема, с которой вы столкнетесь, заключается в том, что нет серебряной пули.Ваша идея в порядке, но в какой-то момент вы должны принять некоторый набор компромиссов.

Вы не можете все индексировать.В какой-то момент вам придется идентифицировать «часто используемые» запросы и построить некоторые индексы для этих вещей.Если вы не планируете хранить все в памяти, вы в конечном итоге создадите индексы.

В каждом типе их может быть до 5000 записей (в большинстве случаев) и, скажем, 20000в крайних случаях.

Эй, есть настоящее ограничение.Сколько оборудования вы можете выбросить на 5k записей?Как насчет 200k записей?Будет ли этого достаточно, чтобы хранить все это в оперативной памяти?Сохранить часть этого в оперативной памяти?Сохранять только индексы в оперативной памяти?

Если вы хотите, чтобы пользователи просто добавляли свои собственные "динамические" схемы, я лично считаю, что MongoDB является естественным соответствием.Специально для этих небольших наборов данных, которые вы указываете.

Но это ни в коем случае не серебряная пуля.Каждое из этих решений будет иметь свой собственный набор проблем.Если бы существовала реальная БД, которая могла бы удовлетворить все выдвинутые вами требования, давайте посмотрим правде в глаза, мы все использовали бы эту БД:)

...