教你用熟悉的MySQL思路慢慢摸索MongoDB里的权限那些事儿
- 问答
- 2025-12-24 16:37:43
- 4
(引用来源:MongoDB官方文档、MySQL DBA的常见类比思路)
很多从MySQL转过来的朋友,一提到MongoDB的权限,头就大了,MySQL里多简单啊,GRANT SELECT ON database.* TO 'user'@'host'; 一句搞定,清晰明了,但到了MongoDB,看到readWrite、dbAdmin,还有什么clusterManager,直接就懵了,感觉像在学一门新外语。
别急,我们今天就用你熟悉的MySQL思路,来慢慢捋一捋MongoDB里的权限那些事儿,你会发现,核心思想是相通的,只是表达方式不一样。
第一步:先找到“服务器”和“数据库”
在MySQL里,你首先得连接到MySQL服务器实例,然后才能操作里面的各个数据库(比如db1, db2),MongoDB也一样,你得先连接到MongoDB服务实例(一个mongod或mongos进程)。
最大的一个区别来了:MySQL的权限,用户是和“从哪个IP来”('user'@'host')强绑定的,MongoDB没这个概念,它只认用户名和密码,认证是在整个服务层面完成的,用户信息存在哪个数据库里,我们待会儿再说。
第二步:理解“权限”的核心:谁,在什么地方,能做什么
这和MySQL一模一样,任何权限系统的三要素都是:
- 谁(Who):用户。
- 在什么地方(Where):权限的作用范围,在MySQL里是数据库和表,在MongoDB里是数据库、集合(Collection,相当于表)、甚至是集群。
- 能做什么(What):具体的操作权限,比如SELECT、INSERT。
我们就从这三点,用MySQL的思维去类比。
“谁”的存储位置:从mysql.user到admin数据库
在MySQL里,用户账户信息存在mysql.user这个系统表里,不管你当前在用哪个数据库,SELECT * FROM mysql.user;都能看到所有用户。
MongoDB里,也有一个类似的核心地方,叫做admin数据库,你可以把它想象成MongoDB的“mysql数据库”。所有用户,不管他最终权限是管理哪个数据库的,其账户信息都存储在admin数据库下(具体是在admin.system.users这个集合里),这是和MySQL非常不同的一个关键点,当你创建一个用户时,你必须先切换到admin数据库(use admin),然后再创建。
“在什么地方”:从Database到“资源”(Resource)
MySQL的权限作用域很清晰:全局()、某个数据库(db_name.*)、某张表(db_name.table_name)。
MongoDB更灵活一点,它把权限的作用范围叫做“资源”(Resource),最常见的资源就是数据库,你给一个用户db1数据库的读权限,他就能读db1里的所有集合(相当于MySQL里db1.*的SELECT权限)。
但它还可以更细,比如指定到某个具体的集合(db1.collection1),或者更广,比如整个集群(cluster)的资源,对于刚入门的我们,先记住“数据库”这个级别就够了,这已经能覆盖80%的场景。
“能做什么”:从Privilege到Role(角色)——这是关键!
在MySQL里,你直接给用户赋权(Privilege),比如GRANT SELECT, INSERT, UPDATE ...。
MongoDB不推荐直接给用户赋权,而是引入了一个“角色”(Role)的概念,这就像公司里不直接定义“张三可以报销1000元”,而是定义了一个“部门经理”的角色,这个角色天然拥有“审批1000元以内报销”的权限,然后把张三赋予“部门经理”的角色。
MongoDB内置了很多常用的角色,对应MySQL里的各种权限:
read:相当于MySQL的SELECT,只能查数据,不能改。readWrite:相当于MySQL的SELECT,INSERT,UPDATE,DELETE,最常用的应用账号角色。dbAdmin:相当于MySQL里对某个数据库的CREATE TABLE,INDEX等DDL操作权限,注意,它不能读用户数据,只能管理数据库结构(集合、索引等),这和MySQL的db_owner有点像但又不完全一样。dbOwner:这个角色厉害了,它结合了readWrite和dbAdmin,还多了一些权限,相当于对这个数据库有完全控制权,类似于MySQL里对一个数据库拥有所有权限。userAdmin:这个角色是管理当前数据库的用户的,注意!它只能管理用户,没有读写的权限,这有点像MySQL里对你授予了mysql数据库下user表的部分管理权,但只限于某个数据库关联的用户。
超级用户在哪里?
MySQL里有GRANT ALL PRIVILEGES ON *.* TO 'superuser' ...。
MongoDB里,对应的超级用户角色有两个,都必须在admin数据库下授予:
userAdminAnyDatabase:管理所有数据库的用户,这是“用户的超级管理员”,但自己不一定有读写数据的权限。dbAdminAnyDatabase:管理所有数据库的结构。readWriteAnyDatabase:读写所有数据库的数据。root:这才是真正的超级管理员,它包含了上面所有权限,相当于MySQL的ALL PRIVILEGES,我们一般就用这个。
来,动手类比一下
假设我们在MySQL里要干两件事:
- 创建一个应用账号
app_user,让它对app_db数据库有完全的读写权限。 - 创建一个管理员账号
dba_user,让它能管理整个MySQL实例。
-
MySQL做法:
-- 1. 创建应用账号 CREATE USER 'app_user'@'%' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'%'; -- 2. 创建DBA账号 CREATE USER 'dba_user'@'localhost' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON *.* TO 'dba_user'@'localhost' WITH GRANT OPTION;
-
MongoDB做法:
// 用最高权限账号(比如刚启动时没有--auth的账号)连接到MongoDB // 切换到admin数据库,因为用户信息都存在这里 use admin // 1. 创建应用账号,作用域在app_db数据库,角色是dbOwner(拥有该数据库所有权限) db.createUser({ user: "app_user", pwd: "password", roles: [ { role: "dbOwner", db: "app_db" } ] // 注意这里,角色和数据库是分开指定的 }) // 2. 创建DBA账号,作用域是整个集群(在admin数据库下授予root角色) db.createUser({ user: "dba_user", pwd: "password", roles: [ "root" ] // 在admin库下给root角色,就是超级管理员 })
看到区别了吗?MongoDB创建用户时,需要明确指定这个角色的生效数据库。app_user的dbOwner角色是生效于app_db的,而dba_user的root角色是内置的全局角色,不需要指定db。
帮你记忆:
- 用户老家在admin:别管用户管哪个库,创建和管理用户时,先
use admin。 - 权限打包成角色:别想一个个权限,先找MongoDB内置的角色(
readWrite,dbAdmin,dbOwner),它们就是为你熟悉的MySQL权限场景准备好的“套餐”。 - 授权时指明地盘:给用户角色时,一定要说清楚这个角色是在哪个数据库上生效的(
{role: "readWrite", db: "your_db"})。
先用这个思路去理解,你会发现MongoDB的权限没那么神秘了,更复杂的自定义角色、集群权限,都是在这些基础概念上扩展的,先把这些基础吃透,就能解决大部分日常权限管理问题了。

本文由符海莹于2025-12-24发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://www.haoid.cn/wenda/67654.html
