SQL Server дизайн базы данных - PullRequest
       3

SQL Server дизайн базы данных

1 голос
/ 29 апреля 2011

Я планирую создать сайт с использованием ASP.NET и SQL Server. Тем не менее, мой план проектирования базы данных заставляет меня задуматься, есть ли лучший способ.

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

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

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

User1 Tables - TransactionTable_Key1, AssetTable_Key1, ResearchTable_Key1 ....;
User2 Tables - TransactionTable_Key2, AssetTable_Key2, ResearchTable_Key2 ....; 

Значения Key1, Key2 и т. Д. Будут получены на основе данных MembershipID при создании учетной записи. Это может привести к очень большому количеству таблиц с течением времени. Я не уверен, ограничит ли это масштабируемость, настроив базу данных таким образом. Любые рекомендации?

Редактировать: Я должен отметить, что некоторые из этих таблиц будут содержать более 20 000 строк

Ответы [ 6 ]

3 голосов
/ 29 апреля 2011

Ваш уровень ORM (код EF, LINQ, DAL) не будет иметь необходимости иметь дело с одним набором таблиц на каждого арендатора. Гораздо лучше иметь либо один набор таблиц для all арендатора в одной базе данных, либо отдельную базу данных для каждого арендатора. Последнее лучше только в том случае, если обновление схемы должно проверяться арендатором (как это делает Salesforce.com). Если вы можете позволить себе сразу обновить всех арендаторов до новой схемы, то для каждого арендатора нет никаких оснований.

Когда вы разрабатываете схему с несколькими арендаторами, важно помнить:

  • не используйте кучи, все таблицы должны иметь кластеризованный индекс
  • добавить идентификатор арендатора в качестве крайнего левого ключа к каждые кластеризованные
  • добавить идентификатор арендатора в качестве крайнего левого ключа к каждый тоже некластеризованный индекс
  • добавить предикат Left.tenantID = right.tenantID к каждому объединению
  • добавить table.TenantID = @currentTenantID в каждый запрос

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

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

3 голосов
/ 29 апреля 2011

Реально это звучит так, как будто вам действительно нужна только одна база данных для этого.

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

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

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

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

2 голосов
/ 29 апреля 2011

Вы определенно не хотите создавать набор таблиц для каждого пользователя, и вы хотели бы, чтобы они были только в одной базе данных.Даже с большой емкостью SQL Server 2008 для таблиц (обратите внимание на общее количество объектов в базе данных), он быстро станет неуправляемым.Лучше всего использовать 20 таблиц и разделить их с помощью столбца на пользовательские области.Возможно, вы захотите разделить таблицы по этому пользовательскому значению, но это также следует проверить по соображениям производительности.

2 голосов
/ 29 апреля 2011

Да, поскольку таблицы содержат только идентификатор, ключ и значение, почему бы не создать одну таблицу?

Есть столбцы: идентификатор, идентификатор пользователя, ключ, значение

Поместите индекс в поле идентификатора пользователя.

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

Ура, Daniel

1 голос
/ 29 апреля 2011

Сложно сказать по сводке, но похоже, что вы разрабатываете динамическую атрибуцию пользователем.Этот подход к разработке называется EAV (Entity-Attribute-Value) и состоит из простого базового ключа коллекции (UserID, SiteID, ProductID ...) и затем строк, состоящих из пар имя / значение.В более сложной версии категории иногда добавляются в виде «супер-столбцов» в кортеж / строку и предоставляют подгруппы для набора пар имя / значение.

Проектирование таким образом перемещает ответственность за целостность типа данныхреляционная целостность и целостность кортежа на прикладном уровне.

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

Если вы хотите внедрить модель EAV, я бы посоветовал вампосмотрите на нереляционное решение (nosql), такое как MongoDB или CouchDB.Эти хранилища позволяют разработчику сохранять и извлекать «документы» или сообщения в формате json, которые по существу состоят из набора пар имя / значение и могут очень похожи на сериализованный объект.Преимущество в том, что вы можете хранить динамическую атрибуцию, не нарушая ваш кортеж.Вы всегда знаете, что у вас есть полный кортеж, потому что вы можете хранить и извлекать его как единый «блок» информации, который можно сериализовать и десериализовать по желанию.Вы также можете обновить отдельные атрибуты в кортеже, если это вызывает проблемы.

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

Надеюсь, это поможет.

1 голос
/ 29 апреля 2011

Нил,

Решение действительно зависит от ваших требований.Если безопасность и доступ к данным вызывают беспокойство, и у вас есть только несколько пользователей, вы можете установить разные БД для каждого пользователя, для которого доступ к нему установлен только для его / ее базы данных.Это хорошая альтернатива, когда у вас есть одна БД и таблицы, разбитые на индексированные столбцы, разделяющие строки данных пользователей.

...