Supabase实战避坑指南:PostgreSQL+RLS+实时订阅上线 checklist
1. 这不是“又一个 Firebase 教程”而是一份能让你在真实项目里立刻用起来的 Supabase 实战手记Supabase 不是概念玩具也不是实验室里的 Demo 工具。我从 2021 年底开始在三个不同规模的项目中落地 Supabase一个面向中小企业的 SaaS 客户管理后台日活 300、一个教育类小程序的实时协作白板功能峰值并发 1200、还有一个硬件 IoT 设备的数据上报与指令下发系统设备端直连无中间网关。这三年里我亲手删过 7 次重装的 PostgreSQL 实例改过 46 版 auth 钩子逻辑调过 200 条 pgvector 向量查询的执行计划也踩过那些文档里绝不会写的坑——比如默认开启的 Row Level SecurityRLS策略在你第一次SELECT * FROM profiles时就静默返回空数组而控制台日志里连个 warning 都没有。这篇指南不讲“Supabase 是什么”它只回答三个问题你该不该现在就用它你上线前必须亲手验证哪 5 件事你遇到报错时第一眼该盯住哪三行日志它适合两类人一类是正在 Firebase 上卡在 iOS FCM 订阅失败、Unity 打点数据不上报、或 Realtime DB 复杂查询性能崩盘的开发者另一类是刚学完 PostgreSQL 基础、想立刻把CREATE TABLE users (id UUID PRIMARY KEY, email TEXT UNIQUE)变成可被前端直接调用的 API 的后端新手。全文所有命令、配置、SQL 片段、甚至错误截图里的路径和时间戳都来自我本地开发机和生产环境的真实记录。你不需要理解 WAL 日志刷盘机制但得知道pg_stat_statements扩展怎么开、为什么必须开你不必背熟 JWT 签名算法但得清楚 Supabase Auth 的service_rolekey 和anonkey 在请求头里放错位置会导致什么后果。这不是理论课这是你明天早上打开 VS Code 就能照着敲的部署清单。2. 为什么选 Supabase 而不是自己搭 FastAPI PostgreSQL核心逻辑拆解2.1 “后端即服务”不是偷懒而是对开发节奏的重新定义很多人把 Supabase 当成“Firebase 开源版”这本质上是个认知偏差。Firebase 的设计哲学是“屏蔽后端复杂性”它用一套封闭协议把数据库、认证、存储全打包进 SDK好处是上手快坏处是当你需要自定义一个带窗口函数的聚合查询、或者想给某个字段加一个基于业务规则的 CHECK 约束时你得绕到 Cloud Functions 里写 Node.js 逻辑再通过 HTTP 调用暴露出去——这已经不是 BaaS而是“BaaS FaaS 混合体”。Supabase 的底层是标准 PostgreSQL 14这意味着你写的每一条 SQL无论是SELECT json_agg(row_to_json(t)) FROM (...) t还是WITH RECURSIVE tree AS (...) SELECT * FROM tree只要语法合法就能被 Supabase 的 REST API 直接执行。我有个客户项目需要按“部门树形结构 员工职级 当月绩效分档”做多维交叉统计用 Firebase Realtime DB 得写三层嵌套循环 客户端内存聚合而 Supabase 里一条带 CTE 的 SQL 就搞定前端只管发 GET 请求响应体里直接拿到渲染用的 JSON 数组。这种能力差异决定了 Supabase 不是“替代 Firebase”而是“在 Firebase 覆盖不到的场景里提供更原生、更可控的解决方案”。2.2 PostgreSQL 作为核心带来的不是“兼容性”而是“确定性”热搜词里反复出现“postgresql 和 mysql 区别”但没人告诉你 Supabase 选 PostgreSQL 的真正原因。不是因为 JSONB 字段支持好也不是因为开源免费——MySQL 8.0 也有 JSON 类型。关键在于事务边界与锁行为的可预测性。举个真实案例我们为一家连锁药店做库存同步系统要求“门店扫码出库”和“总部补货单生成”两个操作必须严格串行不能出现超卖。Firebase 的 Realtime DB 用transaction()方法但它的事务是客户端模拟的先读、再算、再写中间若被其他客户端抢占就重试。而 Supabase 底层是 PostgreSQL 的SERIALIZABLE事务我们直接在函数里写UPDATE inventory SET qty qty - 1 WHERE sku A123 AND qty 1 RETURNING qty配合FOR UPDATE SKIP LOCKED数据库层面就保证了原子性。当 50 个收银台同时扫同一款商品时PostgreSQL 的行锁机制让请求自然排队而不是像 Firebase 那样靠客户端重试把压力甩给网络。这个区别在小流量时毫无感知一旦并发超过 200 QPS就是系统稳定性的分水岭。所以 Supabase 的价值不在于它“有数据库”而在于它把 PostgreSQL 经过 25 年高并发电商、金融场景锤炼出来的事务语义原封不动地透传给了前端开发者。2.3 RESTful 不是风格选择而是工程约束的显性化“RESTful API”这个词被用滥了但 Supabase 的 REST 层设计藏着极强的工程意图。它的 endpoint 路径严格遵循/{schema}/{table}结构比如https://xxx.supabase.co/rest/v1/public.users。这看似简单实则强制你思考三件事第一schema 划分是否合理我们把auth、storage、public三个 schema 分开auth仅存用户元数据public存业务表storage由 Supabase 内部管理——这种隔离让权限策略RLS能按 schema 粒度配置避免一个users表的 RLS 规则意外影响到products表。第二table 命名是否符合领域语言我们坚持用复数名词orders而非order因为 REST 的资源概念天然对应集合。第三HTTP 方法语义是否被尊重Supabase 的POST /rest/v1/table默认是 INSERT但如果你在请求体里带上?select*它会自动转成 INSERT RETURNING这比手写fetch(/api/order, {method: POST})再额外发一次 GET 查询要可靠得多。这种设计把很多原本藏在 SDK 封装里的隐式约定变成了 URL 路径、HTTP 方法、Query 参数这些看得见、可调试、可缓存的显式契约。当你在 Chrome DevTools 里看到409 Conflict而不是500 Internal Error时你就知道是唯一键冲突而不是后端代码崩了——这就是 RESTful 带来的可观测性红利。3. 从零搭建可上线的 Supabase 项目避坑实操全流程3.1 本地开发环境Docker Compose 是唯一靠谱的选择Supabase 官方推荐的supabase startCLI 工具在 macOS M1/M2 上有严重的依赖冲突我试过 11 种 Node.js 版本组合最终放弃。生产环境必须用 Docker而本地开发我只信任自己写的docker-compose.yml。以下是经过 3 个项目验证的最小可行配置# docker-compose.yml version: 3.8 services: db: image: supabase/postgres:14.5.0.89 restart: always environment: POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres volumes: - ./volumes/db:/var/lib/postgresql/data - ./init.sql:/docker-entrypoint-initdb.d/init.sql ports: - 5432:5432 healthcheck: test: [CMD-SHELL, pg_isready -U postgres -d postgres] interval: 30s timeout: 10s retries: 5 studio: image: supabase/studio:2023.12.15 restart: always depends_on: - db environment: SUPABASE_URL: http://db:5432 SUPABASE_ANON_KEY: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQcfrT9Da1-219qXKjLZg SUPABASE_SERVICE_ROLE_KEY: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.Sy4fCtHbWwQaPZvJQoQeQrQqQqQqQqQqQqQqQqQqQqQ ports: - 54323:3000 volumes: - ./volumes/studio:/app/.supabase提示SUPABASE_ANON_KEY和SUPABASE_SERVICE_ROLE_KEY的值是硬编码的因为本地开发无需密钥轮换。但注意init.sql文件必须存在内容为CREATE EXTENSION IF NOT EXISTS pg_net; CREATE EXTENSION IF NOT EXISTS pg_stat_statements;这个配置的关键点在于db服务暴露的是原生 PostgreSQL 端口 5432而非 Supabase 的 54323。很多新手误以为supabase start启动的 54323 端口是数据库端口结果用 DBeaver 连 54323 失败其实该连localhost:5432。另外volumes挂载确保了容器重启后数据不丢失healthcheck避免 Studio 启动时数据库还没 ready 就报错。我见过太多人卡在这一步花两天时间查“supabase studio connection refused”最后发现只是docker-compose up没加-d参数容器前台运行被 CtrlC 中断了。3.2 数据库初始化从CREATE TABLE到 RLS 策略的完整链路Supabase 的魔力不在建表而在建表后的三步加固。以profiles表为例这是几乎所有项目的第一张业务表-- 1. 创建表标准 PostgreSQL CREATE TABLE public.profiles ( id UUID REFERENCES auth.users NOT NULL PRIMARY KEY, updated_at TIMESTAMP WITH TIME ZONE, username TEXT UNIQUE, full_name TEXT, avatar_url TEXT, website TEXT ); -- 2. 启用 RLS这是 Supabase 的安全基石 ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY; -- 3. 添加策略这才是关键 -- 策略1用户只能读自己的 profile CREATE POLICY Profiles are viewable by own user ON public.profiles FOR SELECT USING (auth.uid() id); -- 策略2用户只能更新自己的 profile CREATE POLICY Users can update own profile ON public.profiles FOR UPDATE USING (auth.uid() id); -- 策略3允许插入注册时创建 profile CREATE POLICY Users can insert own profile ON public.profiles FOR INSERT WITH CHECK (auth.uid() id);注意auth.uid()函数是 Supabase Auth 模块注入的它从 JWT token 的sub字段解析出用户 ID。如果策略里写current_user authenticated是无效的因为 PostgreSQL 的current_user是数据库角色名不是应用层用户。这三步缺一不可。我曾在一个教育项目里漏掉第 2 步ENABLE ROW LEVEL SECURITY结果前端发GET /rest/v1/profiles直接返回全部用户数据而控制台日志里没有任何警告——RLS 是“默认关闭”的必须显式启用。另一个坑是FOR INSERT WITH CHECK和FOR INSERT USING的区别WITH CHECK控制 INSERT 时新行是否满足条件USING控制 INSERT 后能否看到该行。对于profiles表我们必须用WITH CHECK否则用户注册时插入自己的 profile 会被拒绝。3.3 Supabase Auth 配置绕过 Firebase FCM 订阅失败的终极方案热搜词里高频出现“firebase unity ios打点 后台看不到数据”这背后是 Firebase 的两个硬伤一是 iOS 14 的 App Tracking TransparencyATT框架导致 FCM token 获取失败率飙升二是 Unity 引擎对 Firebase SDK 的 JNI/Native 层封装不完善Android 端常因google-services.json解析失败而静默降级。Supabase Auth 不走 FCM它用标准的 OAuth 2.0 流程且对 Unity 支持极好。关键配置在Auth → Providers页面Email/Password开启这是最稳定的登录方式Apple必须开启iOS 用户无需 ATT 授权即可用 Apple ID 登录Google开启但注意Client ID必须填 Web Application 类型的不是 iOS/Android 类型的——这是 Unity 插件的要求Discord/GitHub可选用于内部测试账号快速创建。然后在 Unity 项目中用官方supabase-unitySDK// 初始化在 Awake 或 Start 中 Supabase.Client client new Supabase.Client( https://xxx.supabase.co, eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQcfrT9Da1-219qXKjLZg ); // 登录任意时刻调用 var response await client.Auth.SignInWithOAuth(apple); if (response.User ! null) { Debug.Log(Login success: response.User.Id); // 此时 response.Session.AccessToken 就是 JWT可存入 PlayerPrefs } else { Debug.LogError(Login failed: response.Error.Message); }实操心得Unity 的PlayerPrefs存 token 有长度限制iOS 为 1024 字节而 Supabase 的 JWT 通常 1200 字节。解决方案是只存response.Session.RefreshToken约 300 字节登录态过期时用它换新 Access Token。这个细节官方文档没写但supabase-unity的 GitHub Issues 里有 47 个开发者踩过。3.4 实时订阅用postgres_changes替代 Firebase Realtime DB 的实践Supabase 的实时能力基于 PostgreSQL 的LISTEN/NOTIFY机制比 Firebase 的 WebSocket 更轻量、更可控。以“订单状态变更通知”为例// 前端 JavaScriptReact import { createClient } from supabase/supabase-js; const supabase createClient(https://xxx.supabase.co, your-anon-key); // 订阅 orders 表的 INSERT 和 UPDATE 事件 const channel supabase .channel(orders) .on( postgres_changes, { event: INSERT, schema: public, table: orders }, (payload) { console.log(New order:, payload.new); // 触发 UI 更新或推送通知 } ) .on( postgres_changes, { event: UPDATE, schema: public, table: orders, filter: statuseq.shipped }, (payload) { console.log(Order shipped:, payload.new.id); // 调用本地通知 API } ) .subscribe(); // 记得在组件卸载时取消订阅 useEffect(() { return () { supabase.removeChannel(channel); }; }, []);这里的关键参数是filter。Supabase 的实时订阅支持 SQL WHERE 子句语法filter: statuseq.shipped会编译成WHERE status shipped只有匹配的 UPDATE 事件才会推送到前端。这比 Firebase 的.on(value)加客户端 if 判断高效得多——网络带宽和 CPU 都省了。但要注意filter不能用复杂表达式比如filter: created_at now() - interval \1 hour\是非法的必须在服务端用视图或函数预处理。4. 生产环境必验的 5 件事一份上线前核对清单4.1 RLS 策略覆盖率用pg_stat_policy确保无裸表Supabase 的安全模型完全依赖 RLS但策略可能漏配。生产前必须验证每张业务表是否都启用了 RLS 且有至少一条策略。执行以下 SQLSELECT n.nspname AS schema_name, c.relname AS table_name, c.relrowsecurity AS rls_enabled, COUNT(p.oid) AS policy_count FROM pg_class c JOIN pg_namespace n ON n.oid c.relnamespace LEFT JOIN pg_policy p ON p.polrelid c.oid WHERE c.relkind r AND n.nspname NOT IN (pg_catalog, information_schema, auth, storage) GROUP BY n.nspname, c.relname, c.relrowsecurity HAVING c.relrowsecurity false OR COUNT(p.oid) 0;这个查询会列出所有未启用 RLS 或无策略的表。如果返回任何行立即停止上线。我在一个电商项目上线前 2 小时跑出products表漏配策略紧急补上FOR SELECT USING (true)公开商品列表和FOR UPDATE USING (auth.role() admin)仅管理员可改价避免了数据泄露风险。4.2 连接池健康度监控pg_stat_activity防止连接耗尽Supabase 的 REST API 和 Realtime 服务共享同一个 PostgreSQL 连接池。默认最大连接数是 100但每个实时订阅会占用一个连接。当你的应用有 50 个用户同时在线每人订阅 3 个频道连接数就飙到 150超出部分请求会直接503 Service Unavailable。必须定期检查SELECT state, COUNT(*) as count, ROUND(AVG(EXTRACT(EPOCH FROM (now() - backend_start))), 2) as avg_age_sec, ROUND(AVG(EXTRACT(EPOCH FROM (now() - state_change))), 2) as avg_idle_sec FROM pg_stat_activity WHERE backend_type client backend GROUP BY state ORDER BY count DESC;重点关注state idle in transaction的数量。如果这个值长期 5说明有事务没提交可能是前端发了BEGIN但没发COMMIT或是 Supabase 函数里有未捕获的异常导致事务挂起。解决方案是在supabase/functions里所有 SQL 函数开头加SET LOCAL statement_timeout 30s;并确保每个BEGIN都有对应的EXCEPTION块。4.3 JWT 密钥轮换anonkey 和service_rolekey 的生命周期管理Supabase 项目有两个核心密钥anonkey前端 SDK 使用和service_rolekey后端服务或函数使用。它们的轮换策略完全不同anonkey可以长期有效但一旦泄露攻击者能执行所有 RLS 允许的操作。建议每 6 个月手动轮换一次轮换后需更新所有前端代码和 CDN 缓存的 JS 文件。service_rolekey绝对不能出现在前端。它拥有绕过 RLS 的权限等同于数据库 root 用户。我们把它存入 Kubernetes Secret并通过环境变量注入到 Supabase 函数中。轮换时先更新 Secret再滚动重启函数 Pod最后在 Supabase Dashboard 的Settings → API页面点击Regenerate。提示Supabase Dashboard 的Regenerate按钮会立即失效旧 key没有灰度期。所以必须确保所有依赖service_rolekey 的服务如定时任务、Webhook 处理器已部署新版本再点按钮。4.4 存储桶Bucket权限public与private的精确控制Supabase Storage 的权限模型常被误解。publicbucket 不代表“全世界可读”而是“通过 Supabase Storage API 可读”仍受 RLS 约束。真正的权限控制在Storage → Buckets → [bucket-name] → Policies对publicbucket添加策略FOR SELECT USING (true)允许所有认证用户读对privatebucket添加策略FOR SELECT USING (auth.uid() (SELECT user_id FROM storage.objects WHERE id id))用户只能读自己上传的文件。但最关键的一步是在Storage → Buckets → [bucket-name]页面把Public开关设为 OFF。这个开关控制的是“是否允许匿名访问”即不带 JWT token 的 HTTP GET。如果设为 ON那么https://xxx.supabase.co/storage/v1/object/public/avatar.jpg就能被任何人下载RLS 策略完全失效。这个开关默认是 OFF但很多新手在调试时手动打开上线前忘了关——这是生产事故的高发点。4.5 错误日志溯源定位400 Bad Request的真实源头Supabase 的错误响应有时很模糊。比如前端发POST /rest/v1/orders返回400 Bad Request但没说哪里错了。此时必须查三处日志Supabase Dashboard 的Logs标签页筛选Service: rest找对应时间戳的请求看error_code字段。常见值invalid_inputJSON 解析失败、permission_deniedRLS 拒绝、unique_violation唯一键冲突PostgreSQL 的pg_log通过docker exec -it supabase-db psql -U postgres -c SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5;查慢查询看是否有INSERT INTO orders ...卡在idle in transaction浏览器 Network 面板的 Request Payload检查 JSON 是否有非法字符如中文引号“”代替英文或字段类型错误如price传了字符串99.99而不是数字99.99。我总结了一个速查表HTTP 状态码Supabase error_code最可能原因快速验证方法400invalid_inputJSON 格式错误或字段类型不匹配用curl -X POST -H Content-Type: application/json -d {key:value}测试401invalid_jwtJWT 过期或签名错误检查auth.signOut()后是否还用旧 token 发请求403permission_deniedRLS 策略拒绝或anonkey 权限不足用psql连数据库执行SET ROLE anon; SELECT * FROM profiles;409unique_violation唯一键冲突如 email 重复查pg_stat_all_indexes看索引命中率5. 常见问题与排查技巧实录那些文档里找不到的答案5.1 “Supabase 怎样添加本地数据库”——一个根本不存在的问题这是搜索热词里最误导人的一个。Supabase 本身就是数据库它不是一个 ORM 或客户端库。所谓“添加本地数据库”实际是两种需求需求1把现有 PostgreSQL 数据导入 Supabase正确做法用pg_dump导出再用psql导入。但注意 Supabase 的authschema 是受保护的不能直接覆盖。步骤# 1. 从本地库导出排除 auth 和 storage schema pg_dump -U postgres -d mydb --exclude-schemaauth --exclude-schemastorage -f dump.sql # 2. 修改 dump.sql把所有 CREATE TABLE 的 schema 名从 public 改成 myapp # 3. 用 Supabase 的 psql 连接字符串导入 psql $SUPABASE_CONNECTION_STRING -f dump.sql需求2在本地开发时连接 Supabase 的数据库正确做法Supabase 项目 Dashboard 的Database → Connection Pooling页面复制Connection string格式为postgresql://postgres:passworddb.supabase.co:5432/postgres。用 DBeaver 连接时Host 填db.supabase.coPort 填5432Database 填postgres不是rest或realtime。很多新手填54323或6543这是 Studio 的端口不是数据库端口。5.2 “PostgreSQL 5432 端口号一直占用kill 后又来了”——macOS 的罪魁祸首在 macOS 上lsof -i :5432常显示com.apple.WebKit.Networking占用 5432。这不是病毒而是 Safari 的 WebKit 进程在预加载某些网页时会随机绑定 5432 端口做代理测试。解决方案不是kill -9而是关闭所有 Safari 窗口执行sudo lsof -t -i :5432 | xargs kill -9立即启动 Docker Composedocker-compose up -d db再打开 Safari。这个顺序很重要。因为 WebKit 只在 Safari 启动时扫描端口如果数据库服务先占住 5432WebKit 就会跳过。5.3 “Excel 导入 PostgreSQL 数据库”——Supabase 的隐藏技能Supabase Studio 的 Table Editor 支持 CSV 导入但 Excel 文件.xlsx不行。正确流程在 Excel 中文件 → 另存为 → CSV UTF-8 (逗号分隔) (*.csv)打开 Supabase Studio进入目标表的Table Editor点击右上角Import按钮选择 CSV 文件关键一步在导入弹窗中勾选First row contains column names并确认列类型映射如id列选UUIDcreated_at选TIMESTAMP点击Import。如果 CSV 里有中文必须确保保存为UTF-8 with BOM否则 Supabase 会乱码。Windows 记事本默认保存为 ANSI这是常见坑。5.4 “PostgreSQL 支持单表多少记录”——一个被问烂却答错的问题热搜词里总有人问“PostgreSQL 单表最大记录数”答案是“理论上无限实践中看索引”。关键指标是pg_class.reltuples估算行数和pg_index.indisvalid索引有效性。当一张表超过 1 亿行必须检查是否有合适的复合索引例如orders表查询WHERE status paid AND created_at 2023-01-01需要索引CREATE INDEX idx_orders_status_created ON orders(status, created_at)是否启用了VACUUM自动清理Supabase 默认开启但大表批量 DELETE 后需手动VACUUM ANALYZE orders;更新统计信息是否用了分区表PostgreSQL 12 支持声明式分区orders表可按created_at月分区CREATE TABLE orders_2023_01 PARTITION OF orders FOR VALUES FROM (2023-01-01) TO (2023-02-01);。我维护的最大表是events埋点日志23 亿行通过PARTITION BY RANGE (event_time)BRIN 索引查询SELECT COUNT(*) FROM events WHERE event_time 2024-01-01仍能在 1.2 秒内返回。5.5 “Supabase 怎么添加 pgvector 扩展”——向量搜索的实战配置Supabase 从 v1.10.0 起内置 pgvector但需手动启用-- 连接到 Supabase 数据库用 service_role key CREATE EXTENSION IF NOT EXISTS vector; -- 验证是否成功 SELECT * FROM pg_extension WHERE extname vector;然后创建向量字段ALTER TABLE public.products ADD COLUMN embedding vector(1536); -- 创建向量索引关键否则查询慢 CREATE INDEX ON public.products USING ivfflat (embedding vector_cosine_ops) WITH (lists 100);lists 100是聚类数经验公式lists ≈ sqrt(row_count)。我们的products表有 50 万行sqrt(500000) ≈ 707但实测lists 100时召回率和速度平衡最好。查询时SELECT *, embedding [0.1,0.2,0.3] as similarity FROM public.products ORDER BY embedding [0.1,0.2,0.3] LIMIT 5;注意是余弦相似度操作符不是。如果写错会返回空结果且无报错。6. 我在实际项目中发现的一个反直觉事实Supabase 的瓶颈从来不在数据库过去三年我参与的所有 Supabase 项目性能瓶颈 100% 出现在三个地方前端 SDK 的请求合并策略、Realtime 频道的连接复用、以及 Auth 的 JWT 解析开销。PostgreSQL 本身极少成为瓶颈。举个例子一个医疗问诊 App医生端需要实时接收患者消息我们最初为每个患者创建独立频道channel_patient_123结果 200 个患者在线时前端建立 200 个 WebSocket 连接内存暴涨页面卡死。解决方案是改成单频道channel_doctor_messages在消息 payload 里加patient_id字段前端用Map缓存按需分发。连接数从 200 降到 1内存占用下降 70%。另一个案例Auth 的 JWT 解析默认用 HS256 算法但在高并发登录时Node.js 的 crypto 模块会阻塞事件循环。我们改用 RS256把私钥存在 KMS公钥缓存到内存解析耗时从平均 12ms 降到 0.8ms。所以当你觉得 Supabase “慢”时先别急着优化 SQL打开 Chrome DevTools 的 Performance 面板录一段操作看是 Network、JS Main Thread 还是 Rendering 在拖慢。Supabase 的强大恰恰在于它把后端复杂性下沉到 PostgreSQL 这个久经考验的引擎里而把应用层的优化空间留给了你最熟悉的地方——前端代码和网络架构。

相关新闻

锤石辅助进阶指南:从技能连招到对线策略的实战解析

锤石辅助进阶指南:从技能连招到对线策略的实战解析

1. 先搞清楚锤石在下路的定位和优势点锤石这个英雄在辅助里属于典型的“创造机会型”角色,不是单纯靠加血或护盾保AD,而是靠控制链和位移能力打开局面。很多新手锤石容易犯两个错误:要么躲在AD后面只丢灯笼,要么无脑钩上去送人头。…

2026/7/16 3:37:39 阅读更多 →
【板子】Dinic(最大网络流)

【板子】Dinic(最大网络流)

通用 Dinic 最大流板子#include <bits/stdc.h> using namespace std;const int N 10005; // 点的数量上限 const int M 200005; // 边的数量上限&#xff08;记得 *2&#xff0c;因为要建反向边&#xff09; const int INF 0x3f3f3f3f;struct Edge {int to, …

2026/7/16 3:35:38 阅读更多 →
基于Transformer与微服务架构的AI对话系统开发实践

基于Transformer与微服务架构的AI对话系统开发实践

最近在AI聊天应用领域&#xff0c;不少开发者都在寻找既能满足创意需求又具备稳定免费服务的解决方案。本文将从技术角度全面解析如何构建一个功能完善的AI对话系统&#xff0c;涵盖从架构设计到核心功能实现的完整流程&#xff0c;适合有一定Python基础的开发者学习参考。1. A…

2026/7/16 3:33:38 阅读更多 →

最新新闻

计费系统与资源配额管理:用量统计、阶梯定价、配额告警与结算系统实战

计费系统与资源配额管理:用量统计、阶梯定价、配额告警与结算系统实战

文章目录 每日一句正能量 摘要 一、引言:计费系统是SaaS平台的生命线 二、计费系统整体架构 2.1 六层架构设计 2.2 数据流全景 三、用量统计:从原始事件到精准计量 3.1 多维用量指标体系 3.2 实时用量采集实现 3.3 流处理聚合引擎 3.4 用量数据模型设计 四、阶梯定价:灵活定…

2026/7/16 4:35:16 阅读更多 →
JAVA练习294- 环形链表II

JAVA练习294- 环形链表II

题目概览 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统…

2026/7/16 4:35:16 阅读更多 →
YOLOv8 ONNX→TensorRT完整部署教程:C++/Python双接口实现,推理速度提升2倍以上

YOLOv8 ONNX→TensorRT完整部署教程:C++/Python双接口实现,推理速度提升2倍以上

前言:为什么你的YOLOv8部署总是不够快? 在AI模型落地过程中,训练只是起点,部署才是硬仗。很多开发者训练出精度不错的YOLOv8模型后,一放到生产环境就露馅了——推理速度慢、显存占用高、多路视频流卡顿。PyTorch原生推理虽然方便,但动态图开销大、算子融合不足,在实际业…

2026/7/16 4:33:16 阅读更多 →
Unity游戏模组开发框架BepInEx:从架构解析到Harmony补丁实战

Unity游戏模组开发框架BepInEx:从架构解析到Harmony补丁实战

1. 项目概述&#xff1a;为什么我们需要BepInEx&#xff1f;如果你是一名Unity游戏开发者&#xff0c;或者是一名热衷于为游戏制作模组的爱好者&#xff0c;那么你一定遇到过这样的困境&#xff1a;面对一个心爱的游戏&#xff0c;你有一个绝佳的修改或扩展想法&#xff0c;却发…

2026/7/16 4:31:13 阅读更多 →
C++实时数据流水线设计:7大核心模式与性能优化实战

C++实时数据流水线设计:7大核心模式与性能优化实战

1. 项目概述&#xff1a;从概念到实战的实时数据流水线最近刚参加完2025年的全球C技术大会&#xff0c;回来之后一直想找个时间把会上关于实时数据流水线设计的干货好好梳理一下。这个话题在大会上讨论得特别热烈&#xff0c;几乎每个做高性能计算、金融交易系统或者游戏服务器…

2026/7/16 4:29:09 阅读更多 →
DASCTF X SU 春季挑战赛:逆向工程与流量分析实战复盘

DASCTF X SU 春季挑战赛:逆向工程与流量分析实战复盘

1. 逆向工程实战&#xff1a;从混淆代码到算法还原1.1 RC4算法变形与密钥提取在2024 DASCTF春季赛中&#xff0c;一道逆向题采用了魔改版RC4算法。题目给出的是一个被混淆的Windows PE文件&#xff0c;使用IDA Pro分析时发现核心加密函数存在大量花指令。通过动态调试发现&…

2026/7/16 4:29:09 阅读更多 →

日新闻

HarmonyOs应用《重要日》开发第6篇 - 数据持久化存储

HarmonyOs应用《重要日》开发第6篇 - 数据持久化存储

本篇深入剖析 ImportantDays 项目的数据持久化方案——基于 HarmonyOS ArkData 模块的 Preferences 轻量级存储&#xff0c;以及 PreferenceUtil 工具类的单例封装。一、HarmonyOS 数据存储方案对比 HarmonyOS 提供了多种数据存储方案&#xff1a;方案适用场景特点Preferences轻…

2026/7/16 0:08:27 阅读更多 →
Python实现跨境电商商品图批量翻译教程

Python实现跨境电商商品图批量翻译教程

一、问题引入做跨境电商的卖家朋友&#xff0c;你是否遇到过这样的困扰&#xff1f;每次上架新品到亚马逊、Shopee或Lazada等平台&#xff0c;都需要处理大量商品图片的多语言版本。比如上架200款衣服&#xff0c;每款需要翻译成英语、日语、韩语等5种语言&#xff0c;这意味着…

2026/7/16 0:08:27 阅读更多 →
鸿蒙 7 新特性实战①:从 0 到 1 掌握 @kit 标准导入规范

鸿蒙 7 新特性实战①:从 0 到 1 掌握 @kit 标准导入规范

从鸿蒙 7&#xff08;HarmonyOS NEXT&#xff09;开始&#xff0c;官方全面完成了从 ohos.* 零散模块到 kit.* 领域套件的体系重构。对开发者来说&#xff0c;第一道门槛不是 API 用法变化&#xff0c;而是统一的导入规范——旧体系默认导入、解构导入混用的混乱局面被彻底终结…

2026/7/16 0:10:29 阅读更多 →

周新闻

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试&#xff1a;燕双非的搞笑回答与技术探讨 在一个阳光明媚的上午&#xff0c;互联网大厂的面试官坐在桌前&#xff0c;准备迎接他的面试候选人——燕双非&#xff0c;一个以搞笑和幽默著称的程序员。第一轮提问 面试官&#xff1a;燕双非&#xff0c;作…

2026/7/15 21:09:01 阅读更多 →
车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型&#xff1a;示波器、VNA、信号源3类仪器关键参数与预算评估在智能驾驶和车联网技术快速发展的今天&#xff0c;车载以太网作为新一代车载网络的核心传输技术&#xff0c;其物理层性能直接决定了数据传输的可靠性和稳定性。1000BASE-T1作为当前主流的…

2026/7/15 19:42:20 阅读更多 →
VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0&#xff1a;APM32/STM32 项目迁移实战指南嵌入式开发领域正经历一场工具链的静默革命。当传统Keil用户首次打开VSCode的扩展市场搜索EIDE时&#xff0c;往往会惊讶于这个看似简单的插件竟能重构十余年的开发习惯。本文将揭示如何用五个精准步骤&#xff0…

2026/7/15 17:52:08 阅读更多 →

月新闻