Database History

🐘 PostgreSQL 的誕生,是一場對「資料庫該長什麼樣子」的重新設計

PostgreSQL 的起點,來自 Stonebraker 團隊發現當時的關聯式資料庫很擅長存表格,卻很難處理更複雜的資料型態,因此乾脆重新設計一套更容易擴充的資料庫。

1970s Ingres1980s POSTGRES1996 PostgreSQL
01

一段名字的演化史

整個歷史可以先用一條簡單的脈絡記下來,後面再展開每一段的背景。

Ingres
POSTGRES
PostgreSQL
1
Ingres(1970 年代)

Stonebraker 早期參與開發 Ingres,這是 1970 年代非常重要的關聯式資料庫研究專案,奠定了他日後對資料庫設計的基礎理解。

2
POSTGRES(1980 年代)

到了 1980 年代,Stonebraker 開始思考一個問題:如果資料庫除了 integerstring 這些基本型態,還希望支援更複雜的物件、規則甚至自訂型態,資料庫架構應該怎麼設計。於是 Berkeley 團隊啟動了新的 POSTGRES 專案。

3
Postgres95 與正式改名(1990 年代)

後來 POSTGRES 加入 SQL 支援,逐漸演變成 Postgres95,最後在 1996 年正式改名為今天熟悉的 PostgreSQL

💡

名字怎麼來的:POST 加上 INGRES 就是 POSTGRES,可以直接理解成「Ingres 之後的下一個系統」,是一個延續前一代研究成果、再往前跨一步的命名方式。

關鍵人物Michael Stonebraker

Stonebraker 厲害的地方在於,他長期都在重新思考資料庫應該怎麼設計,而且很多研究最後真的變成業界使用的系統。他後來還參與了 VerticaVoltDB 等資料庫相關專案,並在 2014 年獲得 ACM 圖靈獎。

02

資料庫應該可以被擴充

PostgreSQL 很重要的一個設計思想,就是資料庫不應該只能接受它原本規定好的資料型態,開發者應該可以自行擴充它。這個想法直接延續自當年 POSTGRES 專案的研究方向。

所以今天使用 PostgreSQL 時,可以看到很多很有特色的能力,例如自訂一個 ENUM 型態:

CREATE TYPE mood AS ENUM (
    'sad',
    'ok',
    'happy'
);

甚至可以安裝 extension,讓 PostgreSQL 直接擁有原本不存在的能力:

CREATE EXTENSION postgis;
🗺️

裝上 postgis 之後,PostgreSQL 就直接擁有了 GIS 地理資料處理能力。這種「資料庫本身可以被擴充」的味道,和 POSTGRES 當年的研究方向有很深的關係。

為什麼特別強調這五個字眼

PostgreSQL 的文件與生態圈裡,經常反覆出現這五個關鍵字,它們都指向同一件事,也就是讓資料庫可以被擴充。

  • Type:可以自訂資料型態,不侷限於內建的 integer、string
  • Extension:可以用套件形式擴充整套能力,例如 postgispgvector
  • Function:可以用多種語言撰寫自訂函式,塞進資料庫內部執行
  • Operator:可以定義新的運算子,讓自訂型態也能參與比較與運算
  • Index Method:可以擴充索引結構,讓新的資料型態也有對應的高效查詢方式
03

為什麼越來越多人選 PostgreSQL

PostgreSQL 越來越多人用,核心原因是它把免費、成熟、功能強、容易擴充同時做到了一個很高的水準,讓新專案在挑選資料庫時通常很難找到明顯的硬傷。

資料來源年份 / 指標數字
Stack Overflow Developer Survey2018約 33% 開發者使用 PostgreSQL
2024成長到約 49%
2025「使用」與「想使用」兩項調查都排名最高
DB-Engines2026 年 8 月所有資料庫中排名第 4,相較 2025 年同期分數增加 13.32;排名在前的是 Oracle、MySQL、SQL Server
📈

綜合這兩份數據比較準確的描述是:PostgreSQL 已經從開源資料庫的其中一個選擇,逐漸變成很多新系統預設會考慮的主力資料庫。

① 免費且能力完整

免費方案已足以支撐大量正式商業系統。

② Cloud 降低維運門檻

備份、升級、HA、監控多半交給雲端服務。

③ 擴充能力強

需求長大時可以先加能力,不急著換資料庫。

① 免費,而且能力已經非常完整

當免費方案已經能處理大量正式商業系統的需求,團隊自然很難說服自己一開始就支付昂貴的資料庫授權費。例如公司要做電商、CRM、ERP、SaaS、會員系統、訂單系統、金融 Backend,很多情況下 PostgreSQL 已經足夠應付。

Backend
PostgreSQL

因此新專案可能直接採用上面這條路徑,而不是先購買商業資料庫授權。

② Cloud 把維運門檻降低很多

以前選擇 PostgreSQL,還代表要懂不少 DBA 工作。現在雲端服務把備份、升級、HA、監控處理掉很多,選 PostgreSQL 的心理成本自然降低。

以前的做法

安裝 PostgreSQL,接著自行設定 replication、backup、failover、monitoring、upgrade,每一步都可能要親自處理。

現在的做法

各種 managed PostgreSQL 服務已經非常普遍,工程師的體驗逐漸簡化成建立 PostgreSQL、拿到 Connection String、開始寫程式。

☁️

這種維運門檻的下降,對 PostgreSQL 的普及非常重要。

③ 擴充能力非常強

PostgreSQL 很有競爭力的地方,是需求長大之後,常常可以先替 PostgreSQL 加能力,而不用立刻把資料搬去另一套資料庫。

users / orders / products
+ metadata JSONB
+ PostGIS
+ pgvector
  • 需要 JSON 資料:加上 metadata JSONB 欄位就能處理
  • 需要地圖或 GIS:安裝 PostGIS extension
  • 需要 Vector Search:安裝 pgvector extension
🧩

DB-Engines 現在甚至直接把 PostgreSQL 標示成同時具備 relational、document、graph、spatial、vector 等多模型能力的資料庫。

④ AI 時代又給 PostgreSQL 一波機會

AI 應用需要 Vector Search,而 pgvector 讓很多已經使用 PostgreSQL 的團隊可以直接把向量放進原本的資料庫,少維護一套系統就是很大的誘惑。

文章
Embedding
Vector
PostgreSQL + pgvector

原本做 RAG 這類應用時,架構可能需要考慮 PostgreSQL 加上一套獨立的 Vector Database。現在部分規模的系統可以先採用 PostgreSQL 加上 pgvector,讓架構少一個元件。

少一個元件的連鎖效果

少一套獨立的 Vector Database,代表少一套權限管理、少一套 Backup 機制、少一套 Monitoring 設定、少一個可能掛掉的地方。這對小型與中型團隊尤其有吸引力。

04

Vector 是什麼

假設要用數字描述一杯飲料,可以自己規定三個維度:維度一是甜度,維度二是酸度,維度三是咖啡味,而且每個數值都介於 0 到 1 之間。

飲料甜度酸度咖啡味
拿鐵0.60.10.8
檸檬汁0.30.90.0
美式咖啡0.10.11.0
📐

把每杯飲料都寫成 [甜度, 酸度, 咖啡味] 這樣的三個數字,就已經建立了一個非常簡單的三維 Vector 空間。

05

Embedding 是把內容轉成座標

Embedding 指的是把文字、圖片等內容轉換成一串 Vector 數字,讓電腦可以用數學方式比較它們的特徵與相似程度。Vector 和 Embedding 其實是上下游關係,原始資料先經過 Embedding,才變成 Vector。

原始資料
Embedding
Vector

人類看到「我要退款」和「我想把錢拿回來」,很自然會知道這兩句話語意接近,但跟「今天天氣很好」差很多。可是電腦如果只看文字表面,「我要退款」和「我想把錢拿回來」兩句話甚至沒有多少相同的字。Embedding 就是用來處理這個落差的。

假設有一個 Embedding Model,分別把三句話轉成 Vector:

flowchart TD
    M["Embedding Model"] --> A["我要退款"]
    M --> B["我想把錢拿回來"]
    M --> C["今天天氣很好"]
    A --> VA["Vector A [0.82, 0.21, -0.55, ...]"]
    B --> VB["Vector B [0.79, 0.25, -0.51, ...]"]
    C --> VC["Vector C [-0.32, 0.91, 0.17, ...]"]
    VA -->|"距離很近"| VB
    VC -.->|"距離很遠"| VA
💬

轉成 Vector 之後,電腦就能實際計算它們之間的距離:Vector AVector B 距離很近,Vector C 跟前兩者距離很遠,這正好對應到語意上「退款」跟「拿回錢」很接近,跟「天氣」無關。

06

Vector Database 到底解決什麼問題

Vector Database 真正有價值的地方,在於能快速找出距離最近的 Vector。單純把一串數字存進 VARCHAR,只完成了保存資料這件事,並沒有辦法回答距離相關的問題。

GPS 類比

這就像把 GPS 座標 25.0330, 121.5654 存成 VARCHAR,當然可以存進去,但接下來如果被問到「找距離這個座標最近的 10 間店」,這串座標就只是一段文字。資料庫並不知道誰比較近、距離多少、要怎麼快速找出最近的 10 個,Vector 的處境也是一樣。

用 100 萬篇文章拆解這個需求

假設有 100 萬篇文章,每篇文章都有各自的 embedding。使用者搜尋「我買的東西可以退錢嗎」,Embedding Model 會把這句話轉成一個 Query Vector。

flowchart LR
    Q["Query Vector [0.79, 0.14, -0.31]"] -->|"比較距離"| R1["Article 1 [0.81, 0.12, -0.33]"]
    Q -->|"比較距離"| R2["Article 2 [-0.21, 0.92, 0.14]"]
    Q -->|"比較距離"| R3["Article 3 [0.77, 0.15, -0.29]"]
    Q -->|"比較距離"| R4["Article 1,000,000 [0.13, -0.54, 0.82]"]
    R1 -->|"距離很近"| TOP["排序後取 Top 5"]
    R3 -->|"距離很近"| TOP
    R2 -.->|"距離很遠,排除"| TOP
    R4 -.->|"距離很遠,排除"| TOP
🎯

核心需求變成:在 100 萬個 Vector 裡,快速找出跟目標 Vector 最接近的 Top 5。這才是 Vector Database 真正要解決的問題。

07

把 Vector 存成 VARCHAR 會卡在哪裡

假設真的把 Vector 存成 VARCHAR

CREATE TABLE articles (
    id BIGINT,
    content TEXT,
    embedding VARCHAR(10000)
);
idcontentembedding
1如何退款[0.81,0.12,-0.33]
2如何修改密碼[-0.21,0.92,0.14]
3商品退貨流程[0.77,0.15,-0.29]

存進去完全沒問題,但如果要查詢距離最近的 5 筆:

SELECT *
FROM articles
ORDER BY ???
LIMIT 5;

ORDER BY 後面要接什麼,會發現需要先完成一連串手動加工才能做到:

  1. VARCHAR 解析成數字陣列
  2. 把每個維度拿出來
  3. 計算跟目標 Vector 的距離
  4. 跟大量資料逐筆比較
  5. 依距離排序
  6. 取出 Top 5
⚠️

VARCHAR 本身沒有 Vector 的數學語意,資料庫不知道怎麼對一段純文字計算距離,所有加工都要應用程式自己處理。

08

PostgreSQL 加上 pgvector 差在哪裡

裝了 pgvector 之後,可以直接宣告一個真正的 Vector 型態欄位:

CREATE TABLE articles (
    id BIGSERIAL PRIMARY KEY,
    content TEXT,
    embedding vector(1536)
);

資料庫現在真正知道 embedding 是一個 1536 維的 Vector,所以可以直接進行 Vector Distance Search:

SELECT *
FROM articles
ORDER BY embedding <-> '[0.79, 0.14, ...]'
LIMIT 5;
目標 Vector
跟 embedding 比較距離
距離由小到大排序
回傳最近 5 筆

這一段 ORDER BY embedding <-> '...' 已經跟 VARCHAR 存法有本質上的差異,資料庫自己知道怎麼計算距離,不需要應用程式手動解析。

09

Vector Index 為什麼重要

當 Vector 數量很大時,真正讓搜尋實用的能力之一,是透過專門的 Vector Index,避免每次查詢都要完整掃描所有 Vector。pgvector 支援例如 HNSWIVFFlat 這類索引結構,不需要先研究背後演算法,只需要知道它們的目的是縮小搜尋範圍。

沒有適合的 Index

100 萬個 Vector 全部逐一比較,才能找出 Top 10。

有 Vector Index

先利用索引縮小搜尋範圍,再找出 Top 10。

🗂️

這有點類似以前熟悉的 SQL Index,例如查詢 WHERE user_id = 9527 時,不會希望資料庫在 1000 萬筆使用者裡逐筆比對,才終於找到 9527,所以會建立 B-tree index。Vector Search 也有類似的需求,只是「找最相似資料」跟「等值查詢 user_id」是不同性質的問題,因此使用的索引結構也不一樣。

flowchart TD
    PG["PostgreSQL"] -->|"傳統條件查詢"| SQL["SQL 世界:price < 3000、stock > 0"]
    PG -->|"語意相似度查詢"| VEC["Vector 世界:語意是否相似、日系 / 夏天 / 簡約"]
    SQL --> RESULT["搜尋結果"]
    VEC --> RESULT
🐘

同一個 PostgreSQL,一邊處理傳統的條件式 SQL 查詢,一邊處理語意層面的 Vector 相似度查詢,最後匯回同一份搜尋結果,這正是 PostgreSQL 擴充能力在 AI 時代最直接的體現。