對於設計和創建資料庫完全是個新手?沒關係,Joe Celko,世界上讀者數量最多的SQL作者之一,會告訴你這些基礎。和往常一樣,即使是最專業的資料庫老手,也會給他們帶來驚喜。Joe是DMBS雜誌是多年來最受讀者喜愛的作者。他在美國、英國,北歐,南美及非洲傳授SQL知識。他在ANSI / ISO SQ ...
對於設計和創建資料庫完全是個新手?沒關係,Joe Celko,世界上讀者數量最多的SQL作者之一,會告訴你這些基礎。和往常一樣,即使是最專業的資料庫老手,也會給他們帶來驚喜。Joe是DMBS雜誌是多年來最受讀者喜愛的作者。他在美國、英國,北歐,南美及非洲傳授SQL知識。他在ANSI / ISO SQL標準委員會工作了10年,為SQL-89和SQL-92標準做出了傑出貢獻。
在你開始考慮你的資料庫架構或表前,你需要細想下你的數據:數據是什麼類型,你使用值的範圍。它應該是唯一的,精確的且不含糊的。然後你的命名應該通俗易懂的。Joe Celko這樣解釋道。
不要太驚訝,在資料庫設計里第一步是數據。但事實上,太多的程式員不會花時間在它們的數據設計上,而是首先設計架構。這樣行不通。SQL處理的是結構化數據,而不是想文本或圖片的非結構化數據。在關係型資料庫管理系統(RDBMS)里一個基本概念是Codd博士所謂的信息原則(Information Principle)。這個規則寫道:在關係型資料庫管理系統里,所有的數據被建模為表裡行里列里的標量。
這就是說表裡的所有行有同樣的結構。也就是說正確的表設計不會出現有一行是汽車的模型,另一行是魷魚的模型,還有一行表示Lady Gaga。
同樣,這就是說行里的每列是同樣數據元的值。在表裡,一個列不會從鞋子大小變成其它溫度的值。也就是說範圍不會改變——如果你以攝氏度測量溫度,那麼這列的所有值都使用攝氏度的範圍。
選擇數據的範圍和類型很重要。它讓在一些範圍內做數學和比較有意義,而不是與其它。這也解釋了為什麼SQL 是強類型語言(strongly typed language)。一些語言是弱類型的——那就是,變數在程式執行期間可以修改數據類型——一些則是強類型的;那些就是變數保持同樣的數據類型,只有你在強制轉化的時候才會是新的數據類型。並不是所有的強制轉化都合法。弱類型轉化問題的經典例子是PL/I里,如果你分配單個數組元為負數的平方根,它會把整個數組從FLOAT轉為COMPLEX類型。這個發生的時候沒有任何警告信息。關於弱數據類型有個老笑話:
教師:“比利,6乘以9多少?”
比利:“額~~,紅色?”
教師:“不是!薩利,6乘以9多少?”
薩利:“星期四?”
教師:“不是!湯米,6乘以9多少?”
湯米:“54”
教師:“回答正確!現在告訴大家你怎麼得到答案的。”
湯米:“我用紅色除以星期四!”
人們在寫弱類型語言時,經常會在數據元名稱加上首碼或詞尾,告訴大家原始數據類型,防止在程式中大家修改類型。這違反了ISO-11179元數據規則。這個標準總結了命名數據元是它本身應該是什麼,而不是它在存儲中的位置,或者在表裡如何使用。
對於數據元,ISO_11179格式是“[<角色>_]<屬性>_<性質>]"(“[<role>_]<attribute>_<property>”)。在整個架構里,一個數據元有一個且只有一個名稱。如果在整個企業里有且只有一個名稱更佳。最好的話,在宇宙里有且只有一個名稱。我來告訴你另一個老笑話:
“我是小孩時,我們有三隻貓。”
“它們的名字是什麼?”
“貓,貓和貓。”
“聽起來分不清;你怎麼把它們區分開?”
“誰在乎呢?當你叫它們時,它們也不會過來!”
我們希望數據在叫的時候就知道它是什麼。邏輯上有標識規則,通常簡單的從字面上說A就是A。更正式的話,我們稱作:
- 是一些特定的;實體有一個標識。
- 沒有什麼特殊的話就什麼都不是;實體是唯一和精確的。
- 是任何常見的話也是什麼也不是;實體不含糊。
例如,沒有一個東西可以是“id”——它太模糊,太通用(它是用來標識汽車,魷魚還是布蘭妮·斯皮爾斯麽?)。它是沒有性質的屬性。更好的命名會是”vehicle_id",如果那是我們有的屬性性質(attribute property)。最好的數據元名稱是“vin”,這個是普遍使用和定義的ISO 4030“車輛識別碼(Vehicle Identification Number)”標準。VIN精確且很好理解。
同樣,你也會看到沒有性質的屬性。我個人最愛的是“sex”,它可以是“sex_code”(按ISO 5218定義,可以參考它的標誌符“SEX”,雖然這不是個好主意)。"sex_type"(動物或植物的生理選項:雄性還是雌性)或者“sex_frequency”(在我這一廂情願的想法)。
可能最荒謬的錯誤是性質鏈。想下“type_code_id”什麼意思。如果它是個標識,俺麽在數據模型里它是唯一的並屬於一個實體(想下"emp_id")。如果它是個代碼,那麼它有個外部的權威(想下“郵編”)。如果它是個類型,那對它有個測試(想下“血型”)。這就像沒有一個名詞來修改的一連串形容詞。增加一個屬性到鏈不會拯救含糊問題。
再次強調,基本規則是一個數據元名詞告訴我們它是什麼。名稱不會告訴我們:
- 有表名的架構里它的位置
- 在特定表裡它如何使用的(例如在名稱里沒有pk-,fk-或vw-等詞綴的話)
- 它的數據如何物理存儲的(例如對於整形、字元型等沒有“i-”,“str-”等詞綴)
- 沒有告訴我們數據元不是什麼。要確定並精確。
性質組件是從標準化列表裡選取,你可以按需添加。這個列表成為你數據字典的一部分,並需要被執行。
在同個表裡,當同樣的數據元出現2個或更多的角色,要用到<角色>。例如,在組織報表裡會有“supervisor_emp_id”和“subordinate_emp_id”,都來自Personnel表裡的員工標識數據元“emp_id”。
來看下名稱的長度。數據元名稱太長或太短都不好。太短的名稱很難理解,除非它是標準的縮寫。它們也會模棱兩可;我最喜歡的例子是一個系統,在數據元名稱里有多個student的縮寫方式,其中一個是“std”——經常會被誤認為是“standard”的縮寫,在有些地方甚至是“sexually transmitted disease(性病,由性交引起的病)”。
在名稱里避免所有的特殊字元。堅持使用Latin-1字母,數字和下劃線。它們會在其它程式語言里復用。沒錯,數據元名稱不只為SQL。同樣,避免同時使用僅微軟支持的方括弧“["或者僅ANSI/IOS支持的雙引號標記。這個只是為在資料庫里顯示格式草率的編程完成,而不是前端顯示。有一個可能的異常會是語言翻譯問題,Latin-1字母不能正常工作。
執行大寫規則來避免大小寫敏感問題。我的規則是SQL 關鍵字是大寫,標量數據元是小寫,架構對象是大寫。在我的《SQL 編程風格(Sql Programming Style )》書里有這方面的研究,但這裡我會跳過細節。
對於數據元素名稱的標準化性質尾碼列表是基於Teradata的內部標準建立,在行業刊物上通用(CMP,MKP和其它出版商)。這些尾碼有精確的含義。如果你需要發明你自己的,它們也要是精確的。
"_id"=標識者。在架構里它是唯一的,在架構里任何地方它指的是一個實體。唯一性和標識者不是同個東西。圓周率數字它是唯一的,但他不能標識一個實體。絕不使用“<表名>_id";這是基於位置的名字,並告訴你很可能這不是個真正的主鍵。簡單的”id“太含糊,當你有無限個這樣的名稱,你就吧你的數據字典弄混。顯然,自增長值也不是個標識。我一會談下這個謬論。
"_date"或"_dt"=日期時間的維度。它是一些時間——工作,出生,終止等等。沒有本身就是日期這樣列名,那樣會很糟糕,因為DATA在SQL里是註冊的關鍵字。
"_nbr"或"_num"=標簽數字;這是命名一些的數字字元。不要使用"_no",因為它看起來像布爾的是否值。我更喜歡"nbr"或"num",因為在多個歐洲語言里,它是常見的縮寫,而且在"_num"里類似形狀字母的組合會有視覺混淆。
"_name"或"_nm"=這是個字母名稱本身就能看懂。它也成為名稱量表。
"_code"或"_cd"=代碼,被可信源,通常是企業外標準化維護的。例如,郵編是有米國郵政服務維護的。在它的上下文里,代碼很好理解,因此你可能不需要翻譯它。
"_size"=對於一個商品,例如衣服,鞋子, 信封或機器螺絲的行業標準或公司規模。
"_seq"=序列,序數。和標簽數不是同個東西,因為它不會缺口。
"_tot"=合計,一個聚合的維度,邏輯上不同的部分。
"_tally"=值的個數,一個聚合的維度。也稱為絕對標度。
"_status"=一個內部編碼,反射了在知道的模式里將要修改的狀態。考慮下軍事地位。你會出生,然後改變狀態到合法年齡。同時你不能和多個人結婚。你可以從已婚狀態修改為離婚,從離婚變成已婚。如果你死了的話,就不能結婚。
"_cat"=分類,來自內部源的需要官方判定的編碼。例如,五個颶風的類別。這不像個代碼,需要這樣的官方判定。
"_class"=不需要外部源的內部編碼。一個類別就有一些共性一系列東西;對於動物分類你有規則,是哺乳還是爬行。有些情況你很難使用這些規則,例如在澳大利亞的哺乳動物,但是例外會變成它們自己的分類——單孔目。
"_type"=內外都有同樣含義的編碼。血型有新定義的測試過程。比起class,type通常更不正式,且會有重疊。type是三類中最弱的,它需要一個判斷。在一些州,三輪摩托車是作為摩托車註冊。在其它州,會作為汽車。在一些州,如果它有倒車檔的話,也會作為汽車。
在實際的使用中,這3個方面會混淆。因此以行業標準來,即使它違反了上述的定義。
"_addr"或"_loc"=實體的地址或位置。地址和位置間有微妙的區別。地址可以指的是街道地址或一些外部的地理系統。位置指的是內部架構,例如倉庫倉號。倉號可以保持一樣,即使物理位置改變了。
"_img"=圖片數據類型,例如.jpg, .gif等等。使用特定的格式作為性質會是重要的。
如果需要的話,可以隨意添加。但記得跟蹤並標準化你所做的。
原文鏈接:http://www.sqlservercentral.com/articles/Stairway+Series/69801/