oracle中存在“只读表空间”概念,alter tablespace ... read only 使表空间不可修改结构或写入新段,但不控制dml权限;dml限制依赖表级或用户级权限,而非表空间属性。

Oracle中不存在“只读表空间”这个概念
表空间本身没有只读/可写属性来控制用户数据操作权限。你看到的 ALTER TABLESPACE ... READ ONLY 是让整个表空间**不可被修改结构或写入新段**,但它不影响已有对象的 DML 行为——也就是说,即使表空间设为只读,只要用户有 UPDATE 权限,仍可能更新表(前提是该表没被显式设为只读)。真正限制 DML 的是表级或用户级权限控制。
创建用户时必须显式指定 DEFAULT TABLESPACE 和 TEMPORARY TABLESPACE
Oracle 不会自动为新用户分配“只读专用表空间”。你得自己建一个普通表空间(比如 app_read_tbs),再在 CREATE USER 里明确绑定:
-
DEFAULT TABLESPACE:存放用户创建的对象(如 synonym、临时表等),即使只读用户也需此空间;若不指定,会继承数据库默认(通常是USERS),但生产环境严禁依赖隐式行为 -
TEMPORARY TABLESPACE:排序、哈希连接、全局临时表等都依赖它;缺失会导致查询直接报ORA-01652: unable to extend temp segment - 必须同时设置配额:
QUOTA UNLIMITED ON app_read_tbs或QUOTA 10M ON app_read_tbs,否则用户连同义词都建不了
示例语句:
CREATE TABLESPACE app_read_tbs DATAFILE '/u01/oradata/ORCL/app_read_tbs01.dbf' SIZE 100M AUTOEXTEND ON NEXT 10M MAXSIZE 2G; CREATE USER app_read IDENTIFIED BY "R3ad0nly!2026" DEFAULT TABLESPACE app_read_tbs TEMPORARY TABLESPACE temp QUOTA UNLIMITED ON app_read_tbs;
只读能力靠对象权限,不是靠表空间
用户能登录、有默认表空间,不代表能查任何表。关键在授权方式:
- 不要用
GRANT SELECT ANY TABLE:这是高危系统权限,DBA 才该有 - 不要只给
CONNECT:它只含CREATE SESSION,不带任何查询能力 - 必须逐个授予
SELECT ON schema.table,例如:GRANT SELECT ON hr.employees TO app_read; - 如果要省略 schema 名,得额外建同义词:
CREATE SYNONYM app_read.employees FOR hr.employees;,且用户需有CREATE SYNONYM权限
容易被忽略的三个硬性依赖
漏掉任一环节,用户都会在实际使用中失败:
- 没授
CREATE SESSION→ 登录报ORA-01045: user lacks CREATE SESSION privilege - 没设
TEMPORARY TABLESPACE→ 执行ORDER BY或GROUP BY直接卡住或报ORA-01652 - 没给目标表的
SELECT权限,却用hr.employees全限定名查询 → 报ORA-00942: table or view does not exist(注意:这不是权限错,是对象不可见)
表空间只是容器,权限才是开关。把“只读”寄托在表空间配置上,等于没装锁就关了门。











