資料模型 (Data Model) 是所有軟體開發中最重要的環節,每個資料表示層級要如何向更低層級表達資料項目?
看起來有點饒舌,資料表示層級舉例來看:
應用程式端 (Application)
諸如金流、物流、訂單、貨物資料等等,這些項目都是表達了現實世界中你的應用程式會使用到的資料項目。
資料模型端 (Data Model)
當你決定了資料項目後,在來就要想用什麼 data model 來表達,例如 JSON、XML document、relation database 或者 graph model。
儲存與檢索端 (Storage and Retrieval)
該用哪個 database 儲存,每種 database 都有多種查詢、操作資料的方法,如 Hash Index、B-Tress 等等,這部份在 Day 6 會講到。
硬體端 (Hardware)
硬體工程師的世界,通常我們只決定要用多少系統資源執行。
每一層都是在向下一層隱藏該層的複雜性,提供給他們乾淨的 Data Model,今天的主題就是講 Data Model 中的 Relation Model 跟 Document Model,就是常聽到的 SQL 跟 NoSQL。
關聯式資料模型 (Relational Model) 加上 SQL 跟 RDBMS 的推出,這主宰了軟體開發領域長達 25-30 年之久,
Relational model 最早 Edgar Codd 在 1970 年提出的學術文章:資料是組織在關係裡面的 (可視為 table in SQL),每一個關係是未經排序的 tuple 集合 (可視為 row in SQL)。
然後在 1980 年中,relational database management systems (RDBMS) 和 SQL 成為一套標準化的工具,讓人們能用特定結構性的語法去查詢資料。
NoSQL 一詞不代表特定的任一技術,它代表了分散式、非關聯式資料,開始有革命感覺是來自 2009 年在亞特蘭大舉行的會議,NoSQL 不是反對 SQL 之意,比較精準的詞應是 Not Only SQL。
NoSQL 有下述幾項特點
上圖是 Bill Gates 的 LinkedIn Profile 用 reational schema 的方式來表達,這張圖的重點是我們用 Relational Model 來表達一個人可能會有多個
工作經歷、教育背景以及聯絡方式,就是 position、education、contact_info 這 3 個 table,這 3 個 table 都存了 user_id 這個 foreign key 這個參照來找到 user 是誰。
像 Profile 這種資料也常用 Document Model 的方式來表達,以 JSON 來呈現的話長這樣:
{
"user_id": 251,
"first_name": "Bill",
"last_name": "Gates",
"summary": "Co-chair of the Bill & Melinda Gates... Active blogger.",
"region_id": "us:91",
"industry_id": 131,
"photo_url": "/p/7/000/253/05b/308dd6e.jpg",
"positions": [
{
"job_title": "Co-chair",
"organization": "Bill & Melinda Gates Foundation"
},
{
"job_title": "Co-founder, Chairman",
"organization": "Microsoft"
}
],
"education": [
{
"school_name": "Harvard University",
"start": 1973,
"end": 1975
},
{
"school_name": "Lakeside School, Seattle",
"start": null,
"end": null
}
],
"contact_info": {
"blog": "http://thegatesnotes.com",
"twitter": "http://twitter.com/BillGates"
}
}
最大的差別就是 Self-Contained
,工作經歷、教育、聯絡方式都包含在整個 LinkedIn Profile 之中,用 XML 呈現也是一樣意思,但 JSON 比 XML 簡單和好理解太多了XD
一對多的闗係就是上面提到的,一個人可能會有多個
工作經歷、教育背景以及聯絡方式,把這關係轉成 Tree 結構的話就更好理解了。
多對一的關係,繼續用 Bill Gates 的 LinkedIn Profile 來看,我們的居住地區跟職務都是用 ID 來表達,而不是直接寫 "Greater Seattle Area" 和 "Philanthropy",為什麼呢?
"region_id": "us:91",
"industry_id": 131,
最主要的原因就是為了 標準化 (Normalization),維護一個表的話代表居住地或職務一樣的人都會有相同的資料,修改方便也能統一格式,找資料也更快,雖然 ID 只對資料庫有意義就是了,但 去重複 就是 Relational Database 中標準化的關鍵想法。
標準化 (normalization) 的反面就是 去標準化 (Denormalization),也就是在 Document Database 裡常用到的,不會用額外的 table 儲存資料,每個 LinkedIn Profile 的居住地區跟職務都會存成:
{
"region_id": {
"conutry": "US",
"area": "Greater Seattle Area"
},
"industry_id": "Philanthropy"
}
在 documn依舊繼續用 Bill Gates 的 LinkedIn Profile 來看,若我們想讓 Profile 加上 2 個新功能:
顯示 Microsoft 公司和學校的基本資料,如下圖:
user 可以為另一個 user 寫推薦,推薦裡可以看到推薦者 user 的 Profile,若推薦者的 Profile 有資料變更,被推薦者看到的 推薦者 Profile 內容也需要更新,所以被推薦者的 Profile 應該要存推薦者的 user 參照。
下圖是加上 2 個新功能後所需要的多對多關係示意圖:
虛線可被存成 Document Model,在這種情況下,公司、學校、推薦者都需要儲存參照,然後做多次查詢是變的必要了。
[Day 5] Data Model (2) - Relational Versus Doucment Model