2010-05-20 65 views
1

我正在創建一個應用程序,其中有主DB和其他數據存儲在輔助數據庫中。輔助數據庫遵循「插件」方法。我使用SQL Server。有沒有辦法在sql server中創建子數據庫作爲一種子文件夾?

一個簡單的應用程序安裝將只有mainDB,而作爲一個選項可以激活更多的「插件」,並且每個插件都會有一個新的數據庫。

現在爲什麼我做這個選擇是因爲我必須使用一個現有的遺留系統,這是我可以實現插件系統的最聰明的事情。 (基本上插件數據庫有一些「特殊內容」,一些可用作模板的重要數據 - 例如在應用程序中以信函模板的形式考慮)。插件數據庫只在readonly模式下使用,它們是「內容存儲庫」。這個「聰明」的事情是主應用程序也可以被「插件編寫者」使用,他們只是編寫一個數據庫插入內容,並且通過備份數據庫創建一個潛在的插件(這就是爲什麼所有數據庫都具有相同的插件模式)。

這些插件數據庫是從互聯網上下載的,因爲有內容升級可用,每當完整的PlugIn數據庫被銷燬並且一個新名稱被創建時就會被創建。這是爲了簡單,甚至因爲這些數據庫的大小通常很小。

現在這個工作,無論如何,我寧願組織一種樹結構的數據庫,以便我可以強制插件數據庫是主應用程序數據庫的「子數據庫」。

作爲一種變通方法,我想使用的命名規則,如:

ApplicationDB(主應用程序DB)

ApplicationDB_PlugIn_N(對於第N個插件DB)

當我搜索對於插件1我試圖連接到ApplicationDB_PlugIn_1,如果我沒有找到數據庫我提出了一個錯誤。例如,如果som DBA重命名爲ApplicationDB_Plugin_1,則可能發生這種情況。

所以,既然這些插件DB真的依賴於ApplicationDB,我只是試圖「做子文件夾技巧」。

任何人都可以提出一種方法來做到這一點?你能評論一下我上面描述的這種自制的插件嗎?

ADDED INFO(後開始BOUNTY):

在MainDB我打算存儲的連接信息到所有的插件數據塊。基本上它是數據庫名稱,因爲我以一種即使我使用多個sql server登錄名訪問MainDB,一個用戶(通常是「sa」或具有管理員權限的其他用戶)在幕後的方式設計系統。

因此,基本上如果我需要查詢多個數據庫,我將使用數據庫名來區分插件,我不需要在數據庫表中顯式創建名爲PluginID的文件。

因此,不知何故,它的工作原理是這樣的,在主DB中存儲插件數據庫名稱。所以我知道插件的名稱,所以如果我想查詢所有從所有插件的槍,我會做這樣的事情:

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' 

使「絕招」是使用DBNAME插件區別開來。現在這項工作,但對我來說似乎有點「骯髒」。我的問題是「你有更好的方法可以設想嗎?」

+0

@ user193655:你的交叉DB-UNION'骯髒'正是我的建議所避免的。你在尋求更好的方法,這就是我所建議的。 – n8wrl 2010-05-27 11:43:01

+0

問題:您聲明「MainDB和插件數據庫具有完全相同的模式」。例如:「ApplicationDB.dbo.weapons」是否具有「Application_Plugin_x.dbo.weapons」的Idential結構? – 2010-05-28 17:16:15

+0

是的,它們是一樣的。一個簡單的例子是:假設有4個NorthWind數據庫。一個是MainDB,另外三個是插件DB。這是它的工作原理。 – LaBracca 2010-05-31 07:46:44

回答

1

我可以理解你是如何得到你目前的解決方案的。保持數據庫的獨立性可以明確哪些數據屬於每個插件,並保持獨立的關注點。

雖然通過簡單的機構提供明晰,這種方法有一些相當顯著缺點:

  • 連接到不同的數據庫爲每個插件不會是臉。數據庫服務器將運行查詢N次來查詢N個插件,因爲它必須針對每個插件的單獨數據庫運行每個查詢。

  • 參照完整性不易在多個數據庫中實施(如果有的話),所以很可能您的數據可能會變得不一致。

  • 降低靈活性和「活力」:創建一個新的數據庫相當繁重的操作,因此添加一個新的插件變得相當繁重的操作。

  • 最後,處理模式更改將很困難 - 如果您的插件尚未更新到最新模式,那麼由於假定所有數據庫具有相同的結構,因此無法在此模式中使用。

我建議一種混合的方法:每個插件繼續保持它自己的數據庫,可以下載,並在運行時加載,而不是保持在不同的數據庫應用程序和插件,該插件的數據和應用程序DDATA被複制到組合數據庫。組合數據庫可以在啓動時或插件集發生更改時或新的插件版本可用時生成。這是可行的,因爲你提到每個插件數據庫只讀,而不是更新。 (重建數據庫可以做到使得在複合數據庫的應用程序的數據被保留。)

當從插件應用程序數據和該數據被集成到一個數據庫,則避免上述問題:

  • 數據庫服務器執行,因爲所有的數據都保存在一個數據庫只是一個查詢,而不是每個插件一個

  • 引用完整性是強制執行的。

  • 最後,最重要的是,在我看來 - 管理模式更改成爲可能。如果有插件沒有實現最新的模式更改,則合併過程可以調整使用舊模式存儲的數據,同時它將插件數據複製到複合數據庫(它總是使用latet模式)。例如,在複製一個使用舊模式的插件,可以爲新列添加默認值,可以調整結構的變化,可以刪除列/行等。也可以向插件開發人員提供相同的「模式升級」代碼,以允許他們升級他們的插件架構。

合併過程還可以構建一個列出所有插入複製到組合數據庫的插件的「installed_plugins」表。表中包含的每個插件,如插件更新的日期元數據,添加時間,獨特的插件ID等

那麼,什麼是複合數據庫是這樣的:存儲爲獨立的表

  1. 插件數據,使用將它們結合起來的視圖,該視圖將是每個插件的對應表的聯合,以及插件ID的列。這會起作用,但不太可能有效。
  2. 給定表類型的插件數據全部存儲在一起。由於可以在所有插件中使用通用索引,參照完整性維護起來要容易得多,查詢速度也會更快。

我的偏好是第二種選擇。但是,將所有插件數據存儲在一起,如何知道每行來自哪個插件?再次有兩種選擇:

  1. 使用插件ID /名稱向表中添加一列。優點是速度很快。缺點是它改變了基礎模式。
  2. 對於每個表,都有一個伴隨表,它將行ID映射到數據源自的插件ID。這會稍微慢一些,但是可以保持核心數據表的架構免於更改。

爲了簡單起見,我的偏好是1,添加一個ID列。由於組合數據庫中的表由腳本或程序構建,因此任一方案都很容易實現,因此主要關注首選項或性能需求,或者重要的是合併數據庫對核心數據表使用相同的模式原始應用數據庫。

我覺得將數據合併在一起是正確的方法,可以減少疼痛,簡化維護,靈活性和提高性能。但是,如果你仍然有強烈的動機將數據保存在單獨的表中,那麼至少應將它們保存在同一個數據庫中,並使用表名前綴或更好的模式名來保持插件數據名稱空間的分離。

祝你好運,這是你選擇的方式!

+0

謝謝,這個問題真的試圖解決我的問題。我真的覺得你明確地解決了這個問題。我會關閉賞金並接受這個不錯的答案。我不會100%接受它,但混合方法是驚人的。重建數據庫對我來說不是一種選擇,但保留只讀數據庫並將數據合併到應用程序數據庫(無需構建新數據庫)的想法確實改進了我的方法。唯一仍未解決的問題是推薦誠信。這不是一個真正的問題,因爲我不會允許FK插入記錄,因爲它們在每次插件更新時都被銷燬並重新創建。 – LaBracca 2010-05-31 07:39:14

6

您可以使用模式:

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

+1 SQL中一個未被充分利用的特性服務器! – 2010-05-20 10:54:39

+0

你的意思是我可以通過設置plugin_schema而不是dbo來恢復數據庫嗎?當我做備份時,所有表都有dbo。做這種恢復有可能嗎?我的意思是在現有的數據庫上還原另一個數據庫的備份並設置不同的模式? – LaBracca 2010-05-20 12:13:42

+0

您可以刪除架構對象並在更新腳本中重新創建它們。但請注意,在刪除架構之前,應刪除所有架構對象。只要每個開發人員爲其插件使用唯一的模式名稱,就可以消除插件名稱衝突的可能性。 – Quassnoi 2010-05-20 12:17:06

2

如果架構是相同的,你能添加一些現有的表,所以你可以告訴大家,有些數據是從插件-1,而其他數據是來自塞-in-2?你可能會發現未來需要做'跨插件查詢'嗎?

+1

這是一個很好的方法,因爲你說模式是相同的。在所有相關表上放置一個「PLUGINID」列,併爲主應用程序使用值0,併爲每個插件增加值。你甚至可以將它標準化爲與PLUGINS表的關係,在那裏你可以存儲插件Name,Author,LastUpdatedDate和其他相關信息。 – eidylon 2010-05-26 16:36:08

+0

我在問題中添加了新的部分。如果你讀到這可能很明顯,你建議我只是使我的方法複雜化。我已經有了一種方法來區分插件,我只是在尋找更好的方法。謝謝。 – LaBracca 2010-05-27 07:33:10

相關問題