Есть ли способ создать вложенные базы данных в виде подпапок в SQL Server? - PullRequest
1 голос
/ 20 мая 2010

Я создаю приложение, в котором есть основная БД и где другие данные хранятся во вторичных базах данных. Вторичные базы данных следуют «плагиновому» подходу. Я использую SQL Server.

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

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

MainDB и плагины БД имеют абсолютно одинаковую схему (в основном, плагины БД имеют некоторое «специальное содержимое», некоторые важные данные, которые можно использовать в качестве шаблона - например, шаблон письма - в приложении). Базы данных плагинов используются в режиме «только чтение», они являются «хранилищем контента». «Умная» вещь заключается в том, что основное приложение может также использоваться «создателями плагинов», они просто пишут БД, вставляя содержимое, и, делая резервную копию базы данных, они создают потенциальный плагин (поэтому все БД имеют одинаковые схемы).

Эти плагины DB загружаются из Интернета, так как доступно обновление контента, каждый раз, когда полная база данных плагина уничтожается, и создается новая с тем же именем creaetd. Это для простоты и даже потому, что размер этих БД, как правило, невелик.

Теперь это работает, в любом случае, я бы предпочел организовать БД в виде древовидной структуры, чтобы можно было заставить БД подключаемых модулей быть «суб-БД» основной БД приложения.

В качестве обходного пути я думаю об использовании правил именования, таких как:

ApplicationDB (для основной базы данных приложений)

ApplicationDB_PlugIn_N (для N-го плагина БД)

Когда я ищу плагин 1, я пытаюсь подключиться к ApplicationDB_PlugIn_1, если я не нахожу БД, я выдаю ошибку. Такая ситуация может возникнуть, например, если сом DBA переименован в ApplicationDB_Plugin_1.

Так как эти подключаемые БД действительно зависят только от ApplicationDB, я пытался «сделать трюк с подпапками».

Может кто-нибудь предложить способ сделать это? Можете ли вы прокомментировать этот самодельный подход к плагину, который я описал выше?

ДОБАВЛЕННАЯ ИНФОРМАЦИЯ (ПОСЛЕ НАЧАЛА РАБОТЫ):

В MainDB я планирую хранить информацию о подключении ко всем базам данных плагинов. По сути, это имя базы данных, так как я разработал систему таким образом, что даже если я использую несколько учетных записей сервера sql для доступа к MainDB, за кулисами один пользователь (обычно «sa» или другой пользователь с правами администратора).

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

Так что как-то так работает, в основной БД я храню названия БД плагинов. Итак, я знаю название плагинов, поэтому, если я хочу запросить все GUNS из всех плагинов, я сделаю что-то вроде этого:

select * from ApplicationDB_Plugin_1.dbo.weapons where weapon_type = 'gun'
union
select * from ApplicationDB_Plugin_2.dbo.weapons where weapon_type = 'gun'
union
select * from ApplicationDB_Plugin_3.dbo.weapons where weapon_type = 'gun'

так что «трюк» использует имя db для различения плагинов. Сейчас эта работа, но она кажется мне немного «грязной». Мой вопрос: "ЛУЧШЕ ЛИ ПОДХОД, КОТОРЫЙ ВЫ МОЖЕТЕ ПОСЕТИТЬ?"

Ответы [ 3 ]

6 голосов
/ 20 мая 2010

Вы можете использовать схемы:

CREATE TABLE mytable (id INT)
GO

CREATE SCHEMA plugin_schema
CREATE TABLE mytable (id INT)
GO

SELECT  *
FROM    dbo.mytable -- selects from the first one

SELECT  *
FROM    plugin_schema.mytable  -- selects from the second one
2 голосов
/ 26 мая 2010

Если схемы идентичны, можете ли вы что-то добавить к существующим таблицам, чтобы можно было сказать, что некоторые данные получены из плагина-1, а другие - из плагина-2? Возможно, в будущем вы обнаружите необходимость выполнять кросс-плагин-запросы?

1 голос
/ 28 мая 2010

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

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

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

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

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

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

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

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

  • сервер баз данных выполняет только один запрос вместо одного для плагина

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

  • наконец, и самое главное, на мой взгляд, управление изменениями схемы становится возможным. Если есть плагины, которые не реализовали ваши последние изменения схемы, процесс слияния может адаптировать данные, хранящиеся с использованием старой схемы, в то время как он копирует данные плагина в составную базу данных (которая всегда использует латентную схему). Например, при копировании плагин, использующий старую схему, значения по умолчанию могут быть добавлены для новых столбцов, могут быть внесены изменения в структуру, столбцы / строки могут быть удалены и т. д. Тот же код «обновления схемы» также может быть предоставлен разработчикам плагинов, чтобы позволить им обновить их схема плагина.

Процесс слияния может также создать таблицу «instal_plugins», в которой перечислены все плагины, которые копируются в составную базу данных. Таблица содержит метаданные о каждом плагине, такие как дата обновления плагина, время добавления, уникальный идентификатор плагина и т. Д.

Итак, как выглядит составная база данных:

  1. Данные плагина хранятся в виде отдельных таблиц с использованием представления для их объединения. Представление представляет собой объединение соответствующей таблицы из каждого плагина плюс столбец для идентификатора плагина. Это будет работать, но вряд ли будет эффективным.
  2. Данные плагина для данного типа таблицы хранятся вместе. Ссылочную целостность гораздо проще поддерживать, а запросы будут выполняться быстрее, поскольку общий индекс может использоваться для всех плагинов.

Я предпочитаю второй вариант. Но когда все данные плагина хранятся вместе, как узнать, из какого плагина поступает каждая строка? Опять есть два варианта:

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

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

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

Удачи, какой бы путь вы ни выбрали!

...