数据库系统
HappyShip 使用 Supabase 作为数据库解决方案,提供强大的 PostgreSQL 数据库功能。本文档将详细介绍模板中的数据库架构设计、表结构、以及核心数据操作。
📋数据库概述
HappyShip 模板的数据库系统特点:
- 基于 Supabase PostgreSQL 数据库
- 完整的用户管理和认证系统
- 积分系统和订阅管理
- 与 Stripe 支付系统深度集成
- 服务端和客户端双重数据访问
🏗️数据库架构
我们的数据库架构设计简洁而强大,主要由两个核心表组成,能够满足用户管理、积分系统和订阅管理的所有需求。
🗃️ 数据库连接配置
// lib/supabase.ts - 客户端配置
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
// 客户端操作
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
// lib/supabase-admin.ts - 服务端配置
const supabaseServiceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY!
// 管理员客户端(具有更高权限)
export const supabaseAdmin = createClient(supabaseUrl, supabaseServiceRoleKey, {
auth: {
autoRefreshToken: false,
persistSession: false
}
})
📊 数据库表关系图
users_profile
用户基础信息表
• id (UUID)
• email (VARCHAR)
• name (VARCHAR)
• credits (INTEGER)
subscriptions
订阅管理表
• id (UUID)
• user_id (UUID) → users_profile
• stripe_subscription_id
• plan_name, status
一对多关系
users_profile.id → subscriptions.user_id
👤用户表设计 (users_profile)
用户表是整个系统的核心,存储用户的基本信息和积分数据,支持 Google OAuth 登录和积分系统。
📋 表结构定义
CREATE TABLE users_profile (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
email VARCHAR UNIQUE NOT NULL, -- 用户邮箱(唯一)
name VARCHAR, -- 用户姓名
avatar VARCHAR, -- 头像URL
credits INTEGER DEFAULT 0, -- 用户积分
created_at TIMESTAMP DEFAULT NOW(), -- 创建时间
updated_at TIMESTAMP DEFAULT NOW() -- 更新时间
);
🔍 字段说明
字段名 | 类型 | 约束 | 说明 |
---|---|---|---|
id | UUID | 主键,自动生成 | 用户唯一标识符 |
VARCHAR | 唯一,非空 | 用户邮箱,登录标识 | |
name | VARCHAR | 可空 | 用户显示名称 |
avatar | VARCHAR | 可空 | 用户头像图片URL |
credits | INTEGER | 默认0 | 用户可用积分数量 |
⚡ 用户表操作示例
创建新用户(Google登录时)
const { data, error } = await supabaseAdmin
.from('users_profile')
.insert({
email: user.email,
name: user.name,
avatar: user.image,
credits: 3, // 新用户默认3积分
})
查询用户积分
const { data } = await supabaseAdmin
.from('users_profile')
.select('credits')
.eq('email', userEmail)
.single()
扣除积分(生成内容时)
await supabaseAdmin
.from('users_profile')
.update({
credits: currentCredits - 10, // 视频生成消耗10积分
updated_at: new Date().toISOString()
})
.eq('email', userEmail)
💳订阅表设计 (subscriptions)
订阅表管理用户的付费订阅信息,与 Stripe 支付系统紧密集成,跟踪订阅状态和积分发放。
📋 表结构定义
CREATE TABLE subscriptions (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID NOT NULL REFERENCES users_profile(id),
stripe_subscription_id TEXT UNIQUE NOT NULL,
stripe_customer_id TEXT NOT NULL,
stripe_price_id TEXT NOT NULL,
plan_name TEXT NOT NULL, -- 'pro' or 'premium'
status TEXT NOT NULL DEFAULT 'active',
current_period_start TIMESTAMP WITH TIME ZONE,
current_period_end TIMESTAMP WITH TIME ZONE,
credits_per_month INTEGER NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
🔍 订阅状态说明
active
订阅处于活跃状态,正常提供服务
past_due
支付逾期,但仍在宽限期内
canceled
用户主动取消订阅
incomplete
订阅创建中,支付未完成
⚡ 订阅表操作示例
创建订阅记录(Webhook处理)
await supabaseAdmin
.from('subscriptions')
.insert({
user_id: userId,
stripe_subscription_id: subscription.id,
plan_name: 'pro',
credits_per_month: 200,
status: 'active'
})
查询用户活跃订阅
const { data } = await supabaseAdmin
.from('subscriptions')
.select('*')
.eq('user_id', userId)
.in('status', ['active', 'trialing'])
.single()
⚙️数据库操作
模板提供了完整的数据库操作封装,包括用户管理、积分操作和订阅处理,确保数据一致性和安全性。
🛠️ 通用数据库工具
// lib/db.ts - 数据库操作工具函数
export async function getUserByEmail(email: string) {
const { data, error } = await supabaseAdmin
.from('users_profile')
.select('*')
.eq('email', email)
.single()
return data
}
export async function updateUserCredits(email: string, credits: number) {
const { error } = await supabaseAdmin
.from('users_profile')
.update({ credits, updated_at: new Date().toISOString() })
.eq('email', email)
return !error
}
🔐 安全性考虑
双重客户端:客户端使用匿名密钥,服务端使用服务角色密钥,确保权限分离
会话验证:所有敏感操作都需要验证用户会话,防止未授权访问
事务性操作:积分扣除等关键操作使用原子性更新,确保数据一致性
错误处理:完善的错误处理机制,避免数据泄露和操作失败
🔧环境配置
正确配置 Supabase 环境变量是数据库正常工作的前提,这里介绍必需的配置项和获取方法。
📝 必需的环境变量
# .env.local
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
🚀 数据库初始化步骤
1
创建 Supabase 项目
在 supabase.com 创建新项目,获取项目URL和API密钥
2
执行SQL脚本
在 Supabase SQL Editor 中执行 supabase-setup.sql
文件
3
配置环境变量
将 API 密钥添加到 .env.local
文件中
4
测试连接
启动应用,确认数据库连接正常,用户注册功能可用
💡最佳实践
🎯 数据库优化建议
索引优化:为常用查询字段(如 email, user_id)创建索引,提升查询性能
连接池管理:合理配置 Supabase 连接池,避免连接数过多导致的性能问题
数据备份:定期备份数据库,启用 Supabase 的自动备份功能
监控告警:设置数据库性能监控,及时发现和解决问题
🔒 安全最佳实践
密钥管理:服务角色密钥仅在服务端使用,永远不要暴露在客户端代码中
数据验证:所有用户输入都要进行验证和清理,防止 SQL 注入攻击
权限控制:使用 Supabase RLS(行级安全)策略,确保数据访问安全
审计日志:记录关键数据操作日志,便于问题追踪和安全审计
🗃️ 数据库系统总结
HappyShip 的数据库系统基于 Supabase 构建,提供了完整的用户管理、积分系统和订阅管理功能。通过合理的表设计和安全的操作封装,确保数据的一致性和安全性。
📊 简洁架构
两张核心表满足所有业务需求,关系清晰
🔒 安全可靠
多层安全机制,保护用户数据安全
⚡ 高性能
优化的索引和查询,确保系统响应速度
🚀 开始使用 HappyShip 强大的数据库功能吧!