慣性聚合 高效追讀感興趣之博客、新聞、科技資訊
閱原文 以慣性聚合開啟

推薦訂閱源

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python)
多租户PostgreSQL:行级安全与租户级模式之辨及选用时机
Jayanth · 2026-05-24 · via DEV Community

Jayanth

若尔营建多租户之SaaS,此乃架构之始也。

若误,此决将萦绕君心。
吾已将二法皆付诸实践。此诚为坦荡之权衡。

A:共享模式,具行级安全(RLS)

每租户之数据,皆存于同表。每表有租户ID列焉。
行。PostgreSQL RLS之策,强制查询所返之列,唯属今租者。

-- Enable RLS on the table
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

-- Policy: users only see their tenant's rows
CREATE POLICY tenant_isolation ON orders
    USING (tenant_id = current_setting('app.current_tenant_id')::uuid);

入全屏模式 出全屏模式

# Set the tenant context before every query
async def set_tenant(conn, tenant_id: str):
    await conn.execute(
        "SELECT set_config('app.current_tenant_id', $1, true)",
        tenant_id
    )

入全屏模式 出全屏模式

效佳之时:汝有众多小租者。百或千。
户分架构于斯,难于驾驭——迁更独需时辰之巨。

弊生之时:喧嚣之户发重询,致他户之效损。难易移一户之数据于别库。需异户存异策。

择二:户分架构

每户得自具之PostgreSQL架构——实为名域。
租户abc之订单,租户xyz之订单。同表异构也。

-- Create schema for a new tenant
CREATE SCHEMA tenant_abc;

-- Set search path at connection time
SET search_path TO tenant_abc, public;

入全景模式 出全屏模式

# Alembic migration across all tenant schemas
from alembic import command
from alembic.config import Config

def migrate_all_tenants(tenant_schemas: list[str]):
    for schema in tenant_schemas:
        alembic_cfg = Config("alembic.ini")
        alembic_cfg.set_main_option("sqlalchemy.url", db_url)
        alembic_cfg.set_section_option("alembic", "version_table_schema", schema)
        command.upgrade(alembic_cfg, "head")

入全景模式 出全屏模式

当租户较少而规模较大时,企业客户使用效果甚佳。
何人需数据隔离之保证,定制留存,或能
其全数据集,洁然导出之。
中断之时:汝有五百租户以上。行迁移于五百
依序处理模式,则迟滞。连接池之负担渐增。

吾所实用者
于初兴之SaaS产品,多从RLS始。此法简明易行。
運作無難,遷移輕易,汝恆可移至每租戶一模式
为日后特定巨擘,导之至专属架构
,乃至专属数据库
。此混合之策——于中小企业租户施用行级权限控制,于企业建专属架构——
,乃吾所定。尔之连接链,即为此路由器

def get_db_url(tenant: Tenant) -> str:
    if tenant.tier == "enterprise":
        return tenant.dedicated_db_url
    return f"{shared_db_url}?options=-csearch_path={tenant.schema}"

一物无人告汝:试汝RLS之策,当禁超级用户。
PostgreSQL超用户默认可绕过RLS。汝之试运行环境运行
为超用户者,永难察失政之策。试时当用限权之职。