Вопрос по базе данных:Изменить простые реляционные таблицы на нереляционные?

StackOverflow https://stackoverflow.com/questions/938751

Вопрос

У меня есть веб-приложение, работающее с базой данных 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

У меня много предметов, каждый из которых имеет имя и идентификатор.У каждого элемента есть несколько свойств, у каждого свойства есть несколько параметров (я указал только имя и «важность» каждого свойства, но есть и другие).У меня есть десятки миллионов предметов, каждый из которых имеет сотни свойств.

Сценарий использования:Я получаю имя элемента в качестве входных данных, ищу его идентификатор в таблице элементов и извлекаю все свойства по этому идентификатору.Затем я выполняю некоторый анализ списка свойств (в памяти) и возвращаю результат.

90% работы — это поиск по параметру, что (если я правильно понимаю) является болевой точкой нереляционных БД.

Каков рекомендуемый подход?

Это было полезно?

Решение

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

Возьмите две таблицы и превратите их в один объект.

Элемент:- ID - имя - свойства - Prop1 - Prop2

Храните все это в столбцах хранилища данных (Big-Table), документах (CouchDB) или в чем-то еще, что оно использует.

Вы можете искать элементы по любому из идентификаторов, имен или свойств.Нет объединений, которые являются одной из самых болевых точек нереляционных баз данных.Поиск параметров на самом деле не является болевой точкой, если я не понимаю, что вы под этим подразумеваете.Возможно, вам придется выполнить несколько поисков, но в большинстве случаев это не проблема, и он масштабируется намного лучше, чем rdbms.

В вашем примере я на самом деле считаю, что нереляционная модель проще и легче реализовать и понять.

Однако каждое нереляционное хранилище данных имеет разные соглашения и ограничения, поэтому сложно дать рекомендации в общем смысле.CouchDB может создать индекс для любой части объекта, например, с его представлениями.При использовании BigTable вам, возможно, придется хранить несколько копий денормализованных данных, чтобы обеспечить быстрый индексированный поиск.Другим придется учитывать разные моменты, когда вы решите, как хранить данные.Когда вы покидаете мир SQL, существует довольно много дифференциации.

Другие советы

GQL не поддерживает соединения.Вы можете обойти это двумя способами:

  • Присоединяйтесь сами

Просто извлеките элемент, проверьте его идентификатор ItemID и запросите ItemProperties с этим идентификатором ItemID.Ваши таблицы будут выглядеть точно так, как вы их указали.Конечно, это два запроса, но эти два запроса просты.

  • Используйте модели Expando

В модели Expando вы можете создавать новые поля во время выполнения.Они не будут проиндексированы, поэтому если вы захотите выполнить поиск по ним, это может быть медленнее, но просто получить их вполне достаточно.Вы также можете использовать сложные типы, такие как ListProperty.Благодаря такой гибкости вы, возможно, сможете придумать способ поместить все из таблицы ItemProperties в таблицу Items и сохранить запрос.Будь креативным.

У меня очень похожая структура базы данных (наши таблицы «records» и «recordEntries» отражают ваши «items» и «itemProperties»), и я рассматриваю аналогичный переход на нереляционную базу данных.Мы, вероятно, воспользуемся CouchDB, memcachedb или чем-то в этом роде, а не Google.

Как и у вас, у меня нет опыта работы с нереляционными базами данных (как и у моих разработчиков).Тем не менее, мы подкинули пару идей.Наши текущие мысли (используя вашу схему):

  • Первый:Сверните каждый элемент, а также его свойства элемента в один объект с полями (по сути, XML-документ) и поместите его в базу данных с ключом по идентификатору.Каждый раз, когда вы извлекаете элемент, вы также возвращаете все его свойства.

Обратите внимание, что наша разница заключается в том, что мы индексируем наш контент вне базы данных (с помощью Solr), и поэтому нам не нужно выполнять поиск в самой базе данных с использованием свойства «name», поэтому YMMV.

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

Если это окажется слишком сложно, мы попробуем то же самое упражнение с другой моделью.К счастью, у нас есть время планировать.

Одним из ключевых моментов для нас является то, что мы выполняем всю нашу индексацию извне с помощью Solr, поэтому (например) нам не нужно выполнять поиск в базе данных по значениям в значениях itemProperties или выполнять поиск по имени в таблице элементов.

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

ПС:Я делаю вывод, что ваша таблица свойств должна содержать миллиарды строк.Сколько именно и на каком оборудовании вы используете сервер MySQL?У вас уже возникли проблемы с масштабируемостью MySQL?

Вам нужно все это сгладить, я думаю, AppEngine допускает такие структуры, как

Id = 1, itemname = car, itempriority = 7, property = (blue, 1), свойство = (четыре колеса, 2), свойство = (седан, 0) id = 2, itemname = table, itempriority = 2, свойство = (Прямоугольный, 1), свойство = (одна нога, 1) id = 3, itemname = desk, itempriority = 7

Обратите внимание, что одно и то же «поле» может иметь несколько значений и в нем можно использовать несколько элементов.

Ваши примерные данные будут состоять из 3 строк в одной таблице.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top