本文概述了在資料庫設計中,如何處理多國語言的問題,這裡的多國語言是指諸如這樣的業務:在ERP軟體中,我們在填寫客戶名稱時,除了需要填寫客戶的中文名稱,還需要填寫他的英文名稱。 一般的,如果是普通的項目型軟體,就比較簡單了,你只需要設計出固定的 ChineseName和EnglishName欄位就可以了。本文並不討論這種形式,而是討論在大型平台化的ERP軟體中如何?通用化的多語言儲存和讀取。
子表方式
直接:
第一種方式是建立一張子表,U9大概就是這個樣子,你需要注意的是,每一個實體如果包含多語言欄位,都會出現以_Trl為尾碼的表。也許你會覺得麻煩,其實不然,這些都是平台在後台自動處理了,你僅僅需要標記這個欄位是多語言欄位就可以了。
從理論上來說,他的儲存是最符合資料庫設計原則的,不管你的系統使用多少語言,資料庫結構是不變的。但是我總覺得查詢起來SQL會比較複雜,雖然這事平台也會協助你完成。我在想,如果我要一個多語言策略如何?呢?多語言策略的例子:如果此欄位沒有對應的繁體中文,取簡體中文,如果還沒有,取預設的語言內容。那麼在一個SQL中如何?呢?
不管怎麼樣,至少我不喜歡這種。
多欄位模式
還是直接:
恩?這是哪門子設計?和我上面講的項目型設計不是一樣嗎?
資料結構是一樣的,唯一的區別是通過ORM屏蔽了資料庫的結構,在設計實體時,你僅僅設計了Name欄位,其類型是“多語言類型”,然後在客戶那裡初始化時,客戶可以決定採用多少種語言,然後ORM在後台自動添加這些列。
這是我希望的設計,因為他足夠的簡潔,任何人都可以非常方便的寫出SQL語言。而且執行起來一定是最高效的。而且實現上面說的取值策略也很容易,只需要實現編排好多個嵌套的IIF函數就是了。
缺點呢?當然有,首先冗餘很大,即使沒有填寫對應的英文,一樣要佔用一個空間。其次,如果客戶發神經,一下子選擇了十幾個語言,然後發現他並不需要,又想刪除掉?那麼我需要檢查資料庫的所有相關欄位是否全部沒有資料,才能決定可以刪除這個語言並刪除所有相關的欄位。這是個問題。
XML欄位
這種方式我就不畫圖了,很簡單,還是只有一個欄位Name,不過資料類型不是nvarchar,而是把定義成XML類型,這是SQLServer2005新增的類型,我們可以在此欄位儲存諸如下面這樣的資料:
<items>
<item lng="" value="預設" />
<item lng="CHS" value="中文" />
<item lng="EN" value="English" />
</items>
那麼在SQL中怎麼輸出對應的中文內容呢?很簡單:
Select EmployeeId,Name.value('(/items/item[@lng="CHS"]/@value)[1]','nvarchar(max)') FROM Employees
很簡單,我喜歡。
不過有人可能會說,其實沒有xml類型前,我就已經使用nvarchar來實現了,使用一個自訂函數一樣可以解決(使用諸如:/en/english /chs/中文的方式儲存)。但是我認為字串方式處理並不完美,主要表現在你必須自己小心處理特殊字元,否則很容易亂套。使用XML類型的話資料庫會處理這些。另外,SQL Server對XML類型的查詢有最佳化處理,比起SQL自訂函數啟動並執行速度要快的多。而且,我相信,以後SQL Server對XML的支援會越來越好。