Как реализовать пользовательские поля и группировки для мультитенантного приложения: EAV, шаблон фиксированных таблиц, NoSQL - PullRequest
10 голосов
/ 21 ноября 2010

Я работаю в SaaS, где любой арендатор может иметь несколько списков контактов, каждый список может иметь любое количество настраиваемых полей, которые могут хранить контакты в этом списке, и любое количество групп, которые могут быть включены в список (группы используются для сегментирования контактов из списка).У каждого контакта есть одно обязательное поле: адрес электронной почты и любое количество пользовательских полей, которые определены для списка, где он, как я уже упоминал.Мы должны быть в состоянии найти контакты из списков на основе групп, в которых они находятся, и значений пользовательских значений.Мы должны предоставить до 30 пользовательских полей.Теперь я вижу три способа решения этой проблемы:

  1. Использование вида EAV (мы пытаемся сделать это так), но это выглядит довольно сложно.У нас есть таблица списков (списки арендаторов), связанные таблицы custom_fields, связанные таблицы подписчиков, в которых хранятся email_addreses подписчиков списка, таблица subs_custom_data, которая связана с таблицами подписчиков и custom_fields (сохраняются значения пользовательских полей подписчиков).

  2. Шаблон таблицы полей.Его описание здесь http://blog.springsource.com/arjen/archives/2008/01/24/storing-custom-fields-in-the-database/. В этом случае мы будем использовать поле, связанное с настраиваемыми полями, которое будет хранить в столбцах все настраиваемые поля, например, иметь 30 столбцов для хранения значений каждого из возможных настраиваемых полей и таблицу.в котором хранится отображение имени столбца и имени определенного пользователем поля.Это выглядит сложным тоже.У нас должно быть как минимум 30 индексов для поиска по значениям настраиваемых полей, есть и другие проблемы:

  3. Чтобы использовать какую-либо базу данных NoSQL, по крайней мере, для храненияпользовательские поля и, возможно, группы из списка.Как вы думаете, такие базы данных могут помочь здесь, и если да, то как спроектировать для хранения пользовательских полей и групп.Я пытаюсь взглянуть на разные типы NoSQL, например, на документы, ориентированные на MongoDb, но сразу не понимаю, как это может помочь решить эту проблему.Здесь мы можем хранить произвольные атрибуты, но для поиска значений настраиваемых полей нам нужно заранее их проиндексировать, чтобы мы знали, какие настраиваемые поля у нас будут.

Спасибоза любую информацию об этом.

1 Ответ

9 голосов
/ 23 января 2012

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

Вот комментарии о других опциях:

  1. EAV is noхорошо, и я против его использования.Это нарушает многие правила проектирования реляционных баз данных и не масштабируется.Я много писал об этом в Stack Overflow, поэтому ищите мои ответы в теге eav.

  2. Вам не нужно всего 30 индексов- вам нужно до 30 факторных индексов для обработки любой возможной комбинации индексов.Помните, что вы можете создавать многостолбцовые индексы, и эти типы индексов важны для поддержки определенных запросов.Конечно, это совершенно нецелесообразно создавать так много индексов;вам нужно создать индексы, соответствующие запросам, для которых вы хотите оптимизировать.Если вы не знаете, какие поля у вас будут, и какие запросы у вас будут к ним, вы не сможете оптимизировать.

  3. Документно-ориентированные базы данных, такие как MongoDB / CouchDB aren 'магия, независимо от того, насколько их сторонники пытаются утверждать, что они есть.Они требуют индексирования документов для быстрого поиска, а это означает, что вам необходимо знать индексируемые поля документа.

    Создание индекса во время выполнения является проблемой, потому что это может занять много времени, в зависимости от того, какмного данных есть для индексации.Вам нужно будет найти способ запустить создание индекса в автономном режиме (т. Е. Не заставлять пользователя ждать его во время одного http-запроса), а затем уведомить его о завершении.

  4. Вы должны прочитать о Как FriendFeed использует MySQL для хранения данных без схемы .Они используют Serialized LOB, в основном объединяют все пользовательские атрибуты в один BLOB-объект XML или JSON.Таким образом, пользователи могут создавать любое количество дополнительных настраиваемых полей в любое время.Но прежде чем данное настраиваемое поле можно будет сделать доступным для поиска, вы должны создать дочернюю таблицу, которая ссылается на строки, в которых это поле содержит заданное значение.Таким образом, вы получаете индекс, который не превышает количество экземпляров заданного пользователем настраиваемого поля.И вам не нужно настраивать каждое поле для поиска.

...