筆記、後端資料庫(8-2)理論篇


Posted by s103071049 on 2021-07-15

投影片下面的參考資料要閱讀,名詞要知道在幹嘛
更理論可以先跳過

NoSQL (Not only SQL)

例如 : MongoDB。
通常是存大量的資料會用 麼NoSQL 的資料庫,是一個東西對應到一大筆 json 的資料,不像是一個一個的 row。

1. 沒有結構 SCHEMA,可以想像成存 JSON 的資料進 DB,加任意的欄位進去都可以,想放甚麼就放神麼
2. 用 key-value 存
3. 不支援 join (因為不是關聯式資料庫)
4. 通常用來存取結構不固定的資料 (log 之類)

Transaction

一個 transaction 是一個不可分割的 query 集合

舉例、轉帳
小明轉 $20 給小美 => 操作完成後,小明少 $20,小美多 $20。
這個操作牽涉到兩個 sql query,一個是將小明的錢減 $20,另一個是將小美的錢增加 $20。
所以要馬就這兩個同時完成,要馬就這兩個同時沒完成。(<= 原子性)

實際應用:轉帳、購物(一次買多個品項)、其他一次牽涉到多個 query 的操作。

ACID

為了保障 transaction 的正確性,需要滿足 4 個特性

1. 原子性 (atomicity) : 要馬全部失敗,要馬全部成功
2. 一致性 (consistency) : 維持資料的一致性 ( $ 的總數相同)
3. 隔離性 (isolation) : 多筆交易不會互相影響 (不能同時改同一個值)
4. 持久性 (durability) : 交易成功之後,寫入的資料不會不見

原子性與一致性很容易搞混!!!
隔離性也要注意一下,它的定義!!!
影片:(8分~9分)

如何在 mySql 中用 transaction

如果沒有這個,每執行一個 QUERY 就會變成一個 transaction

$conn->autocommit(FALSE);

接著開啟 transaction 模式

$conn->begin_transaction();

建立 query 們

$conn->query("UPDATE FROM money SET amount = 10");
$conn->query("UPDATE FROM money SET sum = 1000");

執行 sql query 們。commit 如果成功就是兩個 query 一起成功,失敗就是一起失敗。這就是一筆交易。

$conn->commit();

優點:一次更新多筆資料。
可以同時下很多個 query (ex:1000),假設今天要新增一千筆資料,就要執行一千筆 sql query,如果這時候把它放在同一個 transaction 中,全部執行完再 commit 效率會比較快。因為它會一次執行一千個而不是一個一個執行。

型態是 db 的引擎,myISAM 不支援 transaction,所以可以將它調成 innoDB,確保他支援 lock and transaction。

transaction 只是保證一個交易裡的東西,要馬全部成功要馬全部失敗,但要是當兩個東西同時存取一個東西時,會發生 race condition

lock

因為很多東西是非同步,很多東西會被同時處理,所以不知道誰先誰後,有可能兩個 request 同時抵達 server,又因為 server 會同時處理這兩個 request。

以搶購頁面為例,東西會超賣。所以這個時候會需要 lock 將資料鎖起來,在更新之前將資料鎖起來,其他人會存取不到,就可以保證結果是正確的。

lock 要加在 transaction 裡面才會有用。

select 後面加 for update,所以在 for update 時就會將東西鎖起來。

$conn->autocommit(FALSE); 
$conn->begin_transaction();
$conn->query('SELECT amount FROM products for update');
$conn->commit();

透過 for update:假設今天有兩個東西都在執行這個 query,先執行的會先往下跑,後執行的他會停在這邊等,等第一個執行回來後他才會往下跑、才會拿的到資料。

因為要等待,所以會有效能上的損耗。所以如果 for update 後東西就一直停在這邊不釋放的話,程式會當掉、會沒辦法處理任何的 query。因為 row 被鎖起來了。

lock 的等級

如果有指定 id,他就會把那個 row lock 起來

$conn->query('SELECT amount FROM products where id = 1 for update');

如果沒有,就會 lock 整個 table,其他的都沒辦法存取,會有更大效能上的問題。

$conn->query('SELECT amount FROM products for update');

補充、

jmeter 用來測試網頁的好東西

noSQL

https://www.ithome.com.tw/news/92506
http://blog.30cm.net/2017/04/21/%E6%B7%BA%E8%AB%87NoSQL/

ACID

https://www.ithome.com.tw/news/92506
http://blog.30cm.net/2017/04/21/%E6%B7%BA%E8%AB%87NoSQL/
https://www.zhihu.com/question/31346392 (推薦)

TRANSACTION

https://www.ithome.com.tw/news/92506
http://blog.30cm.net/2017/04/21/%E6%B7%BA%E8%AB%87NoSQL/


#NoSQL #acid #Transaction







Related Posts

Chrome devtools extension 實作介紹

Chrome devtools extension 實作介紹

AJAX - HTTP狀態碼

AJAX - HTTP狀態碼

[FE302] React 基礎 - hooks 版本:再戰 todo list 與其他 hooks

[FE302] React 基礎 - hooks 版本:再戰 todo list 與其他 hooks


Comments