dramaling-vocab-learning/docs/03_development/api/supabase-schema.md

6.1 KiB
Raw Blame History

Supabase 資料庫架構文檔

資料表結構

1. profiles 表

用戶基本資料表,與 auth.users 關聯

欄位 類型 說明 限制
id UUID 用戶ID PRIMARY KEY, 關聯 auth.users
email TEXT Email UNIQUE
username TEXT 用戶名稱 可選
created_at TIMESTAMP 建立時間 自動產生
updated_at TIMESTAMP 更新時間 自動更新

2. flashcards 表

詞卡資料表,儲存所有詞卡內容

欄位 類型 說明 限制
id UUID 詞卡ID PRIMARY KEY
user_id UUID 擁有者ID FOREIGN KEY → profiles
word VARCHAR(255) 單字/片語 NOT NULL
translation TEXT 中文翻譯
context TEXT 使用情境
example TEXT 例句
pronunciation TEXT 發音/音標
difficulty INTEGER 難度等級 1-5, DEFAULT 3
next_review_date DATE 下次複習日期 DEFAULT 今天
review_count INTEGER 複習次數 DEFAULT 0
ease_factor DECIMAL(3,2) SM-2 難度係數 DEFAULT 2.5
interval INTEGER 複習間隔(天) DEFAULT 1
created_at TIMESTAMP 建立時間 自動產生
updated_at TIMESTAMP 更新時間 自動更新

3. study_sessions 表

學習記錄表,追蹤每次複習

欄位 類型 說明 限制
id UUID 記錄ID PRIMARY KEY
user_id UUID 用戶ID FOREIGN KEY → profiles
flashcard_id UUID 詞卡ID FOREIGN KEY → flashcards
rating INTEGER 評分 1-5 (1=完全忘記, 5=非常簡單)
studied_at TIMESTAMP 學習時間 自動產生

4. tags 表

標籤表,用於分類詞卡

欄位 類型 說明 限制
id UUID 標籤ID PRIMARY KEY
name VARCHAR(100) 標籤名稱 NOT NULL
user_id UUID 建立者ID FOREIGN KEY → profiles
created_at TIMESTAMP 建立時間 自動產生

5. flashcard_tags 表

詞卡-標籤關聯表

欄位 類型 說明 限制
flashcard_id UUID 詞卡ID FOREIGN KEY → flashcards
tag_id UUID 標籤ID FOREIGN KEY → tags

PRIMARY KEY: (flashcard_id, tag_id)

Row Level Security (RLS) 政策

profiles 表政策

-- 用戶只能查看自己的資料
SELECT: auth.uid() = id

-- 用戶只能更新自己的資料
UPDATE: auth.uid() = id

flashcards 表政策

-- 用戶只能查看自己的詞卡
SELECT: auth.uid() = user_id

-- 用戶只能建立屬於自己的詞卡
INSERT: auth.uid() = user_id

-- 用戶只能更新自己的詞卡
UPDATE: auth.uid() = user_id

-- 用戶只能刪除自己的詞卡
DELETE: auth.uid() = user_id

study_sessions 表政策

-- 用戶只能查看自己的學習記錄
SELECT: auth.uid() = user_id

-- 用戶只能建立自己的學習記錄
INSERT: auth.uid() = user_id

tags 表政策

-- 用戶只能查看自己的標籤
SELECT: auth.uid() = user_id

-- 用戶只能建立屬於自己的標籤
INSERT: auth.uid() = user_id

-- 用戶只能更新自己的標籤
UPDATE: auth.uid() = user_id

-- 用戶只能刪除自己的標籤
DELETE: auth.uid() = user_id

資料庫函數

handle_new_user()

自動為新註冊用戶建立 profile

CREATE OR REPLACE FUNCTION handle_new_user()
RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO public.profiles (id, email)
  VALUES (new.id, new.email);
  RETURN new;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

update_updated_at()

自動更新 updated_at 欄位

CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = TIMEZONE('utc'::text, NOW());
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

觸發器

on_auth_user_created

新用戶註冊時自動建立 profile

CREATE TRIGGER on_auth_user_created
  AFTER INSERT ON auth.users
  FOR EACH ROW EXECUTE FUNCTION handle_new_user();

update_flashcards_updated_at

更新詞卡時自動更新 updated_at

CREATE TRIGGER update_flashcards_updated_at
  BEFORE UPDATE ON flashcards
  FOR EACH ROW EXECUTE FUNCTION update_updated_at();

索引建議

為了優化查詢效能,建議建立以下索引:

-- 詞卡查詢優化
CREATE INDEX idx_flashcards_user_id ON flashcards(user_id);
CREATE INDEX idx_flashcards_next_review ON flashcards(user_id, next_review_date);

-- 學習記錄查詢優化
CREATE INDEX idx_study_sessions_user_id ON study_sessions(user_id);
CREATE INDEX idx_study_sessions_flashcard_id ON study_sessions(flashcard_id);
CREATE INDEX idx_study_sessions_studied_at ON study_sessions(user_id, studied_at DESC);

-- 標籤查詢優化
CREATE INDEX idx_tags_user_id ON tags(user_id);
CREATE INDEX idx_flashcard_tags_flashcard ON flashcard_tags(flashcard_id);
CREATE INDEX idx_flashcard_tags_tag ON flashcard_tags(tag_id);

常用查詢範例

取得今日需要複習的詞卡

SELECT * FROM flashcards
WHERE user_id = auth.uid()
  AND next_review_date <= CURRENT_DATE
ORDER BY next_review_date ASC, difficulty DESC;

取得用戶學習統計

SELECT
  COUNT(DISTINCT flashcard_id) as total_reviewed,
  COUNT(*) as total_reviews,
  DATE(studied_at) as study_date
FROM study_sessions
WHERE user_id = auth.uid()
  AND studied_at >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY DATE(studied_at)
ORDER BY study_date DESC;

取得詞卡及其標籤

SELECT
  f.*,
  ARRAY_AGG(t.name) as tags
FROM flashcards f
LEFT JOIN flashcard_tags ft ON f.id = ft.flashcard_id
LEFT JOIN tags t ON ft.tag_id = t.id
WHERE f.user_id = auth.uid()
GROUP BY f.id;

資料備份策略

  1. 自動備份: Supabase 提供每日自動備份Pro 計劃)
  2. 手動備份: 定期匯出重要資料表
  3. 備份腳本:
# 匯出資料
pg_dump -h [SUPABASE_HOST] -U postgres -d postgres > backup.sql

# 還原資料
psql -h [SUPABASE_HOST] -U postgres -d postgres < backup.sql

效能監控

定期檢查以下指標:

  • 查詢執行時間
  • 索引使用率
  • 資料表大小
  • 連線數量

使用 Supabase Dashboard 的 Database Health 功能監控資料庫狀態。