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層??.......... ![]()