2009-04-05 2 views
8

Я был бы признателен за некоторые мнения относительно беспокойства, которое у меня есть.Вопрос по дизайну базы данных

У меня есть [User] стол в моей базе данных, с основной материал можно было ожидать, как имя пользователя, пароль и т.д. ...

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

У меня возникает соблазн добавить таблицу UserProperties с столбцами UserID, PropertyKey и PropertyValue. Этот подход хорошо согласуется с требованиями.

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

Я бы подумал, что с кластеризованным индексом на UserID этот доступ будет по-прежнему быстро кричать, и вы действительно храните около того же объема данных, что и при использовании метода мега-столбцов.

Любые идеи или мысли о производительности? Идеи для лучшего дизайна БД?

Спасибо!

UPDATE:

Во-первых, спасибо за все великие ответы!

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

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

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

ответ

11

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

Таблицу E-A-V можно легко найти. Проблема заключается не в поиске строк, а в поиске соответствующих строк.

Наличие разных таблиц для разных объектов обеспечивает моделирование домена, но они также обеспечивают слабую форму метаданных. В E-A-V таких абстракций нет. (Аналогия Java с EAV будет объявлять, что формальные аргументы всех функций имеют тип Object, поэтому вы не должны проверять тип.)

Мы можем легко найти ключи свойств, но ничто не группирует эти свойства ключи.

В Википедии есть очень хорошая статья о E-A-V, но прочитайте ее сейчас - это, в основном, работа одного автора и намечена на «улучшение».

+0

Я больше не мог согласиться. Модель Entity-Relational является мощной, когда вы получаете ручку на ней. Я чувствую к бедному парню, который наследует базу данных с сущностями, сплюснутыми в пары имя/значение, и должен делать головы или хвосты. –

3

Подход таблицы UserProperties - это то, как я смогу ее моделировать. Как вы предположили, кластеризованный индекс для userID будет означать, что поиск по диапазону в userID будет быстрым (т. Е. Для всех свойств, относящихся к одному пользователю). Можно также добавить некластеризованный индекс для UserID и PropertyKey для выбора одного ключа-2 для каждого пользователя.

1

Сомневаюсь, что в таблице «Пользователи» будет так много значений данных «1 к 1», что вы закончите пространство строк. Вы должны только выгружать значения 1-ко-многим в другую таблицу, используя идентификатор пользователя в качестве внешнего ключа. Мне маловероятно, что вашей таблице пользователя потребуется столько полей VARCHAR(), которые не могут быть превращены в FK из главной таблицы значений. Какие пользовательские атрибуты вы поддерживаете?

1

Любой способ логически сгруппировать свойства? Вы не всегда можете получить доступ к каждой собственности. Кроме того, если они логически сгруппированы, будет легче понять, какие свойства доступны, где новые свойства подходят и т. Д.

Группы могут иметь отношение один к одному или одно к одному с пользователь ...

+0

Группировка может быть добавлена ​​добавлением groupID в таблицу UserProperties –

+0

Митч, я не думаю, что это была точка. Я думаю, что нужно было сократить размер стола. – mpen

+0

«Правые» индексы делают размер таблицы меньше проблемы –

1

Мы реализовали стратегию UserProperties в нескольких проектах.Это общий шаблон и с соответствующими индексами мы никогда не сталкивались с проблемой производительности.

Другим преимуществом является то, что при необходимости можно управлять двумя или более таблицами свойств для управления доступом пользователей. Например, общие свойства могут быть в таблице PublicUserProps, в то время как конфиденциальная информация (я не знаю, что вы храните, но ssn, информация о зарплате и т. Д.) Может находиться в таблице ControlledUserProps, которой только некоторые пользователи могли бы читать или редактировать прав.

1

Мне нравится метод мета-стола, который описал Митч Пшеница. Но если у вас есть несколько полей, которые будут использоваться чаще, чем другие (например, имя и т. Д.), Вы можете обнаружить, что наличие в таблице «Пользователь» может быть полезным, а затем привязать таблицу пользователя к UserProperties. Я думаю, все зависит от конкретных деталей вашего дизайна.

+0

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

1

Несколько вариантов я могу думать:

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

, учитывая указанные ограничения, я не думаю, у вас действительно есть другой выбор!

нормально, вы могли бы расколоть атрибуты пользователя по нескольким таблицам обмен же UserId в качестве основного ключа (и кластерный индекс), но это может быть или не может улучшить производительность

если вы только говорите о 100 атрибутов , это может быть обработано одной таблицей (в MS-SQL max - 1023 неявных столбцов); если атрибуты только частично заполнены, то таблица атрибутов пользователя может потенциально быть более экономичной (только ваш профилировщик точно знает)

1

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

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

Мой совет - попытаться поместить все это в один стол, а затем запустить его с некоторыми тестовыми данными. IF не работает, тогда вы можете пойти по пути решения нескольких таблиц или даже не-db-решение (в конце концов, это не серебряные пули).

7

Я рекомендую вам рассмотреть подход, известный как вертикальное разбиение. Это означает, что вы продолжаете определять таблицы с помощью ключа UserID, вы можете называть их User1, User2 и т. Д. Запустите новую таблицу, когда вы нажмете максимальный размер строки для своей базы данных. Преимущество этого подхода в том, что значения по-прежнему являются истинными атрибутами базы данных. Это приведет к экономии времени при работе с этими данными, например. привязка данных.

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

Если, с другой стороны, требуется гибкая система атрибутов, то непременно следует использовать систему свойств/свойств. Например, если пользователям было разрешено динамически определять свои атрибуты, то вам определенно нужна система key/value. Тем не менее, я бы сказал, что ключ/ценность - это не лучший способ, если вы понимаете структуру своих данных и на законных основаниях идентифицировали сотни атрибутов для пользователей.

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

Смежные вопросы