[SQL]貍貓換太子,解決 SQL Server Express 資料庫上限的問題

[SQL]貍貓換太子,解決 SQL Server Express 資料庫上限的問題

SQL Server 從 2005 版本開始都有提供 SQL Server Express,讓一些比較小型系統可以很方便的來使用,等系統規模作大或者是人數使用者較多之後,可以把資料庫在改掛到 Standard 以上版本,而系統不用做修改就可以繼續使用。

 

SQL Express 版本

容量限制

2005 4GB
2008 4GB
2008 R2 10GB
2012 10GB
2014 10GB

這個部份的細節可以參考德瑞克老師的 Blog

免費無料 SQL Server Express 2005, Royalty Free

SQL Server 2008 Express 版本(Edition)、支援功能、硬體限制

下載 SQL Server 2008 R2 Express:免費版本、硬體限制、支援的功能

問題就從上面的 SQL Server 2005 Express & 2008 Express 的容量限制開始,有朋友遇到在一些比較精簡的環境內,原本使用 SQL Server 2005 Express 都很不錯,但最近因為一些原因,使得資料庫成長了不少,達到了 Express 資料庫容量的上限,但如果要升級到 SQL Server 2008 R2 以上,雖然可以達到 10GB,但又因為要考慮到要重新安裝 .Net Framework 3.5 等因素,沒有辦法進行升級,因此來詢問是否有辦法解決這樣的問題。

 

從上面的表中可以看出,雖然 SQL Server Express 有限制單一資料庫的大小,但沒有限制你不能使用多個資料庫,因此在跟朋友討論的過程中,我們朝向在同一個 Instance 下分散大型資料表到不同資料庫,這樣看起來似乎可以解決問題,但就要程式要改寫去連到不同的資料庫,看起來不是一件小工程,因此我們需要找到一個可以不用改寫程式,卻又可以將資料分散到其它資料庫的方法了。

 

此時我們採用的方式是用 SYNONYM (同義字) 來作解決,這個是微軟在 SQL Server 2005 開始所新增加的功能,詳細語法可以參考 MSDN 上的說明 ( 網址 )。在我們的環境下有幾個資料表,其中一個就佔用了 2.5GB 了,造成我們整個資料庫剩下的空間不足放我們其他的資料表。因此我們希望將這個資料表移到另外的資料庫,但讓原本的程式都可以不用修改就可以執行。

image

因此首先我們先將資料庫分成兩個,主要的資料庫是 SAMPLE,將上述的一個大資料表移到 DEMO 資料庫,為了要能完成這樣的處理,我先用 BCP 將資料表匯出,然後再用 BCP 匯入到新的資料庫內,並且使用 TRUNCATE 將在 SAMPLE 資料庫的該資料表給刪除。

image

 

完成之後我們使用以下的指令建立 SYNONYM

   1: USE [SAMPLE]
   2: GO
   3: CREATE SYNONYM [dbo].[BigTable] FOR [DEMO].[dbo].[BigTable]
   4: GO


或者是在 SSMS 內使用 GUI 命令來設定

image

 

此時可以透過 SSSMS 看到會在同義字的地方看到剛剛所建立的

image

 

此時我們下指令來測試看看,透過下面的指令可以看到,我們在 SAMPLE 的資料庫,下指令查自己資料庫內的 dbo.BigTable,他會正常取得 DEMO 資料庫內的 dbo.BigTable 的資料表內的資料

image

 

有朋友擔心那這樣會不會在該資料表上有設定索引或者是一些限制會不會運作,那以下我們用執行計畫來看指令的執行,從下面兩圖中可以看出來,如果資料表上有設定索引,那麼 SQL 也會去使用,並不用擔心 SQL Server 會把全部資料撈進來在做處理。

image

image

 

討論到這裡,朋友也談到那如果我不採用 SYNONYM 而使用 VIEW 來作模擬呢 ? 也就是在 SAMPLE 資料庫下用類似以下的指令來建立一個 VIEW

   1: CREATE VIEW dbo.BigTable2 
   2: AS
   3: SELECT * FROM DEMO.dbo.BigTable

 

再來做個比較,看起來一般的操作都沒有問題,也都可以使用 DML 指令來操作

image

 

但因為這兩個都不是實際的 TABLE , 因此一般的 DML 操作雖然可以,但如果你要 TRUNCATE TABLE 的話,那就可能還是要調整一下程式,要到實際的 DEMO 資料庫下才能進行操作

image

 

而這兩個都可以使用的狀況下,我個人會比較偏好使用 SYNONYM 來處理,畢竟會比較容易理解。但如果在實際環境中,您是可以按照你的需求去選擇要用哪個,但這裡可能要特別注意的就是權限,因此當你設定使用者對這個資料庫操作的時候,如果把部份資料表放到其他資料庫內的時候,要記得設定相關使用者,也要在對應資料庫中具有權限,這樣才不會造成無法讀取的問題。

image

 

最後的解決方案雖然沒有辦法 100% 都不用修改,但至少可以透過這樣省下不少改寫的功夫,雖不滿意但也可以接受了。