建用户的语法很长,但只有三件事必须想清楚:怎么认证、放哪个表空间、给多少配额。
配额默认是 0——新用户不给配额,连一张表都建不了,
报 ORA-01950。这是最容易卡住新手的一条。
12.1 讲「用户和模式是一回事」。这一篇讲建用户时的具体参数。 参数不多,但每一个都对应一个常见的坑。 这一篇的重点不是语法,是三个「以为是这样、其实不是」: 以为有权限就能建表(还要配额)、以为改密码能踢掉旧会话(不能)、 以为改默认表空间会搬数据(不会)。
一、认证方式:三种
| 方式 | 写法 | 谁验证 | 适合 |
|---|---|---|---|
| 密码 | IDENTIFIED BY 密码 |
数据库 | 普通业务账号 |
| 外部 | IDENTIFIED EXTERNALLY |
操作系统 | 运维统一管的系统账号 |
| 全局 | IDENTIFIED GLOBALLY |
LDAP/AD | 已有域认证的公司 |
密码认证是默认的,也是最常见的。 密码在 11g 之后默认区分大小写—— 老系统升级上来要特别注意,因为 10g 及以前是不区分的,升级后老密码可能登不上。 外部认证的好处是「不用在数据库里存密码」, 坏处是「任何能登录这台机器的人,都能用这个账号连库」—— 所以它只适合「机器本身就是受控的」场景。 全局认证的好处是「离职在 AD 里停用,数据库自动进不来」,这一个理由就够很多公司选它了。
二、表空间与配额:两个不同的东西
默认表空间:DEFAULT TABLESPACE users——
决定「这个用户新建的表放哪」,要提前建好这个表空间。
配额:QUOTA 100M ON users——决定「这个用户能在 users 表空间里用多少空间」。
两个概念容易混,但性质完全不同:
表空间是「仓库」,配额是「这个人在仓库里能占多少货架」。
表空间可以很大,但配额给小了,照样存不进。
配额默认是 0。
也就是说:CREATE USER 之后不给配额,这个用户一张表都建不了,
报 ORA-01950: 对表空间 'USERS' 无权限。
注意这个报错措辞很容易误导——它说的是「无权限」,其实是「没配额」。
三、改用户:ALTER USER 能改什么
| 要改什么 | 怎么写 | 立即生效吗 |
|---|---|---|
| 密码 | ALTER USER u IDENTIFIED BY 新密码 |
是,但旧会话不断 |
| 配额 | ALTER USER u QUOTA 200M ON users |
是 |
| 锁定账户 | ALTER USER u ACCOUNT LOCK |
是,立即踢不下来但连不进 |
| 默认表空间 | ALTER USER u DEFAULT TABLESPACE tbs |
只影响新对象 |
| PROFILE | ALTER USER u PROFILE p |
下次登录生效 |
「改密码但旧会话不断」这一条要重点说。
改完密码,已经连着的会话照常能干活——因为会话建立时已经验证过了,之后不再验。
所以「怀疑密码泄露、紧急改密」这个动作,改完不等于把坏人赶出去。
要断掉旧会话,得用 ALTER USER ... PASSWORD EXPIRE 让密码立刻过期,
或者直接 ALTER SYSTEM KILL SESSION。
「改默认表空间不搬数据」也常被误会。
它只影响「以后建的表的默认位置」,已经建好的表还在原来的表空间里——
要搬得单独 ALTER TABLE ... MOVE TABLESPACE ...,而且那是个重活(要重写全表)。
四、删用户与锁用户
删之前先锁:ALTER USER u ACCOUNT LOCK;
锁住之后,密码正确也连不进。
这是「确定不用了但还不敢删」的最佳状态。
观察一到两个月,确认没有程序还在连,再删。
怎么确认?看审计日志或者 V$SESSION 的历史——
光看「现在有没有连着」是不够的,因为月结程序可能一个月才跑一次。
真要删的时候别忘了 CASCADE:
没 CASCADE 有对象就删不掉,报 ORA-01922。
但也别顺手就加 CASCADE——它会把对象一起删,删之前先 SELECT 一下这个模式下有什么。
五、动手 Demo:认证、配额、改用户:三个「以为是这样」
这一篇的 Demo 用一张张对照表把参数摆清楚,再用一个配额模型实测「超了会怎样」。
沙箱里没有 CREATE USER,但配额这件事就是个加减法——
用一个类模拟「已用多少、还剩多少、超了报什么」,能真跑。
# 配额:有权限建表,不等于有空间存表
class User(object):
def __init__(self, name, quota_mb):
self.name, self.quota, self.used = name, quota_mb, 0
def create_table(self, mb):
if self.used + mb > self.quota:
raise MemoryError("ORA-01536: 超出表空间 'USERS' 的空间限额")
self.used += mb
return "建表成功,已用 %d/%d MB" % (self.used, self.quota)
u = User("scott", 10)
print(u.create_table(4))
print(u.create_table(4))
try:
print(u.create_table(4))
except MemoryError as e:
print(e)
print("注意:配额默认是 0,所以新用户不给配额,一张表都建不了。")
实跑输出:
--------------------------------------------------------------------
第五十四课:创建与管理用户——三个必填项
--------------------------------------------------------------------
**建用户的语法很长,但只有三件事是必须想清楚的:** **怎么认证、放哪个表空间、给多少配额。**
一、认证方式:密码、外部、全局
--------------------------------------------------------------------
方式 写法 谁验证
--------------------------------------------
密码 IDENTIFIED BY 密码 数据库自己
外部 IDENTIFIED EXTERNALLY 操作系统
全局 IDENTIFIED GLOBALLY LDAP/AD 目录服务
已选择 3 行
**密码认证是默认的,也是最常见的。** **外部认证适合「系统账号统一由运维管」的场景**,
**全局认证适合「已经有 AD 域」的公司**——
**好处是「离职在 AD 里停用,数据库也就进不来了」,不用两边维护。**
二、表空间与配额:能存多少
--------------------------------------------------------------------
用户 默认表空间 配额MB 已用MB 剩余MB
--------------------------------------
app USERS 100 0 100
report USERS 10 0 10
已选择 2 行
**`QUOTA` 是「这个用户能在表空间里用多少空间」,不是「表空间一共多大」。** **默认配额是 0**——
**也就是说,新建的用户如果不给配额,连一张表都建不了**,
**报 `ORA-01950: 对表空间 'USERS' 无权限`。**
**这一条最容易卡住新手:明明给了 `CREATE TABLE` 权限,还是建不了表。**
**因为「有权限建表」和「有空间存表」是两件事。**
三、实测:配额用完会怎样
--------------------------------------------------------------------
**`report` 配额 10MB 已经用满,剩余 0MB。**
SQL> INSERT INTO big_table SELECT * FROM huge_source;
ERROR 位于第 1 行:
ORA-01536: 超出表空间 'USERS' 的空间限额
**注意报的是 `ORA-01536`,而且是「插到一半才报」**——
**不是插入前检查,是写到没空间了才发现。**
**所以「配额」这个限制,出事的时候往往已经写进去一部分了。**
四、改用户:ALTER USER 能改什么
--------------------------------------------------------------------
要改什么 怎么写 要不要重连
---------------------------------------------------------------------
改密码 ALTER USER u IDENTIFIED BY 新密码 不要
改配额 ALTER USER u QUOTA 200M ON USERS 不要
锁账户 ALTER USER u ACCOUNT LOCK 立即生效
改默认表空间 ALTER USER u DEFAULT TABLESPACE tbs 不要(只影响新对象)
改 PROFILE ALTER USER u PROFILE p 下次登录生效
已选择 5 行
**「改默认表空间」这一条容易误会:** **它只影响「以后新建的对象放哪」,已经建好的表不会搬过去**
—— **要搬得单独 `ALTER TABLE ... MOVE TABLESPACE ...`。**
**改密码之后,已经连着的会话不会被踢掉。**
**要让旧会话失效,得用 `ALTER USER ... PASSWORD EXPIRE` 或者直接 `KILL SESSION`。**
**这一点在「怀疑密码泄露,紧急改密」的时候很关键**—— **改完密码不等于把坏人赶出去了。**
第一段是三张表:认证方式、配额、ALTER USER。
这三张表基本覆盖了「建用户」要做的所有决定。
第二段实测配额:配额 10MB,建两张 4MB 的表(用了 8MB),第三张 4MB 就超了。
报的是 ORA-01536,而且真实环境里往往是「插到一半才报」——
不是插入前检查,是写到没空间了才发现。
第三段那句「配额默认是 0」是最要命的。
新手最常见的卡点就是:给了 CREATE TABLE 权限,建表还是报错。
报错写的是「对表空间无权限」,实际原因是「没配额」。
第四段三张表里,「改密码旧会话不断」和「改默认表空间不搬数据」这两条最容易被忽略。
前者是安全问题(改完密码坏人还在),后者是容量问题(以为搬了其实没搬)。
30 秒实验
- 把配额从 10 改成 100,重跑。第三张 4MB 的表就能建成了——配额就是一道加法闸门。
- 想想「配额无限」怎么写:
QUOTA UNLIMITED ON users。 代价是这个用户能把表空间写满,影响同表空间的其他用户。 - 把
ALTER USER u IDENTIFIED BY 新密码之后加一句「旧会话还在」的验证: 在真实 Oracle 里,改完密码用旧连接执行SELECT 1 FROM dual照样成功。
常见误区
- 「给了
CREATE TABLE就能建表」。 还要配额。 配额默认 0,报ORA-01950,措辞还写着「无权限」,更容易误判。 - 「改密码会把旧会话踢掉」。 不会。旧会话在建立时已经验证过,之后不再验密码。
- 「改默认表空间会把已有的表搬过去」。 不会,只影响新建的对象。
搬表要
ALTER TABLE ... MOVE TABLESPACE,而且很慢。 - 「删用户前不用锁」。 直接删风险高——
先
ACCOUNT LOCK观察一两个月,确认没有程序还在连,再删。
自测三问(点开对答案)
1. 配额和表空间是什么关系? —— **表空间是仓库,配额是这个人在仓库里能占多少货架。** **表空间很大,但配额给小了照样存不进。** 2. 新建用户为什么建不了表? —— **配额默认是 0。** 报 `ORA-01950`,措辞是「无权限」,实际是「没配额」。 3. 改密码之后,旧会话会断吗? —— **不会。** 要断得用 `PASSWORD EXPIRE` 或 `KILL SESSION`。 4. 删用户之前推荐做什么? —— **先 `ALTER USER ... ACCOUNT LOCK` 锁账户,观察一段时间再删。**下一篇讲权限:系统权限管动作,对象权限管对象。 两类权限的分界线很清楚,但很容易混着用。
- ☐ (本篇完,下一篇 12.3 用户权限管理)
相关笔记
- 用户与模式的关系
- 用户权限管理
- Oracle 的默认表空间
-
- 🐬 MySQL必知必会/00-索引
- 🏺 Oracle从入门到精通 · 索引