內容目錄
ToggleSQL (Structured Query Language 結構化查詢語言) 是一種專門用來管理與查詢關聯式資料庫(Relational database)的程式語言。NoSQL資料庫的意思是 “Not Only SQL”,也就是不限定為「關聯式資料庫」的資料庫管理系統的統稱。
今天,大部分的人提到「資料庫」的時候,通常指的其實是資料庫管理系統(database management system,簡稱 DBMS):一套讓我們能方便使用資料庫的軟體,作為使用者(或是使用資料庫的應用程式)與資料庫之間溝通的平台。在這篇文章,會入門介紹「關聯式資料庫」與「NoSQL(非關聯式)資料庫」這兩種常見的資料庫管理系統。
想了解更多 Data & AI 產業與必備技能?Data & AI 免費公開課在這裡!
關聯式資料庫(Relational Database Menagement System, RDBMS)
1970 年代初,在 IBM 研究實驗室工作的埃德加·科德 (Edgar F. Codd) 出版了一份名為「A Relational Model of Data for Large Shared Data Banks」的研究,定義了「關聯式資料 (Relational Database)」的概念,以及將資料組成表格的應用原則。這份研究,就是關聯式資料庫發展的起點。
關聯式資料庫有三個特質:
1)資料是以一個或是多個資料表 (table) 的方式存放。
在關聯式資料庫裡,每一筆資料都是在 table 中的一個 record,然後再把不同的 table 集合起來,就成為一個關聯式資料庫。
所以使用關聯式資料庫的網站,背後都有多個 table,負責紀錄不同的資料。例如在一個電商網站中,應該會有賣家、商品、分類、使用者和交易紀錄等資料表,然後它們各自也有不同的關聯。
2)資料之間有明確的關聯。
關聯式資料庫一般都用來儲存結構化的資料,而資料之間大多會有清楚的關聯。以電影清單專案為例,我們只有一種資料需要處理,就是「電影 (movie)」 的內容。在建立 To-do List 的認證系統的時候,我們則有 todo 跟 user 這兩種資料,並需要建立它們直接的關聯。而在關聯式資料庫裡,這兩種資料會以兩個資料表來存放,而在兩個資料表之間,我們也會設定「使用者擁有 todo」這個關聯:
3)關聯式資料庫以 SQL 語言操作
SQL (Structured Query Language 結構化查詢語言) 是一種專門用來管理與查詢關聯式資料庫的程式語言。透過 SQL,我們能在關聯式資料庫裡新增、查詢、更新和刪除資料,同時也能建立和修改資料庫模式。它的語法簡單直接,一切都是以資料為主角去思考。讓我們一起來看一個簡單的 SQL 的範例:
SELECT * FROM [TABLE_NAME] WHERE [COND];
這句話的意思,就是「從 [TABLE_NAME] 的資料表中取出滿足 [COND] 條件的資料。
在過去的幾十年裡,關聯式資料庫的發展並不是一帆風順,有很多批評者,但由於關聯式資料庫使用簡單,穩定度高,而 SQL 功能強大,並且也積累了很多企業開放支援 SQL 的軟體與大量的成功案例,所以目前關聯式資料庫仍是最多軟體開發者使用的資料庫系統。
免費點我下載數據技能路線指南
關聯式資料庫的特色
- 資料存放在一個或多個資料表當中。資料都是透過資料表中行列的二元關係呈現。
- 資料表需預先設定架構 (schema)
- 資料表之間的關係也需要預先定義好,使資料之間有明確的關聯
- 可以透過 SQL 語言進行資料操作
另外,一個好的關聯式資料庫設計,也需要能夠確保每一個 transaction 能夠滿足 ACID 原則。ACID 分別代表
- Atomicity (原子性) : 資料操作不能只有部分完成。一次的 transaction 只能有兩種結果:成功或失敗
- Consistency (一致性):transaction 完成前後,資料都必須永遠符合 schema 的規範,保持資料與資料庫的一致性
- Isolation (隔離性):資料庫允許多個 transactions 同時對其資料進行操作,但也同時確保這些 transaction 的交叉執行,不會導致數據的不一致
- Durability (耐久性):transaction 完成後,對資料的操作就是永久的,即便系統故障也不會丟失
關聯式資料庫的侷限性
隨著網路應用程式的普及,使得資料庫的使用、分享、與資料量飛快地增加,讓原本的資料庫設計遇到的挑戰。人們除了需要更快的速度來處理大量資料之外,也需要能夠及時地提供服務以滿足大量使用者的需求。
此時人們開始轉向非關聯式資料庫設計來尋找解決方法,NoSQL 也就開始站上了舞台。NoSQL 的意思不是「不要用 SQL 」或是「資料不需要關聯」,NoSQL 它真正的意思是 Not Only SQL,也就是「不是用 SQL 操作資料的資料庫設計」,因此實際上資料之間還是可以建立關聯的喔。
另外,NoSQL 也不是橫空出世,雖然這個詞看起來很新,但早在電腦科學發展初期,就有許多不同於 Relational model 的資料庫設計。
NoSQL 非關聯式資料庫
前面說到,關聯式資料庫是最多開發者使用的資料庫系統,那麼還有什麼其他的資料庫系統呢?讓我們來聊聊 NoSQL 資料庫。
隨著電腦、行動裝置、與互聯網的普及,網路應用程式的流量大幅地增長,同時 互聯網也進入「使用者生產內容 (user generated content)」為主流的時代。對於 Youtube、Facebook 這些社交網站來說,每分每秒需要處理的資料量是過去一般網站的非常多倍。
而從使用者的角度來看,他們在這些平台上對於資料的需求也跟過去不太一樣。資料庫的主要功能,從過去的「能夠無錯誤地同步處理結構清楚的資料」,到現在慢慢有新需求誕生:「處理高速且大量產生的資料,但不需要即時同步,也不需絕對地零錯誤。」為了呼應這個需求,NoSQL 資料庫就隨之興起了。
Not Only SQL (NoSQL)
NoSQL 的意思是 “Not Only SQL”,也就是不限定為「關聯式資料庫」的資料庫管理系統的統稱,在操作上,NoSQL 並不支持 SQL 語法 與 SQL 的邏輯。所以,NoSQL 資料庫通常不使用關聯模型,也並不需要固定的結構 (也就是 schema-free)。但有需要時, NoSQL 也可以使用關聯模型與 schema。
NoSQL 將聚集後的資料,作為儲存的最小單位,透過縝密豐富的資料結構,有利於將資料分散到多個節點;比起資料的關聯,NoSQL 更關注資料所代表的人(例如使用者)與物(例如一篇分享在社交平台上的文章)的「狀態」變動,例如文章被分享、按讚等。
文件資料庫 (document database)
文件資料庫是NoSQL資料庫的一種,顧名思義,是把資料存放成「文件 (documents)」,這些文件會組成為「集合 (collection)」並放在一起,圖示如下:。
在文件資料庫裡,文件會存成 JSON 格式,而資料物件會由「屬性-值」 (attribute-vaule pair) 或陣列組成。例如下圖:
此外,NoSQL 還有一個特點是,不講求資料同步,只求最後結果一致。怎麼說呢?
我們先來看一個例子。如果我們今天要匯出一筆款項給商家,那麼當款項從我們的帳戶匯出後,系統一定要同步「帳戶已經扣除這筆款項」這個訊息,不然款項可能會被重複扣除,或者其他系統會誤以為我們帳戶的結餘跟匯款前一樣。這是適合使用 SQL 的情境。
至於適合 NoSQL、所謂不講求資料同步,只求結果一致的情境是什麼呢?
例如我們要來處理一篇在 Facebook 上的 po 文有多少人按讚時,其實這個訊息的準確性就不是非常重要。當一篇文章獲得第 100 個按讚時,某些使用者可能會馬上看到新的數字,但部分使用者可能要隔數十秒後才看到按讚數從 99 轉到 100。這種延誤,並不會造成什麼嚴重的問題。而對 Facebook 來說,更重要的是能在一定的成本之下,去處理大量的數據。順便告訴你,有報導說:Facebook 每一分鐘會收到超過四百萬個讚!
由於 NoSQL 的種類很多,而技術的成熟度與使用場景不一,所以目前業界還是以 SQL 資料庫佔大多數。在 Stackoverflow 2018 年的調查結果,關聯式資料庫系統還是最多開發者使用的資料庫管理系統,佔前五名中的首四名!
延伸閱讀:SQL (關聯式) 與NoSQL (非關聯式) 資料庫的比較
應用程式與資料庫
當你要在你的應用程式裡整合資料庫管理系統時,需要瞭解以下三件事:
- 應用程式如何與資料庫溝通
- 選擇用什麼資料庫
- 如何在應用程式裡定義資料結構
與資料庫溝通:ODM 與 ORM
若需要使用資料庫的功能,比如查詢、新增、修改或刪除資料等,就必須使用資料庫管理系統 (DBMS) 提供的原生查詢語言,其中最著名的是SQL (structured query language),也就是是專門用來操作關聯式資料庫的語言。
但在實務上,當我們用 Express.js 開發應用程式時,會希望能直接用 JavaScript 操作資料庫,而不需要另外撰寫 SQL。換成不同的程式語言,也會有一樣的需求,因此有人開發了一種叫「物件映射 (object mapping)」 的技術,主要是用程式語言裡的「物件」來包裝資料庫的 SQL,讓開發者可以直接使用物件導向的方式操作資料庫。
學會用 Express.js 製作完整的 Web App 產品
依不同的資料庫類型,會分別使用不同的映射技術:
- 文件資料庫:ODM (Object Document Mapper)
- 關聯式資料庫:ORM (Object Relational Mapping)
兩種技術的用途與概念非常類似,只是對應的類型不同。ODM 是針對文件資料庫 (document database) 的技術,而 ORM 則是針對關聯式資料庫 (relational database)。不過簡單來說,ODM 與 ORM 都是讓開發者可以使用物件導向語法來操作資料庫,同時也增加程式碼的易讀性與維護性。
舉個例子,如果我們要在 Todo 資料庫尋找一筆名為「買蘋果」,但還沒被完成的待辦事項 (todo),透過 ORM 的語法:
Todo.find ({ name: ‘買蘋果’, done: { false }})
若使用 SQL 的指令的話,會是:
SELECT * FROM Todos WHERE name=’買蘋果’ AND done=FALSE;
可以看到,使用物件導向語法時,程式碼會更簡潔,而且可以更好地銜接程式碼中同樣以物件導向語法建立的部分。
需要注意的是,任何技術都有優、缺點,ORM 與 ODM 也不例外。有部分開發者甚至大力反對使用 ORM 與 ODM,認為直接用資料庫管理系統的原生語言(如 SQL),才能確保操作時的效率與準確。
有很多不同的資料庫如 MongoDB、MySQL、PostgreSQL 等等。當你為自己的應用程式選擇一個資料庫時,也需要選擇對應的 ORM/ODM 系統。
MySQL or MongoDB?
說了這麼多,回過頭來到自己的專案上,該選擇 MySQL 還是 MongoDB 呢? 阿不對,剛剛都繞了這麼一大圈了,這裡應該是問,
「該選擇 RDBMS 還是 NoSQL 呢? 」
這裡有幾個考量點提供給大家參考:
可以考慮使用 NoSQL (譬如 MongoDB),如果
- 想快速啟動小專案測試 idea
- 資料格式不確定 (unstable schema),而未來很有可能調整
- 資料之間沒有複雜的關聯、或未來讀取資料時不需要使用 JOIN 的功能
- 著重在快速讀取資料與可用性,而非 ACID
可以考慮使用 RDBMS (譬如 MySQL),如果
- 已經有明確的資料格式,未來不會大幅的變動
- 資料之間的關聯很重要
- 想要更有效率的讀取資料,未來會大量使用到 JOIN 的功能
- 更著重在資料操作的準確性與一致性 (ACID)
上述的情境主要是在個人專案上,如果實際在業界開發,還需要考量到
- 商業邏輯的設計
- 目前使用的系統(如何加入,需不需要做調整或轉移)
- 部署方式
- 成本計算
- 維護與營運考量
- 未來的擴充性
有這麼多需要考量的點,這也難怪當問你朋友「應該用 MySQL 還是用 MongoDB 好」的時候時,他只能回答「看情況囉」
從資料分析入門課開始建立數據思維,4 週養成數據洞察力與實戰問題解決力
看了這麼大篇的文章,已經對資料庫有初步了解了嗎?來做個小測驗複習測試一下。