天天看點

SqlServer 垂直分表

當單表資料太多時。我們能夠水準劃分,參考

sqlserver 分區視圖實作水準分表 ,水準劃分能夠提高表的一些性能。

而 垂直分表 則相對非常少見到和用到,由于這可能是資料庫設計上的問題了。假設資料庫中一張表有部分字段差點兒從不不更改但常常查詢,而部分字段的資料頻繁更改。這樣的設計放到同一個表中就不合理了,互相影響太大了。在已存在改情況的表的時候,能夠考慮按列拆分表,即垂直拆分。

由于垂直分表的案例比較少,近期由于存在這種表,是以個人搗鼓了一下。

源表設計結構:

注:拆分後各表的主鍵都是同樣了。并且拆分後的表是規範化的。

如今拆成兩張表:

注意選擇一張表作為基表,其它表都有與該表的外鍵。

假設之前是對單個表或者視圖操作。拆分之後邏輯層修改可能非常多。為保持修改最小,能夠用聯合視圖操作。怎麼連接配接表依個人情況而定。

這時問題來了,要對表進行dml操作。insert , update , delete 怎麼解決?由于要求主鍵是分散在多個表而且是同樣的。

這時僅僅能用考慮觸發器來保證一緻性了,觸發器則定義在視圖上,使用的是 instead of 類型的觸發器。

insert 觸發器:

視圖 [vdemotab] 中的 [guid] 為表 插入時值。在插入觸發器中,虛拟表[inserted]的[guid]是唯一的。是以在觸發器中能夠同一時候使用該 [guid] 插入到多個分表中,保證了多個分表的[guid]是同樣的。

update 觸發器:

同理,更新時涉及虛拟表 deleted 和 inserted,而更新是對視圖[vdemotab]更新的,是以虛拟表inserted包含了全部的字段,是以須要觸發器分别更新多個分表。

delete 觸發器:

删除視圖[vdemotab]記錄,涉及多個表則不同意删除,是以僅僅要删除"主表"的記錄就可以。其它分表都會級聯删除。

設計基本就完畢了,如今進行測試。

基本操作都是正常的!垂直分表完畢!

性能怎麼樣呢?

因為 guid 作為主鍵,使用的是 newid() 而不是  newsequentialid(),新增記錄時聚集索引都可能又一次排序較多資料。

分表之後,單個資料頁能存儲的資料很多其它了,可是分成多個表中,資料頁也增多了,同一時候 guid 在每一個表都存在,是以查詢資料時io會很多其它。

對于更新資料。在觸發器中是兩個表同一時候更新的。即使更新當中一個分表,其它分表都會影響。

假設分表之後不同一時候更新。能夠在觸發器中使用 if(update(col)) 來推斷更新的是那一列,就更新對應的基表即可,其它分表不更新。

最好的情況就是,拆分後的表都是“獨立”的。不用聯合視圖,查詢和更改都獨立,這須要更改邏輯層。

本文出自“hello.kk (sql server)”的部落格,轉載請務必保留此出處javascript:void(0)/article/details/46740315