динамическая модель данных

У меня есть проект, который требует пользовательских атрибутов для конкретного объекта во времени выполнения (Позволяет, говорят что объект человека в этом примере). Проект будет иметь многих различных пользователей (1000 +), каждый определяющий их собственные уникальные атрибуты для их собственных наборов объектов 'Человека'.

(Например, - у пользователя № 1 будет ряд определенных атрибутов, которые будут относиться ко всем объектам человека, 'принадлежавшим' этому пользователю. Mutliply это 1 000 пользователей, и это - число минимума нижней строки пользователей, с которыми будет работать приложение.) Эти атрибуты будут использоваться для запросов людей, возражают и возвращают результаты.

Я думаю, что это возможные подходы, которые я могу использовать. Я буду использовать C# (и любая версия.NET 3.5 или 4), и иметь ре полной свободы: что использовать для хранилища данных. (У меня есть mysql и mssql доступный, хотя имеют свободу использовать любое программное обеспечение, пока это будет отвечать всем требованиям),

Я пропустил что-нибудь или сделал какие-либо неправильные предположения в моей оценке?

Из этого выбора - для какого решения Вы пошли бы?

  1. Гибридная объектная модель EAV. (Определите базу данных с помощью нормальной реляционной модели и имейте таблицу 'набора свойств' для таблицы Person).

    Оборотные стороны: много соединений на / запрос. Низкая производительность. Может поразить предел количества соединений / таблицы, используемые в запросе.

    Я поднял быстрый образец, который имеет Дозвуковое 2.x 'esqe интерфейс:

    Select().From().Where  ... etc
    

    То, которое генерирует корректные соединения, затем фильтрует +, вертится возвращенные данные в c#, для возврата таблицы данных, настроенной с правильно введенным набором данных.

    У меня есть все же к нагрузочному тесту это решение. Это основано на совете EA в этом техническом описании Microsoft: лучшие практики SQL Server 2008 RTM Документов для Семантического Моделирования данных для Производительности и Масштабируемости

  2. Позвольте пользователю динамично создавать / изменяют таблицу объекта во времени выполнения. Это решение - то, что я полагаю, что NHibernate делает в фоновом режиме при использовании динамических свойств, как обсуждено где

    http://bartreyserhove.blogspot.com/2008/02/dynamic-domain-mode-using-nhibernate.html

    Оборотные стороны:

    Когда система растет, число определенных столбцов станет очень большим, и может поразить макс. число столбцов. Если бы существует 1 000 пользователей, каждый с 10 отличными атрибутами для их объектов 'Человека', то нам была бы нужна таблица, содержащая 10k столбцы. Не масштабируемый в этом сценарии.

    Я предполагаю, что мог позволить таблицу атрибутов человека на пользователя, но если существует 1 000 пользователей для запуска, это - 1 000 таблиц плюс другие 10, нечетные в приложении.

    Я не уверен, если это было бы масштабируемо - но это не кажется так. Кто-то исправьте меня если я неправильное!

  3. Используйте хранилище данных NoSQL, такое как CouchDb / MongoDb

    Из того, что я читал, они еще не доказаны в крупномасштабных приложениях, на основе строк, и очень ранние в этапе разработки. ЕСЛИ я являюсь неправильным в этой оценке, кто-то может сообщить мне?

    http://www.eflorenzano.com/blog/post/why-couchdb-sucks/

  4. Используя столбец XML у людей таблица для хранения атрибутов

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

  5. Сериализация графа объектов к базе данных.

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

  6. Привязка C# для berkelyDB

    Из того, что я читал здесь: http://www.dinosaurtech.com/2009/berkeley-db-c-bindings/

    Дб Беркли, определенно оказалось, был полезен, но как Robert, на которого указывают – нет никакого легкого интерфейса. Ваши все ДОБИВАЮТСЯ обертки, должна быть рука, кодированная, и все Ваши индексы являются сохраняемой рукой. Это намного более трудно, чем SQL / linq-to-sql, но это - цена, которую Вы платите за смешную скорость.

    Кажется большими издержками - однако, если кто-либо может предоставить ссылку на учебное руководство о том, как поддержать индексы в C# - это мог быть посетитель.

  7. SQL / гибрид RDF. Нечетный я не думал об этом прежде. Подобный опции 1, но вместо таблицы "набора свойств", просто XREF к хранилищу RDF? Запросы были бы их включать 2 шага - запрашивают хранилище RDF для людей, поражающих корректные атрибуты, чтобы возвратить объект (объекты) человека и использовать идентификатор для них объект человека в SQL-запросе для возврата реляционных данных. Дополнительные издержки, но мог быть посетитель.

19
задан Cœur 14 March 2018 в 10:59
поделиться

4 ответа

Движок базы данных ESENT в Windows в значительной степени используется для такого рода полуструктурированных данных. Одним из примеров является Microsoft Exchange, который, как и ваше приложение, имеет тысячи пользователей, где каждый пользователь может определить свой собственный набор свойств (MAPI назвал свойства). Exchange использует слегка модифицированную версию ESENT.

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

В этом случае вы можете иметь по одной таблице на пользователя и создавать в таблице столбцы для каждого пользователя, создавая индексы для любых столбцов, которые вы хотите запросить. Это будет похоже на то, как некоторые версии Exchange хранят свои данные. Недостатком такого подхода является то, что ESENT не имеет движка запросов, поэтому вам придется вручную обрабатывать ваши запросы в виде MakeKey/Seek/MoveNext вызовов.

Управляемая обертка для ESENT находится здесь:

http://managedesent.codeplex.com/

7
ответ дан 30 November 2019 в 05:18
поделиться

В модели EAV вам не нужно иметь много объединений, так как вы можете просто иметь присоединения, которые вам нужны для фильтрации запроса. Для результатов, возвращайте записи недвижимости как отдельный rowset. Это то, что мы делаем в нашей реализации EAV.

Например, запрос может вернуть людей с расширенной недвижимостью «Возраст»> 18:

Таблица свойств:

1        Age
2        NickName

Первые результаты:

PersonID Name
1        John
2        Mary

Вторые Resultset:

PersonID PropertyID Value
1        1         24
1        2         'Neo'
2        1         32
2        2         'Pocahontas'

Для первых результатов вам нужен внутренний Присоединиться к расширенной недвижимости «Возраст» Чтобы запросить часть объекта объекта Basic Person:

select p.ID, p.Name from Persons p
join PersonExtendedProperties pp
on p.ID = pp.PersonID
where pp.PropertyName = 'Age'
and pp.PropertyValue > 18 -- probably need to convert to integer here

для второго призыва мы делаем внешнее соединение первых результатов с таблицей PersonextendedStoneS, чтобы получить остальные расширенные свойства. Это «узкие» результаты, мы не винтифицируем свойства в SQL, поэтому нам не нужно несколько присоединиться здесь.

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

2
ответ дан 30 November 2019 в 05:18
поделиться

Моя рекомендация:

Разрешить свойства быть помечены как индексируемые. Имейте небольшой жесткий предел по количеству индексируемых свойств и на столбцах на объект. Имейте большой жесткий предел на полных типах столбцов во всех объектах.

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

Сериализация данных, включая столбцы индекса, плюс поставьте индекс Propertoes в реляционные колонны первого класса в их выделенных таблицах индекса. Используйте JSON вместо XML, чтобы сохранить место в таблице. Обеспечить выполнение политики NAME CONLEPON (или длительное отображение и короткое хранилище политики ИМЯ) для экономии места и повышения производительности.

Используйте кварки для идентификаторов полей (но только в главном двигателе, чтобы сохранить оперативную память и скорость некоторые операции чтения - не полагайтесь на сравнение указателя QUARK во всех случаях).

Моя мысль о ваших вариантах:

1 - это возможным. Производительность ясно будет ниже, чем если столбцы поля поля не сохраняются.

2 - нет в общих двигателях БД не все довольны изменениями динамической схемы. Но возможно, да, если ваш двигатель БД хорош в этом.

3 возможно.

4 Да, хотя я бы использовал JSON.

5 кажется, что 4 только менее оптимизированы ??

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

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

Редактировать: Изменена последняя редактирование формулировки.

0
ответ дан 30 November 2019 в 05:18
поделиться

Предполагая вам место ограничение, N, на сколько пользовательских атрибутов каждый пользователь может определить; Просто добавьте дополнительные столбцы на таблицу человека. Тогда имейте отдельную таблицу, в которой вы храните метаданные для каждого пользователя, чтобы описать, как интерпретировать содержимое этих столбцов для каждого пользователя. Похоже на # 1, как только вы прочитаете данные, но не нужно присоединиться к пользовательским атрибутам.

0
ответ дан 30 November 2019 в 05:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: