# 閱讀技術文章_基礎關聯式資料庫與非關聯式資料庫_SQL/NoSQL ###### tags: `SQL` `技術文章` `關聯式資料庫` `非關聯式資料庫` --- [SQL/NoSQL是什麼?認識資料庫管理系統DBMS](https://tw.alphacamp.co/blog/sql-nosql-database-dbms-introduction)(閱) 筆記內所有成就皆不來自我,感激技術文章分享者 --- ## 目錄 - SQL - NoSQL - 關聯式資料庫 - 非關聯式資料庫 ---- ## SQL SQL (Structured Query Language 結構化查詢語言) 專門用來管理與查詢 **關聯式資料庫(Relational database)** 的程式語言 NoSQL資料庫的意思是 "Not Only SQL",也就是不限定為「關聯式資料庫」的資料庫管理系統的統稱。 --- ## 關聯式資料庫(Relational Database Menagement System, RDBMS) 關聯式資料庫有三個特質: 1)資料是以一個或是多個資料表 (table) 的方式存放。 在關聯式資料庫裡,每一筆資料都是在 table 中的一個 record,然後再把不同的 table 集合起來,就成為一個關聯式資料庫。 ![](https://i.imgur.com/t5tXv4Y.png) 所以使用關聯式資料庫的網站,背後都有多個 table,負責紀錄不同的資料。例如在一個電商網站中,應該會有賣家、商品、分類、使用者和交易紀錄等資料表,然後它們各自也有不同的關聯。 2)資料之間有明確的關聯。 關聯式資料庫一般都用來儲存結構化的資料,而資料之間大多會有清楚的關聯。以電影清單專案為例,我們只有一種資料需要處理,就是「電影 (movie)」 的內容。在建立 To-do List 的認證系統的時候,我們則有 todo 跟 user 這兩種資料,並需要建立它們直接的關聯。而在關聯式資料庫裡,這兩種資料會以兩個資料表來存放,而在兩個資料表之間,我們也會設定「使用者擁有 todo」這個關聯: ![](https://i.imgur.com/nvQXLds.png) 3)關聯式資料庫以 SQL 語言操作 SQL (Structured Query Language 結構化查詢語言) 是一種專門用來管理與查詢關聯式資料庫的程式語言。透過 SQL,我們能在關聯式資料庫裡新增、查詢、更新和刪除資料,同時也能建立和修改資料庫模式。它的語法簡單直接,一切都是以資料為主角去思考。讓我們一起來看一個簡單的 SQL 的範例: SELECT * FROM [TABLE_NAME] WHERE [COND]; 這句話的意思,就是「從 [TABLE_NAME] 的資料表中取出滿足 [COND] 條件的資料。 在過去的幾十年裡,關聯式資料庫的發展並不是一帆風順,有很多批評者,但由於關聯式資料庫使用簡單,穩定度高,而 SQL 功能強大,並且也積累了很多企業開放支援 SQL 的軟體與大量的成功案例,所以目前關聯式資料庫仍是最多軟體開發者使用的資料庫系統。 ## 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)」並放在一起,圖示如下: ![](https://i.imgur.com/1xW4f39.png) 在文件資料庫裡,文件會存成 JSON 格式,而資料物件會由「屬性-值」 (attribute-vaule pair) 或陣列組成。例如下圖: ![](https://i.imgur.com/zjqMAPM.png) NoSQL 還有一個特點是, **不講求資料同步,只求最後結果一致**。怎麼說呢? 我們先來看一個例子。如果我們今天要匯出一筆款項給商家,那麼當款項從我們的帳戶匯出後,系統一定要同步「帳戶已經扣除這筆款項」這個訊息,不然款項可能會被重複扣除,或者其他系統會誤以為我們帳戶的結餘跟匯款前一樣。這是適合使用 SQL 的情境。 至於適合 NoSQL、所謂不講求資料同步,只求結果一致的情境是什麼呢? 例如我們要來處理一篇在 Facebook 上的 po 文有多少人按讚時,其實這個訊息的準確性就不是非常重要。當一篇文章獲得第 100 個按讚時,某些使用者可能會馬上看到新的數字,但部分使用者可能要隔數十秒後才看到按讚數從 99 轉到 100。這種延誤,並不會造成什麼嚴重的問題。而對 Facebook 來說,更重要的是能在一定的成本之下,去處理大量的數據。順便告訴你,有報導說:(link)Facebook 每一分鐘會收到超過四百萬個讚! 由於 NoSQL 的種類很多,而技術的成熟度與使用場景不一,所以目前業界還是以 SQL 資料庫佔大多數。在 (link)Stackoverflow 2018 年的調查結果,關聯式資料庫系統還是最多開發者使用的資料庫管理系統,佔前五名中的首四名! 延伸閱讀:[SQL (關聯式) 與NoSQL (非關聯式) 資料庫的比較](https://aws.amazon.com/tw/nosql/) ## 應用程式與資料庫 當你要在你的應用程式裡整合資料庫管理系統時,需要瞭解以下三件事: - 應用程式如何與資料庫溝通 - 選擇用什麼資料庫 - 如何在應用程式裡定義資料結構 ## 與資料庫溝通:**ODM** 與 **ORM** 若需要使用資料庫的功能,比如查詢、新增、修改或刪除資料等,就必須使用資料庫管理系統 (DBMS) 提供的原生查詢語言,其中最著名的是SQL (structured query language),也就是是專門用來操作關聯式資料庫的語言。 **但在實務上,當我們用 Express.js 開發應用程式時,會希望能直接用 JavaScript 操作資料庫, *而不需要另外撰寫 SQL。換成不同的程式語言* 也會有一樣的需求,因此有人開發了一種叫「物件映射 (object mapping)」 的技術,主要是用程式語言裡的「物件」來包裝資料庫的 SQL,讓開發者可以直接使用物件導向的方式操作資料庫。** 依不同的資料庫類型,會分別使用不同的映射技術: - 文件資料庫: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 系統。