需求场景
服务器SQL Server中有多个数据库,需要给用户账号,账号仅能访问指定数据库,实现数据库权限隔离。
实现方法
创建包含数据库用户
操作步骤
在 SQL Server Management Studio (SSMS) 中,包含数据库用户(Contained Database User) 是在 具体的数据库内部 创建的,而不是在服务器级别的“登录名”中创建。
它不依赖于服务器级别的登录(Login),而是将用户的身份和权限完全“包含”在某个数据库内部,因此称为“包含数据库用户”。
✅ 在哪里创建包含数据库用户?
步骤 1:确保已启用“包含数据库”
⚠️ 这是前提!默认情况下 SQL Server 不启用包含数据库功能。
- 在 SSMS 中,右键点击 服务器实例 → 选择 “属性”
- 左侧选择 “高级” 选项卡
- 找到 “包含数据库验证”(Containment Resolution)
- 将其设置为 “True”
- 点击“确定”
- 重启 SQL Server 服务(必须重启才能生效)

步骤 2:启用目标数据库为“部分包含数据库”
如果目标数据库还不是“包含数据库”,需要先将其改为支持包含用户。
-- 执行以下 SQL 启用包含功能
ALTER DATABASE [你的数据库名]
SET CONTAINMENT = PARTIAL;
例如:
ALTER DATABASE [SalesDB] SET CONTAINMENT = PARTIAL;
📌 只有设置了
PARTIAL或FULL包含模式,才能创建包含数据库用户。

步骤 3:在数据库中创建包含用户(图形界面操作)
- 在 SSMS 中,展开:
数据库 → [你的数据库名] → 安全性 → 用户
例如:
数据库 → SalesDB → 安全性 → 用户
- 右键点击 “用户” → 选择 “新建用户”
- 在弹出的窗口中填写:
- 用户名:输入你想创建的用户名(如
app_user) - 用户类型:选择 “SQL 用户,无登录”
> 🔐 这是关键!表示这个用户只存在于这个数据库中,不需要服务器登录。 - 密码 和 确认密码:设置强密码
- (可选)默认架构:如
dbo
- 在左侧选择 “成员身份”:
在 SQL Server 中,数据库级别的固定数据库角色(Fixed Database Roles) 是一组预定义的权限集合,用于简化权限管理。你提到的这些角色(如 db_datareader、db_owner 等)是 SQL Server 内置的,每个角色具有不同的权限范围。
下面是对这些角色的详细解释和权限区别:
✅ SQL Server 固定数据库角色权限一览表
| 角色名称 | 中文含义 | 主要权限 | 适用场景 |
|---|---|---|---|
db_owner | 数据库所有者 | ✅ 拥有数据库中所有操作权限 • 可读、写、删、改结构(DDL) • 可管理用户和角色 • 可执行任何命令 | 数据库管理员 |
db_securityadmin | 安全管理员 | ✅ 管理数据库级别的权限 • 可执行 GRANT, DENY, REVOKE• 可管理角色成员身份 ❌ 不能创建对象或访问数据 | 权限审计或安全控制人员 |
db_accessadmin | 访问控制管理员 | ✅ 管理用户对数据库的访问权限 • 可添加/删除用户( CREATE USER, DROP USER)• 可控制登录映射 ❌ 不能管理具体对象权限 | 用户生命周期管理 |
db_backupoperator | 备份操作员 | ✅ 可备份数据库 • 可执行 BACKUP DATABASE 和 BACKUP LOG❌ 不能恢复数据库(需更高权限) | 运维人员、备份任务 |
db_ddladmin | DDL 管理员 | ✅ 可执行数据定义语言(DDL) • 可创建/修改/删除表、视图、存储过程等 • 但不能读写数据(除非额外授权) | 开发人员(仅负责结构变更) |
db_datawriter | 数据写入者 | ✅ 可对所有表和视图执行 INSERT, UPDATE, DELETE ❌ 不能 SELECT(除非搭配 db_datareader) | 写入数据的应用账户 |
db_datareader | 数据读取者 | ✅ 可对所有表和视图执行 SELECT ❌ 不能修改数据或结构 | 报表、查询分析用户 |
db_denydatawriter | 拒绝数据写入 | ❌ 显式拒绝 INSERT, UPDATE, DELETE 权限 • 通常用于“黑名单”机制 | 防止某些用户写数据 |
db_denydatareader | 拒绝数据读取 | ❌ 显式拒绝 SELECT 权限 • 用户无法读取任何表 | 安全隔离、禁止访问数据 |
⚠️ 注意:
db_denydatareader和db_denydatawriter是“拒绝”角色,优先级高于其他角色的“允许”,用于强制限制权限。
🔍 详细说明与使用建议
1. db_owner
- 最高权限,相当于数据库的“超级用户”
- 危险!不要随意分配给普通用户
- 可以修改数据库结构、删除数据、添加用户等
2. db_securityadmin
- 可以管理权限(如
GRANT SELECT ON Table1 TO UserA) - 但不能访问数据本身(除非被授予)
- 适合安全审计员或权限管理员
3. db_accessadmin
- 负责用户能否“进入”数据库
- 例如:将一个登录名映射为数据库用户
- 常用于自动化用户开通流程
4. db_backupoperator
- 可以运行备份命令:
BACKUP DATABASE [MyDB] TO DISK = 'D:\Backup\MyDB.bak'
- 但不能
RESTORE(恢复需要sysadmin或db_owner)
5. db_ddladmin
- 可以执行:
CREATE TABLE, ALTER PROCEDURE, DROP VIEW 等
- 但默认不能
SELECT * FROM 表,除非也加入db_datareader
6. db_datareader + db_datawriter
- 这两个是最常用的组合:
db_datareader:只读应用、报表系统db_datawriter:数据采集、写入服务- 如果需要读写,可同时加入两个角色
7. db_denydatareader / db_denydatawriter
- 这两个是“否定”角色,用于覆盖其他权限
- 例如:用户是
db_datareader,但你想禁止其访问某表,可加入db_denydatareader - 拒绝权限优先级高于允许
🧩 实际使用示例
-- 示例:创建一个只读用户
CREATE USER [report_user] FOR LOGIN [report_login];
ALTER ROLE db_datareader ADD MEMBER [report_user];
-- 示例:创建一个可读可写但不能改结构的用户
CREATE USER [app_user] FOR LOGIN [app_login];
ALTER ROLE db_datareader ADD MEMBER [app_user];
ALTER ROLE db_datawriter ADD MEMBER [app_user];
-- 示例:禁止某个用户读数据(即使他是 db_datareader)
ALTER ROLE db_denydatareader ADD MEMBER [restricted_user];
✅ 推荐实践
| 需求 | 推荐角色 |
|---|---|
| 查看所有数据 | db_datareader |
| 写入数据 | db_datawriter |
| 读写数据 | db_datareader + db_datawriter |
| 修改表结构 | db_ddladmin 或 db_owner |
| 备份数据库 | db_backupoperator |
| 管理用户权限 | db_securityadmin |
| 添加/删除用户 | db_accessadmin |
| 完全控制 | db_owner(慎用) |
❗ 注意事项
- 角色是累积的:用户可以同时属于多个角色。
- 拒绝优先:
DENY权限会覆盖GRANT。 - 最小权限原则:只授予必要角色,避免滥用
db_owner。 - 自定义角色更灵活:如果内置角色权限太粗,可创建自定义数据库角色。
📌 总结
| 角色 | 读数据 | 写数据 | 改结构 | 管用户 | 备份 |
|---|---|---|---|---|---|
db_datareader | ✅ | ❌ | ❌ | ❌ | ❌ |
db_datawriter | ❌ | ✅ | ❌ | ❌ | ❌ |
db_ddladmin | ❌ | ❌ | ✅ | ❌ | ❌ |
db_backupoperator | ❌ | ❌ | ❌ | ❌ | ✅ |
db_owner | ✅ | ✅ | ✅ | ✅ | ✅ |
db_securityadmin | ❌ | ❌ | ❌ | ⚠️(权限) | ❌ |
db_accessadmin | ❌ | ❌ | ❌ | ⚠️(访问) | ❌ |
✅ 掌握这些角色的区别,能帮助你更安全、高效地管理数据库权限。
- 可以添加该用户到数据库角色,如:
db_datareader(只读)db_datawriter(读写)- 或自定义角色
- 点击 “确定” 完成创建
相关截图


✅ 创建后的效果
- 该用户 不会出现在 服务器级别的“登录名”中
- 用户只能连接到这个特定数据库(如
SalesDB) - 连接时直接使用该用户名和密码,无需先在服务器创建登录
- 更安全、更便携(适合数据库迁移或云环境)
✅ 如何用这个用户登录?
使用 SSMS 或应用程序连接时:
| 字段 | 值 |
|---|---|
| 服务器名称 | 你的 SQL Server 实例名 |
| 身份验证 | SQL Server 身份验证 |
| 登录名 | 你创建的包含用户用户名(如 app_user) |
| 密码 | 对应密码 |
| 连接到数据库 | 选择该包含用户所在的数据库(如 SalesDB) |
✅ 连接成功后,该用户只能访问
SalesDB,无法看到或访问其他数据库。
📍 总结:包含数据库用户在哪里创建?
| 项目 | 位置 |
|---|---|
| 创建入口 | 数据库 → [数据库名] → 安全性 → 用户 → 新建用户 |
| 关键设置 | 用户类型选择 “SQL 用户,无登录” |
| 前提条件 | 1. 服务器启用“包含数据库验证” 2. 目标数据库设置为 CONTAINMENT = PARTIAL |
✅ 优点:
- 用户与数据库绑定,便于迁移
- 不占用服务器登录名额
- 更安全,权限隔离更好
✅ 适用场景:
- 多租户应用
- 数据库需要独立部署或迁移
- 希望简化权限管理
现在你就可以在指定数据库中安全地创建一个“只属于这个库”的用户了!
在WorkFine中的应用
为什么要给用户数据库权限?
在数据集成的外部数据源中需要链接自身数据库,就需要用到账号信息,这时候就没必要给高权限的账号,需要使用本文中提到的数据库功能

常见问题
- 创建SQL Server用户时用户类型没有【图】
需要先启用【启用目标数据库为“部分包含数据库”】,看上面步骤 - 由于无法在数据库 ‘szhjxc’ 上放置锁,ALTER DATABASE 失败。
可能的原因:数据库正在被使用,【解决办法】强制关闭所有连接(推荐)















