第1章:权限体系基础
各位同学好,我是老张。在金融行业摸爬滚打了十几年,数据库权限这块,我踩过的坑比你们走过的路还多。今天咱们就来聊聊权限体系的基础,这是整个课程的基石。
说实话,我刚入行那会儿,对权限管理也不太当回事。直到有一次,一个测试账号不小心删了生产库的一张核心表...嗯,那场面,我这辈子都忘不了。从那以后,我养成了一个习惯:权限管理,再怎么小心都不为过。
系统权限 vs 对象权限
先搞清楚两个最基本的概念:系统权限和对象权限。说白了,一个管的是"你能干什么",一个管的是"你能对什么东西干"。
系统权限,就是数据库系统级别的高级权限。比如你能不能创建数据库、能不能创建用户、能不能杀掉别人的会话。这些权限影响的是整个数据库实例。
我举个例子,在MySQL里:
-- 授予创建用户的系统权限
GRANT CREATE USER ON *.* TO 'zhangsan'@'localhost';
-- 授予超级权限(小心!)
GRANT SUPER ON *.* TO 'zhangsan'@'localhost';
对象权限,则是针对具体的数据对象。比如你能不能查某张表、能不能往某个视图里插数据、能不能执行某个存储过程。
-- 授予查询特定表的权限
GRANT SELECT ON bank_db.accounts TO 'zhangsan'@'localhost';
-- 授予插入和更新权限
GRANT INSERT, UPDATE ON bank_db.transactions TO 'zhangsan'@'localhost';
核心区别一句话总结:系统权限是"大权",对象权限是"小权"。在金融系统里,系统权限要像发金库钥匙一样谨慎,对象权限则要精确到每一张表、每一列。
GRANT 与 REVOKE 命令
这两个命令,是权限管理的"左右手"。GRANT用来给权限,REVOKE用来收权限。我在项目中见过太多人只会GRANT不会REVOKE,结果权限越积越多,最后成了安全隐患。
GRANT 的基本语法:
GRANT 权限类型 ON 对象级别 TO 用户 [WITH GRANT OPTION];
REVOKE 的基本语法:
REVOKE 权限类型 ON 对象级别 FROM 用户;
来看个完整的例子:
-- 创建一个只读用户
CREATE USER 'readonly'@'%' IDENTIFIED BY 'StrongPass123!';
-- 授予只读权限
GRANT SELECT ON bank_db.* TO 'readonly'@'%';
-- 后来发现这个用户需要查看交易明细
GRANT SELECT ON bank_db.transactions TO 'readonly'@'%';
-- 再后来,发现权限给多了,收回部分权限
REVOKE SELECT ON bank_db.* FROM 'readonly'@'%';
-- 注意:这不会收回对 transactions 表的权限,因为那是单独授予的
我曾经踩过的坑:有一次,我想收回一个用户的所有权限,用了 REVOKE ALL PRIVILEGES,结果发现这个用户还有通过角色继承来的权限没被收回。所以记住:REVOKE 只收回直接授予的权限,不收回通过角色获得的权限。
权限层级:从实例到行
金融系统的权限管理,讲究的是"层层设防"。从大到小,一共五个层级:
| 层级 | 范围 | 典型权限 | 金融场景举例 |
|---|---|---|---|
| 实例级 | 整个数据库服务器 | SUPER, CREATE USER | DBA管理所有数据库 |
| 库级 | 单个数据库 | CREATE, DROP | 开发人员管理测试库 |
| 表级 | 单张表 | SELECT, INSERT | 柜员操作交易表 |
| 列级 | 表中特定列 | SELECT(列名) | 只能查看客户姓名,不能看身份证号 |
| 行级 | 表中特定行 | 通过视图或策略实现 | 客户经理只能看自己管理的客户 |
你想想看,为什么金融系统要搞这么细?说白了,就是最小权限原则。每个角色只给刚刚够用的权限,多一点都不行。
实例级权限
这是最高级别的权限。在MySQL里,实例级权限通常用 *.* 来表示:
-- 授予实例级所有权限(极度危险!)
GRANT ALL PRIVILEGES ON *.* TO 'dba'@'localhost' WITH GRANT OPTION;
我个人习惯,实例级权限只给DBA团队的核心成员。其他人,想都别想。
库级权限
针对某个数据库的所有对象:
-- 授予对 bank_db 数据库的所有权限
GRANT ALL PRIVILEGES ON bank_db.* TO 'dev_team'@'%';
表级权限
这是最常用的权限级别:
-- 只给查询和插入权限
GRANT SELECT, INSERT ON bank_db.accounts TO 'teller'@'%';
列级权限
嗯,这里要注意。MySQL原生支持列级权限,但用得不多。我更喜欢用视图来实现:
-- 创建只暴露部分列的视图
CREATE VIEW bank_db.customer_public AS
SELECT customer_id, customer_name, branch_code
FROM bank_db.customers;
-- 授予视图的查询权限
GRANT SELECT ON bank_db.customer_public TO 'csr'@'%';
行级权限
这是最细粒度的权限。MySQL本身不直接支持行级权限,但我们可以通过视图加条件来实现:
-- 创建只显示当前用户所属分支数据的视图
CREATE VIEW bank_db.my_branch_accounts AS
SELECT * FROM bank_db.accounts
WHERE branch_code = (SELECT branch_code FROM employees WHERE user_id = CURRENT_USER());
-- 授予视图权限
GRANT SELECT ON bank_db.my_branch_accounts TO 'branch_mgr'@'%';
我的经验之谈:在金融系统里,行级权限是最容易被忽视的。很多公司只做到表级,结果客户经理能看到全行客户的数据。这要是出了事,可不是闹着玩的。我建议,凡是涉及客户敏感信息的系统,必须做到行级权限控制。
知识体系总览
为了让大家更直观地理解权限体系的整体结构,我画了张图:
这张图把整个权限体系串起来了。从权限类型到具体层级,再到操作命令和核心原则,一目了然。
好了,这一章的内容就到这里。权限体系是基础中的基础,后面的所有内容都建立在这之上。建议大家把GRANT和REVOKE的命令多练几遍,特别是列级和行级权限的实现方式,在实际工作中非常实用。