如果你有先見之明的話,會給表名,預存程序的名字加上首碼,例如論壇表命名為BBS_xxx,部落格表命名為BLOG_xxx;這樣的話在分表處理時會比較容易一些。說到這兒也許你會想到外鍵約束怎麼辦,我的部落格表,論壇文章表都有用了User表的主鍵做外鍵呀。這個很容易處理,我們需要當機立斷的刪掉外鍵,這個當機立斷可能會帶來一些麻煩,我們來分析下可能會遇到一些什麼問題:
1. 分成多個庫,沒了外鍵了以前的inner join操作要跨庫嗎?
假定情境:部落格表有對使用者表的外鍵引用,我們需要在首頁顯示部落格列表,部落格列表需要顯示使用者名稱和使用者id的資訊
之前使用者表,部落格表在一個庫裡面的時候我們可以通過外鍵inner join來取得使用者的關聯資訊,現在使用者庫和部落格庫被拆成了兩個庫,我想對跨庫做inner join說no;為什麼呢,因為這不適合擴充,假如有一天我們的業務量又增長了我們就需要把使用者庫挪到另外一台機器上,這要導致inner join跨伺服器了,這顯然不是一個好辦法,那該怎麼辦呢? 我有兩種方案,大家評判好壞:
1)做違反範式的設計,將使用者的不變資訊使用者名稱和使用者id一起存在部落格表中,讓使用者名稱冗餘吧,這樣做可以保證取部落格資料連帶使用者名稱時是非常高效率的
2)我們不再從資料庫中取使用者名稱的資訊,改從緩衝中取,我們可以在緩衝中形成一個最近活躍的使用者資料池,當我們需要使用者名稱時從這個緩衝區中去取。
目前在我的應用程式中用的是第一種方案,第二種更有伸縮性,第一種存冗餘資料只能存使用者名稱,有時候只存使用者名稱就夠了,有時候可能會出現不夠的問題。
2. 如果用到了根據外鍵做的串聯刪除,那這是一個噩夢
對付這個問題,我的方案是修改程式,如果需要串聯刪除,在程式邏輯中完成,不要在資料庫做串聯刪除了,串聯刪除是一種隱含在資料庫中的邏輯,是一種不好的設計方案。
3. 觸發器也可能帶來和外鍵做串聯刪除同樣的麻煩,同樣的也是修改程式邏輯,代替這種資料庫層級的隱含邏輯。
也許你會說分庫之後一定會帶來效能的提高嗎?這個問題得具體分析,這要看你的伺服器效能如何,如果分庫之後資料庫的cpu,io,記憶體的壓力依然很大;那麼您可以將分庫之後的其中某一個庫遷移到另外一台伺服器上,讓兩台伺服器分攤資料訪問的壓力,肯定會提升效能的。
最後說下,分庫分與不分是由資料量、效能要求決定的。下篇分表敬請期待!