# 第十六堂:資料庫與後端常見 QA * 記得錄影 ## 問題一:如何在docker上用postgreSQL創建資料表 需要透過後端來達到,[範例程式碼](https://github.com/hexschool/node-training-postgresql) ## 問題二:postgreSQL 和 MySQL 的差異 | **比較面向** | **PostgreSQL** | **MySQL** | | --- | --- | --- | | **性能** | - 複雜查詢與高並發性能佳- 索引類型多樣(支援 B-Tree、GIN、GiST) | - 讀取速度快,對簡單查詢效能佳- InnoDB 在主鍵查詢時具有優勢 | | **ACID 與事務管理** | - 完整 ACID,相容性高- MVCC 及 DDL 可回滾 | - 取決於引擎 (InnoDB 完全 ACID)- 8.0 開始支援單語句原子 DDL | | **可擴展性與高可用性** | - 原生分區功能- WAL 串流複製穩定 (異/同步)- 多主需第三方工具 | - 易於讀寫分離- 二進制日誌複製成熟- 提供多主集群解決方案 (Group Replication, NDB) | | **JSON / NoSQL 支援** | - JSON/JSONB 原生支援強- 可對 JSONB 建索引,函式/運算符豐富 | - 提供 JSON 資料類型- 透過 Generated Columns 對 JSON 路徑進行索引 | | **安全性** | - 角色/行級安全 (RLS)- 多種認證方式(SCRAM, Kerberos... ) | - 權限控制傳統且較簡單- 需透過外掛實現行級安全 | | **社群與支持** | - 社群主導,開源度高- 許多擴充(地理 PostGIS、時序 TimescaleDB) | - 廣泛使用度,社群龐大- Oracle 提供企業版 (付費) 與開源社群版 | | **適用場景** | - OLAP、複雜交易、多租戶與 JSON/地理場景 | - 讀多寫少的 Web 應用、LAMP 架構 | | **價格與授權** | - 免費 + BSD/MIT 類授權 (PostgreSQL License)- 無功能區分 | - 開源版採 GPLv2 授權- 企業版需付費,可獲 Oracle 商業支援 | **總結:** - **PostgreSQL**:功能完備,適合高併發、複雜查詢、JSON/地理空間等需求。 - **MySQL**:部署簡單、讀取量大時效能突出,適合一般 Web/輕量應用。 - 選型可視資料特性、工作負載模式與團隊經驗而定,兩者都十分成熟且有強大社群支持。 ## 問題三:六角學院後台運作的資料庫設計 - grafana - AWS,沒有用 redis - 分享開發心路歷程 ![截圖 2025-03-06 下午4.07.48](https://hackmd.io/_uploads/SJsxu0Lo1l.png) ## 問題四:許願mysql & mongodb&要如何將資料庫內容匯出並於另一台電腦資料庫匯入 ``` 一、MySQL 1. 匯出 (Export) 使用 mysqldump 指令: mysqldump -u [使用者名稱] -p [資料庫名稱] > [匯出檔名].sql 2. 匯入 (Import) mysql -u [使用者名稱] -p [資料庫名稱] < [匯出檔名].sql 二、MongoDB 1. 匯出 (Export) mongodump --db [資料庫名稱] --out ./mongodb_backup/ 2. 匯入 (Import) mongorestore --db [要匯入的資料庫名稱] ./mongodb_backup/[資料庫名稱]/ ``` ## 問題五:本地端如何存取 Docker 內的檔案資料,拿來用在開新容器時可以還原 假設有個跑一陣子的容器 my_container,想把容器內的某些檔案或整個資料夾抓到本地端做備份: ``` docker cp my_container:/app/data /home/user/backup_data ``` my_container:/app/data:容器裡的路徑 /home/user/backup_data:本地要放置的路徑 備註: docker cp 只會在執行複製指令的 當下 抓取容器內資料,並不會持續同步。 ## 問題六:許願任務二第五題延伸題:計算王小明剩餘時數跟dbeaver怎麼用,跟後端實際是怎麼用dbeaver,docker這些工具 [挑戰題] 查詢:請在一次查詢中,計算用戶王小明的剩餘可用堂數查詢,顯示須包含以下欄位: user_id , remaining_credit ![improved-sql-flow-diagram](https://hackmd.io/_uploads/S1QvHCUoye.svg) ```sql= SELECT ("CREDIT_PURCHASE".total_credit - "COURSE_BOOKING".used_credit) AS remaining_credit, "CREDIT_PURCHASE".user_id FROM ( -- 子查詢 1:計算總購入堂數(total_credit) SELECT "CREDIT_PURCHASE".user_id, SUM("CREDIT_PURCHASE".purchased_credits) AS total_credit FROM "CREDIT_PURCHASE" WHERE "CREDIT_PURCHASE".user_id = ( SELECT id FROM "USER" WHERE email = 'wXlTq@hexschooltest.io' ) GROUP BY "CREDIT_PURCHASE".user_id ) AS "CREDIT_PURCHASE" INNER JOIN ( -- 子查詢 2:計算已使用堂數(used_credit) SELECT "COURSE_BOOKING".user_id, COUNT(*) AS used_credit FROM "COURSE_BOOKING" WHERE "COURSE_BOOKING".user_id = ( SELECT id FROM "USER" WHERE email = 'wXlTq@hexschooltest.io' ) AND "COURSE_BOOKING".status != '課程已取消' GROUP BY "COURSE_BOOKING".user_id ) AS "COURSE_BOOKING" ON "COURSE_BOOKING".user_id = "CREDIT_PURCHASE".user_id; ``` ## 問題七:wireframe時會怎麼拆解對應功能的資料表 - db 欄位設計請依照 [此資料庫欄位圖片](https://firebasestorage.googleapis.com/v0/b/hexschool-courses.appspot.com/o/hex-website%2Fnode%2F1739179853094-fitness_5.png?alt=media&token=a65de209-3ae6-4263-bdc0-d4f08638ff20) 定義