1NF? 2NF? 3NF?
NF 是 Not Fine 還是 No Function?
如果資料庫規劃只想到正規化, 那就太小看資料庫了, 那還有什麼東西要考慮呢?
最近在改寫一個以前的案子, 幾年前已經套用過正規化的動作了, 但改起來就覺得不順手, 所以整理了一些元素, 簡單介紹一下:
1. 考慮系統用的編號:
因為系統用的編號與人用的編號是不同的, 常見的身分證字號雖然常被當 PK , 但畢竟是人設定的, "凡原則必有例外", 所以會有重複號, 無身分證號(外籍人士)等情況, 所以有些關連用的 PK , 應該考慮另編系統用的編號.
2. 考慮系統人員與使用者可以異動的欄位:
大概可以分成三種人用的(依需求可以再分)
a. 一定要系統人員設定, 屬於程式相關參數的.
b. 屬於管理人員可以異動, 但需要一定討論過的, 例如: 電話可以分不同類別, 或人的職業/學歷等.
c. 操作人員可以修改的項目.
為什麼會這樣區隔, 是因為覺得這樣的分類, 往往跟 Index 的建立有關連, 之後的速度也有差別.
3. 善用反正規化:
這應該很多資料都有提過, 透過程式先把一些資料, 另外存到某個欄位, 下次只要查詢該欄位, 就不用再查原始資料, 可以提高速度.
4. 使用節點而不用分層:
這是從地址分類想到的, 以前設計地址時, 是用分層處理, 例如個人資料有: 縣市 - 鄉鎮市區 兩欄, 系統資料則是"xx市-xx區"對照表, 後來把這種資料都列為節點, 例如: 台南市跟大安區都是"地理區"的一欄, 再有一欄"上層單位", 則縣市層級的資料就少很多, 維護也較方便.
原始:
106|台北縣|大安區|(誤)
119|台北縣|風化區|(誤)
如果要異動台北縣改為新北市, 就要全改, 所以後來架構改用
1|地球|0(無上層, 系統定義)
2|臺灣|上層為1
38(系統自動編碼)|台北縣|上層為2
119(系統自動編碼)|風化區|上層為38
這樣系統預設找上層為2(臺灣), 就是各縣市, 選好縣市, 再選區就可以了; 而且台北縣改名, 只要改一個欄位, 如果像台南縣與台南市合併, 只要把上層對照指標改掉就好.
5. 把一些同性質的東西擠在一起.
這是由通訊資料整理時想到的, 以前是"電話1", "電話2", "手機", 後來改用指標:
個人表: 個人編號, 姓名
電話表: 電話編號, 電話號碼, 電話類型
地址表: 地址編號, 最小單位區碼, 最小單位區碼對照地址, 其他地址, 地址類型
考慮"電話"或"地址"這種"物件"其實可能會再異動(7碼升為8碼, 縣市升格), 所以將電話表與地址表獨立, 另外再用一張多對多的對照表來查詢.
當然開太多查詢表格會降低速度, 所以用了一個"反正規化", 地址有一項"最小單位區碼", 就是前面提到的分區, 系統記錄如果是 119 , 就會把"台北縣風化區"(誤)記在"最小單位區碼對照地址", 這樣只有新增或異動地址才會需要查詢區域對照表, 平常查地址時只要"個人""個人對照地址""地址". (其實實作時又有小調整)
6. 用同一張表打包起來:
因為剛剛的通訊資料分類法, 把一般常見的"表格式"通訊錄改掉了, 所以類別那一欄, 以前可能只有"公""私", 後來又多了"小三"(誤), "情婦"(大誤), "炮房"(18x), 但是這種類別在人事單位可能想調整, 所以就另外又設一張"類別表", 順便把最高學歷等東西都打包起來, 看起來像這樣
類型 |代號 |說明
2(電話用)|33 |公
2(電話用)|34 |小三
4(地址用)|23 |通訊地址
4(地址用)|28 |戶籍地址
7(學歷用)|11 |低級大學
7(學歷用)|14 |博士後研究助理(誤)
1(職業用)|86 |水母(爆)
1(職業用)|34 |遊民(再爆)
這樣在對應的欄位, 比如要查學歷時, 只要查類別代號為 7 , 就知道最高學歷. 這樣也是結合使用頻率(啊, 忘記寫了), 因為異動學歷/職業通常是同時修改, 所以說明就可以放在同一張表, 而且使用機率不高, 所以程式異動也少.
大概簡單分類就這樣, 除了資料庫基本的正規化, 再加上一些"人"與"環境"的因素來整理的感想, 給大家參考看看.
slime提到:
"小三"(誤), "情婦"(大誤), "炮房"(18x)
我嚴重懷疑此文章有洩露國家機密之嫌,因為看起來好像到處都隱藏著重要密碼...
完了,完了,考試考正規,反正規,五層正規,我絕對0分
我都用OO,ER,EM..設計理念,直接把企業實體模型就轉換成資料關聯了,隨便拉都可以拉上百個關聯,而且不出錯,不用背公式.
資料庫可存的樣式太多,欄位可以存放二進制語音,串流,字串Json,XML,剩至於地理或一些協定格式..
除非你是純資料管理人員,你才會把全部的演算法都做在資料儲存層,資料邏輯層
像我以整個架構為觀點,有些資料會撈到資料存取層或企業邏輯層,把複雜的結構序列反序列計算完再寫入
比你用很複雜的正規劃和一堆nest select join where 有效率
pantc328提到:
隨便拉都可以拉上百個
佩服, P大家裏的馬桶需要多準備幾個才行.
那麼多馬桶喔,難怪日子可以過得爽爽的...
slime提到:
1F? 2F? 3F?
停車請往B1F、B2F...
不早說,我停到B18F很久了...
ted99tw提到:
我停到B18F很久了
難怪, 廣播找泰大都七天了, 都還見不到人影....
在B18要廣播七七四十九天才行...
ted99tw提到:
在B18要廣播七七四十九天才行...
這是傳說中的七旬
還是觀落陰
不要下來找我,在B18吃香喝辣壞事做盡淹死在女人堆都沒關係,因為..沒有B19
反正規化是一種高耦合的做法, 除了資料與邏輯的高度耦合之外, 最難堪的是把人的因素耦合進來, 在反正規化的思考中, 不同的人會有不同的想法, 因此會產生許多不同的"反正規化'的結果, 很不幸的, 高耦合的系統是不穩定的系統, 尤其當人員離職, 離開, 或老化, 新進的人有機會"忽略掉"某些"反正規化"的細節, 而正規化的目的就是要降低耦合度, 讓溝通時不會產生誤解.
雖然台北縣改制為新北市, 商業邏輯上, 台北縣和新北市是不同的, 如果將台北縣改為新北市, 就是失去了"台北縣"這資訊, 因此, 應該要用一隻程式來自動產生新的地址紀錄, 在我的設計裡, 地址等通訊資料是有時效的.
不同的思考方向,就會產生不同的邏輯,
要如何取捨,就要考驗IT人員思考的角度...
你這樣講, 沒有實務經驗的人, 有聽沒有懂 !!!
所以 [站在巨人肩膀] 很重要
考慮系統用的編號:
[內碼] 比 [編碼] 連結快 PK/FK 都一樣
考慮系統人員與使用者可以異動的欄位:
System Auditing Field 系統內部記錄欄位
User 輸入欄位在不同 Role 不同 DocType 不同 DocStatus 有不同權限
不可 manual entry 異動欄位,關連異動欄位都是要用設定的
hard-code 就完蛋了......
這些要能寫彥正規則引擎否則就系統就很low...
要你自己開發 Framework 考慮到這些你應該暈倒了
albertachen提到:
這些要能寫彥正規則引擎否則就系統就很low...
這些要能寫驗正規則引擎否則就系統就很low...
要不要開個 資料庫 的粉絲團啊?
D 槽粉絲團?
slime提到:
D 槽粉絲團?
這個團的粉絲的原料可能都有毒.....
而且是劇毒...
ted99tw提到:
而且是劇毒...
那就開個順丁稀二酸粉絲團吧...........
那就要恭邀王永慶來當團長了...
賈伯斯 在教 王永慶用 iPhone ?
等一下打給他 ?
ted99tw提到:
那就要恭邀王永慶來當團長了...
有請泰大廣播叫人一下吧, 你不是在第18層??..........