SQL NoSQL

前端工程師邁向後端之路 2 – 淺談 SQL NoSQL:database 簡介

根據上一篇文章:前端工程師邁向後端之路 1 – server 是什麼?database server 可以說是 web application 不可或缺的一環,因此接下來就稍微介紹一下 database 。

database 通常分為兩大類:RDBMS ( Relational Database Management System )、 NoSQL ( Not only SQL ) ,也就是所謂的關聯式資料庫和非關連式資料庫。

1. RDBMS

在關聯式資料庫中,通常使用 SQL ( Structured Query Language ) 語言來對資料庫做 CRUD ( Create, Read, Update, Delete ) 的操作,因此當提到 「 SQL 與 NoSQL 」時可以將 SQL 視為 RDBMS 的意思。

以下會使用到 SQL 的基礎語法,不過都是很基礎的語法,看字面上的意思也可以推敲出一二,如果你有興趣更深入了解 SQL 可以參考這篇文章:簡明 SQL 資料庫語法入門教學

1.1 RDBMS 的架構

通常一個 database server 可以有許多個 database ,各 database 是獨立的,因此一般來說 1 個 web application 只會對應到 1 個 database。而每個 database 由許多 table 所組成,table 內有多筆資料,一筆資料為一個 row 。

SQL NoSQL

可以將 database 視為一個 excel 檔案,將 table 視為 excel 檔案裡面的工作表。

SQL NoSQL
SQL NoSQL

1.2 何謂關聯?

那麼為什麼叫做關聯式資料庫呢?舉個最實際的例子:

假設我的 database 裡有兩個 table ,並且加入一些初始資料如下:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  username VARCHAR
)
SQL NoSQL
CREATE TABLE orders (
  id SERIAL PRIMARY KEY,
  productname VARCHAR,
  user_id INTEGER REFERENCES users(id)
)
SQL NoSQL

在新增 orders 這個 table 的時候,可以看到 user_id INTEGER REFERENCES users(id) ,代表我將 orders 中的 user_id 和 users table 中的 id 做關聯,當我希望同時顯示兩個 table 的某些欄位的資料時,就可以利用這層關聯,舉例來說,雖然 username 並不存在 orders table 中,但我可以利用 user_id 和 users table 中的 id 關聯來做查詢:

SELECT orders.*, users.username
FROM orders
JOIN users
ON users.id = orders.user_id;

結果如下:

SQL NoSQL

這就是 RDBMS 最核心的觀念,將相關的欄位「 關聯 」起來,以便查詢資料。

1.3 何謂 table schema ?

當我們在 create table 時,必須同時定義這個 table 的 schema ,以剛剛 create 的 users table 為例:

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  username VARCHAR
)

這個 table 的欄位就是 id, username ,必須事先定義 schema 的壞處就是,當日後希望擴充資料的欄位時,table 的欄位也必須先擴充,舉例來說,當我今天 user 多了 age 的欄位,當我要新增資料時:

INSERT INTO users (username, age) VALUES (Jed, 20);
-- column "age" of relation "users" does not exist

就會出現 error,正確的作法應該要如下:

-- 在 table 新增 age 欄位
ALTER TABLE users ADD COLUMN age INTEGER;
-- 再新增資料
INSERT INTO users (username, age) VALUES (Jed, 20);

因此若是採用 RDBMS 的設計,那麼 database 的 schema design 就非常重要,因為一旦欄位需要擴充或是做其他關聯就會是一項大工程。

1.4 RDBMS 的特性:ACID

在說明 ACID 以前,先提一下 Transaction 這個觀念:

Transaction ,中文交易的意思,想像一下,今天有個朋友跟你說他想加入東森直銷,需要跟你借 50,000 塊開店,看在你們交情不錯的份上你也決定借他,而你的帳戶有 100,000 塊,朋友的帳戶則是完全沒錢,因此用 SQL 操作的話如下:

-- 原本 100,000 ,借給朋友後把存款更新為 50,000
UPDATE bank SET deposit = 50000 WHERE user_name = Jimmy;
-- 原本 0 ,收到你的錢後更新為 50000
UPDATE bank SET deposit = 50000 WHERE user_name = Jed;

當你在 ATM 上輸入完匯款金額後,按下確定的那一瞬間,銀行的 database server 大當機,而銀行的 databse 剛好執行完第一行 SQL ,也就是你的帳戶已經被扣款,然而銀行系統當機而沒有執行第二行 SQL,因此朋友並沒有收到錢。這個問題不得了了,於是銀行想出了一個機制來解決問題,也就是 ACID 。

其實 ACID 有點像是在 git 上開 branch ,當需要開發新功能時,我們會在 git 上開 branch 等到功能開發完成再 merge 回 master,如果該功能開發失敗,或是客戶後來覺得不需要等等,就直接把整個 branch 捨棄掉。

而在匯款的時候你也會希望:如果匯款程序已經開始,要馬匯款不成功 ⏤ 我的帳戶沒扣到錢,朋友的帳戶也沒有錢入帳;要馬匯款成功 ⏤ 我的帳戶被扣到錢,朋友的帳戶也有錢入帳,不希望會有只執行到一半的情形發生。

-- 以 PostgreSQL 語法為例
-- 開始 transaction
BEGIN;
UPDATE bank SET deposit = 50000 WHERE user_name = Jimmy;
UPDATE bank SET deposit = 50000 WHERE user_name = Jed;
-- 成功,更新資料庫
COMMIT;
-- 失敗,捨棄整個 transaction 的操作
ROLLBACK;

ACID 分別代表 Atomicity, Consistency, Isolation, Durability,以下分別解釋一下這 4 種特性:

1.4.1 Atomicity

Transactions 通常包含多個指令 ( 上述例子即為 2 個指令 ) ,Atomicity 的特性可以將整個 Transaction 視為一個執行單位 ⏤ 若是成功,則 transactions 中的指令全部被執行成功,並且更新 database ;若是失敗,則 Transactions 中的指令全部執行失敗 ( 也就是不執行,database 為執行 transaction 之前的樣子 )。

也就是說有了 Atomicity 原則後,剛剛的 SQL 執行完第一行後 database 就算當機了,整個 transaction 會被 rollback,資料庫會維持執行這個 transactions 之前的樣子,若是這個 transactions 中的所有指令都成功執行了,那會將這個 transaction 的結果 commit 回 database ( 可以理解為更新 database )。

1.4.2 Consistency

Transactions 成功或失敗, database 中的資料都必須符合所定義的 schema ,不能 transactions 成功後發現朋友的帳戶竟然不是數字,變成了字串 ( Jimmy ) 之類的。

1.4.3 Isolation

Database 允許多個 transactions 同時進行,而 isolation 的特性指的是當 transaction 在執行的過程當中,其改變的 data 並不被其他 transaction 所看見。

以剛剛的借款為例,當執行完第一個 SQL 後,你的存款為 50,000 ,而你朋友的存款為 0,但對其他 transactions 來說,他們看到的是你的存款為 100,000 ,而你朋友的存款為 0,因為這個 transaction 還沒執行完畢。

1.4.4 Durability

Transactions 執行完成後,對資料的更新就是永久性的,並不因為系統故障或其他原因而改變資料。

1.5 常見的 RDBMS

目前較常見的 RDBMS 有: MySQL, PostgreSQL, MariaDB ( MySQL 被收購後的開源分支 )。其中關於 PostgreSQL 和 MySQL 的比較可以參考 PostgreSQL 的官方文件:PostgreSQL vs MySQL – PostgreSQL 常見問題

其中 PostgreSQL 比較特別,除了 RDBMS 外還支援 NoSQL 的 JSONB 欄位,再加上筆者目前的工作是使用 PostgreSQL ,因此日後文章也會以 PostgreSQL 做為主要的 database。

2. NoSQL

NoSQL 指的是 Not Only SQL ,也就是不把資料庫侷限在關聯式資料庫的設計。


2.1 NoSQL 的種類

NoSQL 的種類有:

  • Document Oriented Database
  • Key-value Oriented Database
  • Column Oriented Database
  • Graph Oriented Database
  • In-memory Database
  • Search Database

這邊就以最常見的 Document Oriented Database 來討論。

2.2 NoSQL 的架構

Document Oriented Database 中的 document 和 collections 對應到 RDBMS 的部分就是 rows 和 table ,簡單來說每一筆資料都是 document ,多筆 documents 組成 collections。

在 Document Oriented Database 中,資料是以類似 JSON 的資料儲存在 database 中 ( 以 mongoDB 為例,以 BSON 儲存;以 PostgreSQL 為例,以 JSONB 儲存 ),如下:

SQL NoSQL

database 會將該筆資料作為 document 存在 collection 當中。

以 mongoDB 為例,資料的結構如下:

SQL NoSQL

2.3 Schema-free

和 RDBMS 不一樣,NoSQL 是不需要事先定義 schema 的,也就是說日後即便資料的欄位增加,也可以直接將資料存到 collection 當中,資料結構比 RDBMS 彈性許多。

以 mongoDB 為例,儲存資料時是將一個 JSON 存進 collection 裡,他並不在乎你這個 JSON 有什麼欄位,因此相對 RDBMS 來說,資料結構的定義寬鬆許多。

2.4 NoSQL 的特性:CAP

由於 NoSQL 經常用於處理巨量資料,因此也較常使用在分散式系統上,而 CAP 則是針對分散式系統所提出的理論,以下以 node 作為分散式系統的儲存單位:

2.4.1 Consistency

確保每個 node 的資料都一樣。

2.4.2 Availability

每次向 database server 發出 request ,都可以取得 response ,但不保證 response 為最新的資料。

2.4.3 Partition tolerance

當 node 有錯誤時,並不會影響系統的運作。

根據 CAP 的理論,分散式系統不可能同時滿足以上 3 個特性,因此目前的 NoSQL 都是滿足其中的 2 個特性,另一個的支援就比較差。

想深入瞭解 CAP 與 NoSQL 的關係可以參考:初步認識分散式資料庫與 NoSQL CAP 理論

2.5 NoSQL 的特性:ACID … ?

看了滿多文章都說 NoSQL 是不完整支援 ACID 的特性的,但有看到 mongoDB 在版本 4.0 以後其實已經支援 transactions 了 ( 資料來源:ACID Transactions in MongoDB ) ,所以在使用 NoSQL 之前還是先確認一下官方 document 有沒有完整支援 ACID ,這樣也比較能夠知道 database 是否有符合自己的應用需求。

3. SQL or NoSQL

那麼什麼樣的情況下該用 SQL ,什麼情況下該用 NoSQL 呢?一般來說,當 web application 的規模還沒有太大時,會選擇使用 RDBMS ,等到成長到高流量時才會考慮到使用 NoSQL ,可以參考這篇文章:RDBMS (關聯式資料庫) – ACID 基礎觀念 的開頭和總結,個人覺得分析的滿實際的。

談完 SQL 和 noSQL 的差別後,接著就要來實際架設 database server 啦:前端工程師邁向後端之路 3 – PostgreSQL 教學:架設 database server

4. 參考資料

Kenny – RDBMS (關聯式資料庫) – ACID 基礎觀念
[筆記] RDBMS v.s. NoS – 邁向王者的旅途
ACID – Wikipedia
ACID properties of transactions – IBM
NoSQL入門介紹及主要類型資料庫說明 – TPIsoftware
什麼是 NoSQL?| 非關聯式資料庫,彈性的結構描述資料模型 | AWS
NoSQL 之CAP 定理與挑選| Tsung’s Blog
初步認識分散式資料庫與 NoSQL CAP 理論

看完這篇文章是不是想換工作了呢(咦?那就千萬別錯過 2024 職涯博覽會!想換工作的,有機會在博覽會遇見更好的另一半,不想換工作的,有機會在博覽會遇見更好的工作!趕快點擊下面的 banner,拯救你的人生!!!https://s.yourator.co/jimmy

如果覺得我的文章有幫助的話,歡迎幫我的粉專按讚哦~謝謝你!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top