PostgreSQL-Constraint學習筆記

前言 這篇文章主要是探討 PostgreSQL 的 Constraints 情境下的幾種 ACTION,以作為一個簡單的學習紀錄 何謂 Constraint? 眾所皆知,Foreign key(FK) 是 Table 中一個或一組用來關聯另一張表的 Primary key(PK) 的欄位,其中: 關聯另張表的表叫做 referencing table 或 child table 被關聯的表則稱為 referenced table 或 parent table 當 parent table 的某欄位和 child table 的某欄位有關聯時,例如: PK(Primary Key)和 FK(Foreign Key)的關係時,此時對 parent table 這個欄位做出修改(update)或刪除(delete)的操作,勢必會連帶影響到 child table。此時,child table 就需要明確的告訴 parent table,該筆操作對 child table的欄位要有什麼影響(ACTION)? 所以如何決定這些跨表參照欄位的存亡關係,就取決於 Constraint 的設定.換言之,SQL 透過 Constraint 的限制來協助我們維持父子表之間的參照完整性(referential integrity) 而 Constraint 又分為被更新(ON_UPDATE)以及被刪除(ON_DELETE)時,分別有對應的影響(ACTION)可以設定,實務上有 PK 和 FK 關係的欄位,大多會用 ON_DELETE居多. 在 PostgreSQL 中的語法結構大致如下(參考該網站): [CONSTRAINT fk_name] FOREIGN KEY(fk_columns) REFERENCES parent_table(parent_key_columns) [ON DELETE delete_action] [ON UPDATE update_action] ACTION 有哪些? 可設置的 delete_action 和 update_action 都稱為 ACTION,分為以下幾種:...

<span title='2023-01-25 19:49:13 +0800 +0800'>January 25, 2023</span>&nbsp;·&nbsp;3 min&nbsp;·&nbsp;527 words&nbsp;·&nbsp;Madi

初探Caddy搭建AWS EC2的HTTPS Web Server

前言 前陣子使用 AWS 的 EC2 來部署一個測試用的 backend api,以利 Netlify 上的前端網站作溝通,但因為近代瀏覽器(ex: Chrome…)遵守 CSP(Content-Security-Policy) 限制,避免 HTTPS 協定的網站前端 javascript 透過 fetch 方式去索取 HTTP 協定的任何資源,以避免 MIT(中間人攻擊),所以勢必得將自身 backend 的網域加上憑證,起初想到用 Nginx 搭配 Let’s Encrypt 來定期每三個月更新憑證,但後來發現 Caddy 更好用更簡潔,就順手紀錄一下操作的歷程。 Caddy 介紹 Caddy 是一個功能強大、可擴充的平台,可以提供(serve)服務或網站,底層是用 Go 撰寫的,依照 Caddy 官網所說,它不僅僅能作為 Web server 或是 proxy,更能作為 server of servers. Caddy 預設以 HTTPS 為通訊協定(也支援 HTTP/2),支援 gzip 壓縮,而且不再需要每三個月定期去 Let’s Encrypt 更新憑證,因為 caddy 會自動幫我們更新憑證。此外,運行時不仰賴其他套件或 runtime,可獨立 host 在 container 內。依照官網所說,caddy 已經是 production-ready,可以取代上一世代的 Nginx 或 Apache。 前置作業:創建 EC2 首先,我先在 AWS 上創建 EC2 的 instance:...

<span title='2023-01-24 09:32:04 +0800 +0800'>January 24, 2023</span>&nbsp;·&nbsp;3 min&nbsp;·&nbsp;487 words&nbsp;·&nbsp;Madi

[閱讀筆記] Transactionally Staged Job Drain in PostgreSQL

前言 前陣子因為某接案需求要研究 Medusa 這個開源的電商專案,發現底層設計的 Event Architecture 有參考到 Transactionally Staged Job Drain 這個事務處理機制,因此拜讀了一下這篇 2017 年的文章,當時作者也在 Hacker News 上與網友有不少討論,相信對於研究底層的設計可以讓自己功力提升,因而有了這篇文章的誕生. 問題描述:Event Queue + ACID 聲明:本篇取材自 Transactionally Staged Job Drain 的整理消化,圖片皆來自於此. 文章探討的情境是: 任務佇列(Job Queue)消化的速度太快,導致後台服務(background worker)在該事務 commit 前就嘗試取用,進而無法訪問到預期可用的資料,也就是如何搭配 ACID 與 Event Queue 解決上述事務的問題. 底下是一個顯而易見的例子: BEGIN TRANSACTION; /* db_op1 */ INSERT INTO USER(id, name, age, email) VALUES (1, 'Madi', 27, 'example@gamil.com'); /* queue_job */ -- Some enqueuer worker /* db_op2 */ INSERT INTO USER(id, name, age, email) VALUES (2, 'Kevin', 20, 'example2@gamil....

<span title='2023-01-22 00:49:13 +0800 +0800'>January 22, 2023</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;421 words&nbsp;·&nbsp;Madi

Git Submodule 學習筆記

前言 最近用 Hugo 重新架了新的部落格,部落格本身是一個 git repo,但 Theme 的資料夾的內容是另一個 git repo,導致在不同電腦想要同步部落格內容時,遇到 Git Submodule 的議題,是一個實務開發上較少遇到的情境,所以順手紀錄一下操作記錄. 何謂 Git Submodule? 使用 Git Submodule 的情境是在開發專案時資料夾內有第三方 Library 或你正單獨開發並被多個父專案使用的子專案,此時你想要將兩個專案視為獨立的,但又希望可以在其中一個專案使用到另一個專案的內容. Git Submodule 其實就是一個巢狀的 Git 檔案結構,他會幫你把專案內某個子資料夾視為 Library 處理,不會受到主專案的 Git 操作影響. 以下是我遇到 Git Submodule 的情境: 我的部落格資料夾內含有 Theme 主題,部落格資料夾是父資料夾,而 Theme 是子資料夾,因為他參照的是另一個第三方的 git remote url,也就是一個第三方維護的靜態主題專案,未來我可能會需要同步他上面最新的更新,或是切換到他專案某個時間的 commit,這時候我就需要將他視為和我部落格是不同的專案,但彼此卻又需要被互相引用,這時候 Git Submodule 就可以很好的幫我解決這個問題. 實戰演練 為了模擬巢狀的 Git 結構,在 GitLab 上分別建立一組父子專案,父專案名稱是 Parent,子專案名稱是 Child.建立好之後,分別 clone 到本地端的 parent 和 child 資料夾. . ├── child │ └── README.md └── parent └── README....

<span title='2023-01-20 19:49:13 +0800 +0800'>January 20, 2023</span>&nbsp;·&nbsp;3 min&nbsp;·&nbsp;560 words&nbsp;·&nbsp;Madi

細究Content-Type的Multipart/form-data

前言 前陣子開發時,遇到 Node.js 上傳檔案到某個 file storage 時的問題,後來深入研究了一下上傳檔案時的 Content-Type: multipart/form-data,順手記錄一下,也透過常用套件 multer, busboy 的原始碼來驗證這些機制的存在。 何謂 boundary? 網路世界中,HTTP 協定定義了 Content-Type 標頭檔來規範資料傳遞的格式, 其中表單(Form)提交是很常見的情境,而表單提交的 Content-Type 主要有三種,並寫在 form 的 enctype 屬性裏頭: application/x-www-form-urlencoded multipart/form-data text/plain 第一種 application/x-www-form-urlencoded 會被表單轉換成 url 帶上 query params 的格式,例如: ?name=Madi&age=20,使用 & 符號作為參數的分隔符(Delimiter)。 第二種 multipart/form-data 就是本篇文章要探討的主角,他也有類似 application/x-www-form-urlencoded 的分隔符 &,但是是使用 boundary 作為分隔符,在上傳檔案的 Request Header 都可以看見它的存在,而主要目的就是透過這個分隔符來區分不同格式的資料,例如圖片、檔案、影片…等等。 boundary 可以是任意符合 ascii-7 的字元,可以自己定義他的值,但開頭需要兩個 hyphen(連字號-),且長度須限制於 70 字元以內。當送出請求的 Content-Type 是 multipart/form-data時,強制規定必須帶上 boundary才能成功派送,但若是使用瀏覽器來發送,他會自己幫我們帶上一組 boundary。 例如,底下寫個簡單的 fetch,帶上 local 的某個文字檔 <script> const formData = new FormData(); formData....

<span title='2023-01-18 19:49:13 +0800 +0800'>January 18, 2023</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;294 words&nbsp;·&nbsp;Madi