Вопрос базы данных: заменить простые реляционные таблицы на нереляционные?
У меня есть веб-приложение, работающее над базой данных MySQL (в разработке). Я планирую перенести свое приложение в Google App Engine и хотел бы лучше понять, как моя простая модель реляционной базы данных может быть преобразована в нереляционный подход.
Я давно работаю с реляционными базами данных, и у меня нет опыта работы с БД на основе столбцов, таких как BigTable. На всякий случай, если Google также поддерживает небольшие развертывания реляционных баз данных, я хотел бы заявить, что мой вопрос является общим и не специфичным для Google - я хотел бы понять, как простые реляционные модели могут быть представлены в нереляционных БД.
Моя база данных (упрощенная) выглядит следующим образом:
Items Table
------------
ItemID ItemName ItemPriority
1 "Car" 7
2 "Table" 2
3 "Desk" 7
ItemProperties Table
---------------------
ItemID Property Importance
1 "Blue" 1
1 "Four Wheels" 2
1 "Sedan" 0
2 "Rectangular" 1
2 "One Leg" 1
У меня есть много предметов, каждый с именем и идентификатором. Каждый элемент имеет несколько свойств, каждое свойство имеет несколько параметров (я только указал название и "важность" каждого свойства, но есть и другие). У меня десятки миллионов предметов, у каждого есть сотни свойств.
Сценарий использования: я получаю ItemName в качестве входных данных, ищу его идентификатор в таблице элементов и извлекаю все свойства по этому идентификатору. Затем я выполняю некоторый анализ списка свойств (в памяти) и возвращаю результат.
90% работ - это поиск, основанный на параметре, который (если я правильно понимаю) является основной проблемой нереляционных БД.
Какой рекомендуемый подход?
4 ответа
От того, кто какое-то время работал с Нереляционными БД, ваши две таблицы должны быть действительно легко переведены в нереляционные БД.
Возьмите две таблицы и превратите их в один объект.
Предмет: - Id - Имя - Свойства - prop1 - prop2
Сохраните все это в своих столбцах хранилища данных (Big-Table), документе (CouchDB) или в другом месте, где оно используется.
Вы можете искать элементы по любому из идентификаторов, имен или свойств. Нет никаких объединений, которые являются одной из самых больших болевых точек нереляционных БД. Поиск параметров на самом деле не является проблемой, если я не понимаю, что вы подразумеваете под этим. Возможно, вам придется сделать несколько поисков, но в большинстве случаев это не проблема, и она масштабируется намного лучше, чем rdbms.
В вашем примере я на самом деле считаю нереляционную модель проще и проще для реализации и понимания.
Каждое нереляционное хранилище данных имеет свои условные обозначения и ограничения, хотя трудно дать руководство в общем смысле. CouchDB может создать индекс для любой части объекта, например, с его представлениями. С BigTable вам, возможно, придется хранить несколько копий денормализованных данных, чтобы получить быстрый индексированный поиск. У других будут разные вещи, когда вы решите, как хранить данные. Когда вы покидаете мир SQL, существует множество различий.
Вы должны сгладить все это, я думаю, что AppEngine позволяет такие структуры, как
ID=1, ItemName=Car, ItemPriority=7, Свойство = (Синий,1), Свойство = (Четыре Колеса,2), Свойство = (Седан,0) ID=2, ItemName= Таблица, ItemPriority=2, Свойство = (Прямоугольный,1), Свойство = (Одна нога,1) ID=3, ItemName=Desk, ItemPriority=7
Обратите внимание, что одно и то же "поле" может иметь несколько значений и что в нем можно использовать несколько элементов.
Ваш пример данных будет 3 строки в одной таблице.
GQL не поддерживает объединения. Вы можете обойти это двумя способами:
- Сделай сам
Просто выберите Item, проверьте его ItemID и запросите ItemProperties с этим ItemID. Ваши таблицы будут выглядеть точно так, как вы их указали. Конечно, это два запроса, но эти два запроса просты.
- Используйте модели Expando
В модели Expando вы можете создавать новые поля во время выполнения. Они не будут проиндексированы, поэтому, если вы хотите искать по ним, это может быть медленнее, но просто получить их просто. Вы также можете использовать сложные типы, такие как ListProperty. Благодаря такой гибкости вы можете придумать способ поместить все данные из таблицы ItemProperties в таблицу Items и сохранить свой запрос. Будь креативным.
У меня очень похожая структура базы данных (наши таблицы "records" и "recordEntries" отражают ваши "items" и "itemProperties"), и я рассматриваю возможность аналогичной миграции на нереляционную базу данных. Мы, вероятно, пойдем в CouchDB или memcachedb или что-то в этом роде, а не в Google.
Как и у вас, у меня нет опыта работы с нереляционными базами данных (как и мои разработчики). Тем не менее, мы бросили пару идей вокруг. Наши текущие мысли (используя вашу схему):
- Во-первых: сверните каждый элемент плюс его свойства элемента в один объект с полями (по сути, документ XML) и вставьте его в базу данных с ключами по идентификатору. Каждый раз, когда вы получаете предмет, вы получаете обратно все itemProperties.
Обратите внимание на то, что у нас есть различие в том, что мы индексируем наш контент вне базы данных (с помощью Solr), и, следовательно, нет необходимости выполнять поиск в самой базе данных с использованием свойства name, поэтому YMMV.
- Второе: мы составляем список всех "реляционных" операций, которые мы делаем, которые не могут поддерживаться моделью выше. Это включает в себя несколько операций "группировки", в которых мы запрашиваем элементы на основе специального поля в таблице элементов, и запрос, в котором мы пытаемся обнаружить все элементы, которые были недавно изменены (ранее выполненные с помощью запроса в столбце даты в таблица предметов). Мы придумываем альтернативные реализации для каждого из этих случаев (к счастью, их всего несколько).
Если это окажется слишком сложным, мы попробуем то же самое упражнение с другой моделью. К счастью, у нас есть время для планирования.
Одним из ключевых моментов для нас является то, что мы выполняем внешнюю индексацию с помощью Solr, поэтому (например) нам не нужно выполнять поиск в базе данных по значениям в значениях itemProperties или выполнять поиск по имени в таблице элементов.
В любом случае, это, вероятно, не сильно поможет, но я буду стремиться увидеть, какие решения могут предложить более опытные люди.
PS: я предполагаю, что ваша таблица свойств должна содержать миллиарды строк. Сколько именно и на каком оборудовании вы используете сервер MySQL? У вас есть проблемы с масштабируемостью с MySQL?