不可行。grant on 不支持表名前缀通配符,mysql 和 postgresql 均报错;权限最小粒度为单表、库或列,无表名模式授权;唯一可靠方案是物理分库(mysql)或分 schema(postgresql)并单独授权。

GRANT ON 表名前缀是否可行?
不行。GRANT ON 语法不支持通配符前缀匹配表名,比如 GRANT SELECT ON `team_a_%`.* TO 'user' 是非法的,MySQL 和 PostgreSQL 都会报错 ERROR 1146 (42S02): Table doesn't exist 或类似解析失败提示。权限粒度最小是单表、数据库或列,没有“按表名模式授权”这一层抽象。
真正能落地的表级隔离方案
靠数据库原生权限机制,必须把表物理分库或分 schema(MySQL 的 database / PostgreSQL 的 schema),再对不同库/Schema 单独授权。这是唯一被广泛验证、无兼容性风险的做法。
- MySQL:为每个团队建独立 database,如
team_a_prod、team_b_prod,然后执行GRANT SELECT, INSERT ON team_a_prod.* TO 'team_a_rw' - PostgreSQL:用 schema 隔离,
CREATE SCHEMA team_a,建表时指定CREATE TABLE team_a.users (...),再授权GRANT USAGE ON SCHEMA team_a TO team_a_user和GRANT SELECT ON ALL TABLES IN SCHEMA team_a TO team_a_user - 避免用
GRANT ... ON *.*或GRANT ... ON db_name.*授权给跨团队账号——哪怕只是只读,也等于开放了该库下所有当前及未来新建表
为什么不用视图 + 行级权限替代?
视图只能解决“看到什么”,不能阻止 DML 操作影响其他团队数据;行级权限(如 MySQL 8.0 的 Row-Level Security)依赖策略函数,但无法按表名动态拦截,且不支持 DDL(如 DROP TABLE、ALTER TABLE),团队仍可能误删/改他人表。
- 视图无法防止
INSERT INTO original_table绕过(除非设为WITH CHECK OPTION,但仅限 INSERT/UPDATE,且对跨表关联无效) - RLS 策略需手动绑定到每张表,新表上线容易漏配,且 PostgreSQL 的 RLS 对
TRUNCATE无效,MySQL 的 RLS 实际可用性低、文档不全 - DDL 操作完全不受视图和 RLS 约束,这才是多团队共用同库时最常出问题的环节
如果必须共用一个 database,最低成本补救措施
靠约定 + 自动化拦截,而非数据库权限。在应用层或 SQL 网关(如 ProxySQL、MaxScale)加规则,拒绝含非授权前缀的 DDL/DML。
- 例如,在 ProxySQL 中配置
mysql_query_rules,匹配^DROP TABLE (?!team_a_)并返回错误 - CI/CD 流水线中加入 SQL 审计脚本,用正则校验迁移文件里的
DROP TABLE、ALTER TABLE是否符合team_x_*命名,不符合直接失败 - DBA 手动定期执行
SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema = 'shared_db' AND table_name NOT REGEXP '^team_[a-z]+_',快速发现违规建表
这种方案不改变数据库权限模型,但把风险点从“谁能执行”转移到“谁敢提交”——而后者更容易监控和收敛。真正的难点不在语法怎么写,而在团队间命名共识能否稳定维持三年以上。










