Одной из наиболее важных функций любой базы данных является скорость запросов. Мы храним данные и хотим быстрый доступ к данным, которые соответствуют нашим критериям. Однако в последнее время базы данных без схем стали популярными. Одно дело, если у нас есть база данных без схемы, но на самом деле есть логическая схема (в голове / в приложении); он просто не был официально объявлен базой данных.
С другой стороны, допустим, нам действительно нужна открытая база данных, в которой несколько пользователей имеют свои собственные схемы для своих собственных проблемных областей. Пользователь будет определять свой собственный «домен». Этот домен (база данных на сервере 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.
К сожалению, это один из тех случаев, когда несмотря на совет Джоэла Спольски я пыталсяархитектура космонавтов.