第二章:PostGIS 空間資料庫與 AI SQL 生成
如果我們只有 10 個露營區,那把經緯度寫死在程式碼裡就好。但我們有幾百、幾千個露營泊點!我們需要一個資料庫,而且是一個**「懂得處理座標的資料庫」**。 在 Supabase 裡,我們可以開啟強大的 PostGIS 擴充功能!
🎯 本章目標
- 學習如何在 Supabase 開啟 PostGIS 擴充。
- 使用 Vibe Prompt 讓 AI 生成包含
geography格式的 SQL Schema。 - 了解如何透過 SQL 執行「範圍搜尋 (例如搜尋半徑 50 公里)」。
🛠️ 第一步:在 Supabase 啟用 PostGIS
- 登入 Supabase 控制台,進入你的專案 (例如
car_camping_db)。 - 點擊左側選單的 Database。
- 點擊上方的 Extensions。
- 搜尋
postgis。 - 將
postgis的開關切換為 ON。
就這麼簡單!你的資料庫現在擁有強大的空間運算能力了。

🧠 第二步:用 Vibe 生成地理資料表 Schema
現在,我們要請 AI 幫我們建表。這跟 Course 1 不同,我們要明確告訴 AI 使用 PostGIS。
[!TIP] Vibe Prompt (請複製並發送給 AI):
我正在開發一個車泊地圖應用,後端是 Supabase,並且已經開啟了 PostGIS 擴充。請幫我寫一段能在 Supabase SQL Editor 執行的建立資料表的 SQL:資料表名稱:campsites欄位需求:1. id (UUID,主鍵)2. name (文字,營地名稱)3. description (文字,營地描述)4. location (PostGIS 的 geography(Point, 4326) 格式,用來儲存經緯度)5. created_at請附上一個範例,教我如何 INSERT 一筆測試資料 (包含轉換經緯度到 location 欄位的語法)。
AI 會生成類似下方的專業 SQL:
-- 建立資料表
CREATE TABLE public.campsites (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
-- 這是關鍵!使用 PostGIS 的 geography 格式
location geography(Point, 4326) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 為了加速空間搜尋,建立 GIST 索引
CREATE INDEX campsites_location_idx ON public.campsites USING GIST (location);
-- 插入測試資料的範例寫法 (注意 ST_Point 的經度在前、緯度在後)
INSERT INTO public.campsites (name, description, location)
VALUES (
'武陵農場露營區',
'超美的賞櫻勝地',
ST_SetSRID(ST_Point(121.314, 24.364), 4326)::geography
);
[!WARNING] 經緯度順序陷阱! AI 通常會提醒你,在 PostGIS 的
ST_Point函數中,參數順序是(經度 Longitude, 緯度 Latitude),而不是我們常說的「緯經度」。這是一個非常容易踩雷的地方,有了 AI 的提醒,我們就能一次做對!

🔍 第三步:如何搜尋「附近的營地」?
這就是 PostGIS 的價值所在。假設使用者的手機定位在台北市中心,我們只想撈出 50 公里內的營地,該怎麼做? 我們不用自己在後端寫數學公式,直接交給 AI 和資料庫!
[!TIP] Vibe Prompt (向 AI 提問):
在 Supabase 裡,如果我有了上面的 campsites 資料表,我該如何用 Supabase JS Client 或是 SQL,寫一個查詢「距離特定經緯度 (例如 121.5, 25.0) 50 公里內的所有營地」?
這段查詢會是你未來應用程式的核心功能,我們先在資料庫端確認語法正確即可。
✅ 本章小結
你學會了最進階的地理資訊資料庫 (PostGIS) 設定,並且只用了兩段 Prompt 就完成了! 下一章,我們將教你如何把這些資料庫裡的座標,透過 Supabase API 撈回前端,並且變成地圖上一個一個精美的標記 (Markers)!