开发团队账号须按Schema单独创建并严格隔离,禁止复用或跨库授权;每个团队需专属数据库、用户及显式权限,通过实测验证隔离有效性。

开发团队账号必须按Schema单独建,不能复用
一个账号不能同时连多个业务库,更不能让多个团队共用同一个账号。MySQL 的 user@host 是唯一标识,'team_a_dev'@'10.20.%' 和 'team_b_dev'@'10.20.%' 是两个完全独立的权限主体。常见错误是只建一个 'dev'@'%',结果团队 A 误操作删了团队 B 的表。
实操要点:
- 每个团队先建专属数据库:
CREATE DATABASE team_a_prod CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 再单独建用户:
CREATE USER 'team_a_dev'@'10.20.1.%' IDENTIFIED BY 'pwd_a_2026'; - 禁止用
'%'@'%'——它允许从任意 IP(包括公网)连接,除非你真需要远程调试 - 如果团队用跳板机,IP 会统一为出口地址,此时要配合 DNS 域名限制(如
'team_a_dev'@'%.internal'),但前提是关掉skip_name_resolve
GRANT 必须显式指定 Schema 名,禁用 *.*
GRANT ALL ON *.* 是最危险的起点:它隐式授予 SHOW DATABASES、PROCESS 等管理权限,且在 MySQL 5.7 中可能导致后续 REVOKE 失效。团队只能看到自己负责的库,不是靠应用层“不 USE 别的库”,而是靠权限层硬隔离。
正确写法:
GRANT SELECT, INSERT, UPDATE ON team_a_prod.* TO 'team_a_dev'@'10.20.1.%';- 如果团队需要执行存储过程,加
EXECUTE;不需要就别给 - 绝对不要加
WITH GRANT OPTION——防止开发自授权限给测试账号 - 即使没给其他库权限,也建议显式撤回:
REVOKE ALL ON team_b_prod.* FROM 'team_a_dev'@'10.20.1.%';,边界更清晰
验证权限是否真正生效,不能只看 SHOW GRANTS
SHOW GRANTS FOR 'team_a_dev'@'10.20.1.%' 只显示语句记录,不代表实际行为。真实权限受 host 匹配顺序、DNS 反解、系统库可见性等影响。
必须实测三件事:
- 用该账号直连:
mysql -uteam_a_dev -p -h db-host -e "SHOW DATABASES;"—— 应只返回team_a_prod和information_schema -
mysql -uteam_a_dev -p -h db-host -e "USE team_b_prod;"—— 必须报错Access denied for user 'team_a_dev'@'10.20.1.5' to database 'team_b_prod' -
mysql -uteam_a_dev -p -h db-host -e "SELECT * FROM mysql.user;"—— 应报错Table 'mysql.user' doesn't exist - 检查
CURRENT_USER()返回值是否为预期的'team_a_dev'@'10.20.1.%',否则说明 host 匹配错了
跨团队数据访问必须走视图或 API,不能直授跨库权限
订单团队要查用户昵称,不能直接 GRANT SELECT ON team_b_prod.users TO 'team_a_dev'@'10.20.1.%'。这等于把用户库整个暴露出去,违反最小权限原则。
安全替代方案:
- 在
team_a_prod内建只读视图:CREATE VIEW user_nickname AS SELECT id, nickname FROM team_b_prod.users; - 只授视图权限:
GRANT SELECT ON team_a_prod.user_nickname TO 'team_a_dev'@'10.20.1.%'; - 严禁视图用
DEFINER = 'root'@'%',否则低权限账号能借 root 身份执行逻辑 - 如果数据变更频繁或字段敏感,优先走用户服务 API,而不是数据库层打通
权限边界的模糊点往往不在语法,而在 host 匹配精度、DNS 反解行为、以及系统库的默认可见性。哪怕所有 GRANT 语句都写对了,CURRENT_USER() 返回的 host 和你预设的不一致,整套隔离就失效了。


















