對於設計和建立數據庫徹底是個新手?不要緊,Joe Celko,世界上讀者數量最多的SQL做者之一,會告訴你這些基礎。和往常同樣,即便是最專業的數據庫老手,也會給他們帶來驚喜。Joe是DMBS雜誌是多年來最受讀者喜好的做者。他在美國、英國,北歐,南美及非洲傳授SQL知識。他在ANSI / ISO SQL標準委員會工做了10年,爲SQL-89和SQL-92標準作出了傑出貢獻。前端
在你開始考慮你的數據庫架構或表前,你須要細想下你的數據:數據是什麼類型,你使用值的範圍。它應該是惟一的,精確的且不含糊的。而後你的命名應該通俗易懂的。Joe Celko這樣解釋道。程序員
不要太驚訝,在數據庫設計裏第一步是數據。但事實上,太多的程序員不會花時間在它們的數據設計上,而是首先設計架構。這樣行不通。SQL處理的是結構化數據,而不是想文本或圖片的非結構化數據。在關係型數據庫管理系統(RDBMS)裏一個基本概念是Codd博士所謂的信息原則(Information Principle)。這個規則寫道:在關係型數據庫管理系統裏,全部的數據被建模爲表裏行裏列裏的標量。sql
這就是說表裏的全部行有一樣的結構。也就是說正確的表設計不會出現有一行是汽車的模型,另外一行是魷魚的模型,還有一行表示Lady Gaga。數據庫
一樣,這就是說行裏的每列是一樣數據元的值。在表裏,一個列不會從鞋子大小變成其它溫度的值。也就是說範圍不會改變——若是你以攝氏度測量溫度,那麼這列的全部值都使用攝氏度的範圍。編程
選擇數據的範圍和類型很重要。它讓在一些範圍內作數學和比較有意義,而不是與其它。這也解釋了爲何SQL 是強類型語言(strongly typed language)。一些語言是弱類型的——那就是,變量在程序執行期間能夠修改數據類型——一些則是強類型的;那些就是變量保持一樣的數據類型,只有你在強制轉化的時候纔會是新的數據類型。並非全部的強制轉化都合法。弱類型轉化問題的經典例子是PL/I裏,若是你分配單個數組元爲負數的平方根,它會把整個數組從FLOAT轉爲COMPLEX類型。這個發生的時候沒有任何警告信息。關於弱數據類型有個老笑話:
數組
教師:「比利,6乘以9多少?」架構
比利:「額~~,紅色?」數據庫設計
教師:「不是!薩利,6乘以9多少?」sqlserver
薩利:「星期四?」測試
教師:「不是!湯米,6乘以9多少?」
湯米:「54」
教師:「回答正確!如今告訴你們你怎麼獲得答案的。」
湯米:「我用紅色除以星期四!」
人們在寫弱類型語言時,常常會在數據元名稱加上前綴或詞尾,告訴你們原始數據類型,防止在程序中你們修改類型。這違反了ISO-11179元數據規則。這個標準總結了命名數據元是它自己應該是什麼,而不是它在存儲中的位置,或者在表裏如何使用。
對於數據元,ISO_11179格式是「[<角色>_]<屬性名>_<特徵名>]"(「[<role>_]<attribute>_<property>」)。在整個架構裏,一個數據元有一個且只有一個名稱。若是在整個企業裏有且只有一個名稱更佳。最好的話,在宇宙裏有且只有一個名稱。我來告訴你另外一個老笑話:
「我是小孩時,咱們有三隻貓。」
「它們的名字是什麼?」
「貓,貓和貓。」
「聽起來分不清;你怎麼把它們區分開?」
「誰在意呢?當你叫它們時,它們也不會過來!」
咱們但願數據在叫的時候就知道它是什麼。邏輯上稱同一概(the Law of Identity),一般簡單的從字面上說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")。若是它是個代碼,那麼它有個外部的權威(想下「郵編」)。若是它是個類型,那對它有個測試(想下「血型」)。這就像沒有一個名詞來修改的一連串形容詞。增長一個屬性到鏈不會拯救含糊問題。
再次強調,基本規則是一個數據元名詞告訴咱們它是什麼。名稱不會告訴咱們:
性質組件是從標準化列表裏選取,你能夠按需添加。這個列表成爲你數據字典的一部分,並須要被執行。
在同個表裏,當一樣的數據元出現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/