文章目录
1 概述
以实体-关系图的形式绘制 Oracle 存储模型,逻辑结构在左,物理结构在右。
- 有一个关系使用虚线绘制,表示段和数据文件的多对多关系。之所以使用虚线表示关系,是因为这种关系不应该存在。出色的关系工程师不应该允许多对多关系的存在。
- 表空间实体消除了段与数据文件之间的多对多关系。一个表空间可以包含多个段,而且可以由多个数据文件组成。
小提示:
在创建
table
和index
时,都要带上属主(对应用户的表空间)
2 语法
2.1 创建
- 表空间创建者必须拥有
create tablespace
系统权限 - 创建表空间时,默认/可选 的子句很多,我们只要知晓最常用的即可。
- 非常完整的请参考: Oracle 12.2 官方文档 - create tablespace
常用语法:其中 [ ] 表示该参数可选
create [temporary | undo] tablespace "tbs"
datafile 'D:\oracle\tbs_01.dbf'
size 100m
[loggin | nologgin] -- 默认 loggin
[autoextend off] | [autoextend on next n1 maxsize m] -- 自动扩展, 默认 off, n1 默认 , m 默认 unlimited <= size n
[extent management local [uniform size n]] -- 默认 local, n = 64K;
[segment space management auto] -- 默认 auto, 且不建议被修改
-- 创建新用户,使用该表空间,方便测试
create user ODSDATA identified by 12345 default tablespace tbs
temporary tablespace temp quota unlimited on odstbs;
grant create session to ODSDATA;
grant resource to ODSDATA;
语法解析:
1. create tablespace tbs 创建一个名为 "tbs" 的表空间(最常用)
(1) temporary: 临时表空间,用于临时数据的存放
(2) undo: 撤销表空间,用于重做日志文件的存放
2. datafile 'D:\oracle\tbs_01.dbf' size 5m 指定数据文件的位置和大小
(1) 数据文件位置: "D:\oracle\tbs_01.dbf" -- 推荐使用绝对路径
(2) 数据文件大小: 5m
(3) 如果有多个文件,可以用逗号 , 隔开. 但是每个每个文件都要指明大小
3. loggin | nologgin 默认是 loggin,一般不写,但你要知道
(1) loggin: 创建表空间时,同时生成重做日志文件(数据丢失时,可以恢复)
(2) nologgin: 与 loggin 相反,但表创建速度快
4. autoextend 表空间是否自动扩展
(1) off: 不自动扩展,默认值
(2) autoextend on next 10m maxsize 100m
自动扩展,增量是 10m,最大大小是 100m
5. extent management local | dictionary 区管理
(1) local 本地管理,强烈推荐,从 Oracle 9i 开始,只能用 local,效率高
(2) dictionary 数据字典管理,以前的管理方式。
将数据文件中的每一个存储单元做为一条记录,在大量数据管理时,会产生大量的 insert、update 操作,严重影响性能。
同时,长时间对表数据的操作,会产生很多磁盘碎片,这就是为什么要做磁盘整理的原因。
6. uniform size n: 指定 extent 的固定大小
(1) size 8m: 固定为 8m
(2) 若不填,extent 默认 64k (参考: dba_tablespaces 中的 initial_extent)
7. segment space management auto | manual
(1) auto: 段空间由系统自动管理,只能使用在本地管理的表空间中(lob 字段的表除外)
(2) manual: 段空间手动管理,目前已不用,主要是为了向后兼容
当我们创建完后,也可通过数据字典查询上述设置的参数:
SELECT ddf.file_id,
ddf.file_name, -- 数据文件名称 datefile 'fileName'
dt.tablespace_name, -- 表空间名称 tablespace tbs
ddf.bytes / 1024 / 1024 || 'm' size_n, -- 初始数据文件大小,也就是 size n
dt.logging, -- 日志属性 loggin
ddf.autoextensible, -- 自动扩展
dt.extent_management, -- extent management local | dictionary
dt.allocation_type, -- system 长度自适应 | uniform 长度固定
dt.segment_space_management, -- segment space management auto | manual
dt.next_extent / 1024 / 1024 || 'm' next_n -- 数据文件增量大小,也就是 next n (当 allocata_type = 'uniform' 时,才有值)
FROM dba_tablespaces dt, -- tablespace_name
dba_data_files ddf -- file_name, file_id, tablespace_name
WHERE ddf.tablespace_name = dt.tablespace_name
AND dt.tablespace_name IN ('');
2.2 修改
- 系统内置的表空间是不允许修改的,如:
system、sysaux、temp、undo、users
- 表空间名称修改之后相应的数据文件、位置、大小没有变化
- 处于脱机状态的表空间不能修改其名称
1. 调整数据文件的大小
alter database datafile 'D:\oracle\tbs01_1.dbf' resize 10m;
2. 调整数据文件为自动扩展
alter database datafile 'D:\oracle\tbs01_1.dbf' autoextend on next 20m maxsize 1g; -- 增量 20m, 最大长度 1g
3. 新增数据文件
alter database datafile 'D:\oracle\tbs02_1.dbf' size 2000m; -- 不自动扩展
alter database datafile 'D:\oracle\tbs02_1.dbf' autoextend on next 20m maxsize 1g; -- 自动扩展
2.3 删除
- Oracle 数据库的任何表空间都可以删除(除了
system、sysaux、temp、undo、users
) - 表空间一旦删除就不能恢复,所以删除表空间前最好备份
- 不能删除含任何活动段的表空间,应该使表空间在被删除前脱机(很简单,不脱机或者说不关闭运行的 PL/SQL, 删除表空间会报错的)
- 删除表空间的用户必须要拥有
drop tablespace
权限
1. 删除空的表空间(数据文件还在)
drop tablespace tbs;
2. 删除表空间 和 数据文件
drop tablespace tbs including contents and datafiles;
3. 仅从数据字典中删除表空间信息,但数据文件仍然存在,但已经失去作用
drop tablespace tbs including contents;
2.4 查询
查询表空间信息:(若有多个数据文件,需分组求和)
SELECT ddf.file_id 文件id,
ddf.file_name 文件名,
dt.tablespace_name 表空间名,
dfs.block_id 块id,
dt.contents 表空间类型,
dt.extent_management 表空间管理模式,
dt.segment_space_management 块空间管理模式,
dt.allocation_type 分配类型, -- "system 系统随机" or "uniform 固定"
dt.logging 日志模式,
dt.force_logging 是否强制日志, -- 优先级 > 日志模式
ddf.autoextensible 是否自动扩展,
ddf.bytes / 1024 / 1024 "表空间初始大小(M)", -- 单位由 字节 -> MB
ddf.maxbytes / 1024 / 1024 "表空间最大扩展到多少(M)", -- 0 表示自动扩展: off
ddf.bytes / 1024 / 1024 "总大小(M)",
dfs.bytes / 1024 / 1024 "剩余大小(M)",
(1 - dfs.bytes / ddf.bytes) * 100 "使用率%"
FROM dba_tablespaces dt, -- tablespace_name
dba_data_files ddf, -- file_name, file_id, tablespace_name
dba_free_space dfs -- tablespace_name, file_id, block_id
WHERE ddf.tablespace_name = dt.tablespace_name
AND dfs.tablespace_name = ddf.tablespace_name
AND dfs.file_id = ddf.file_id
AND ddf.tablespace_name IN ('表空间名');
3 示例
3.1 创建自动扩展表空间
创建一个 100M 大小的数据库文件 student.dbf 的永久表空间 tbs_student, 每 10M 自动扩展,最大值为 500M
CREATE TABLESPACE tbs_student
DATAFILE 'D:\table_space\student.dbf'
SIZE 100m
AUTOEXTEND ON NEXT 10M MAXSIZE 500M -- 自动扩展, 每次扩展 10M, 最大扩展到 500M
PERMANENT -- 永久表空间,默认
EXTENT MANAGEMENT LOCAL;
通过数据字典对表空间进行查询:
SELECT dt.tablespace_name 表空间名,
dt.contents 表空间类型,
dt.extent_management 表空间管理模式, -- "LOCAL 默认,本地" or "DICTIONARY 数据字典"
dt.segment_space_management 段空间管理模式, -- "AUTO 默认,自动管理" or "MANUAL 手动管理"
dt.logging 默认日志属性, -- "LOGGING 默认" OR "NOLOGGING"
dt.allocation_type 分配类型, -- "SYSTEM 系统自动分配" or "UNIFORM 统一分配"
dt.next_extent 默认增量, -- next, 当 allocation_type = UNIFORM 时,才有值
ddf.file_id 文件id,
ddf.file_name 文件名,
ddf.autoextensible 是否自动扩展,
ddf.bytes / 1024 / 1024 "表空间初始大小 M", --,单位
ddf.maxbytes / 1024 / 1024 "表空间最大扩展到多少 M"
FROM dba_tablespaces dt, -- tablespace_name
dba_data_files ddf -- file_id
WHERE ddf.tablespace_name = dt.tablespace_name
AND ddf.tablespace_name = 'TBS_STUDENT';
查询结果:
3.2 表无法在表空间中扩展
原因:
- 表空间满了!
- 未设置表空间自动扩展
- 或设置了表空间自动扩展,但超过了
MAXSIZE
测试用户准备
-- 表空间创建语句
CREATE TABLESPACE "TESTTBS_02" DATAFILE
'D:\TABLE_SPACE\TESTTBS_02.DBF' SIZE 1m
AUTOEXTEND ON NEXT 1m MAXSIZE 2m
EXTENT MANAGEMENT LOCAL
SEGMENT SPACE MANAGEMENT AUTO;
-- 测试用户
CREATE USER test_tablespace IDENTIFIED BY 12345 DEFAULT TABLESPACE TESTTBS_02;
GRANT CREATE SESSION TO test_tablespace; -- 允许登录
GRANT RESOURCE TO test_tablespace; -- 不对用户表空间进行限制
测试语句:
CREATE TABLE test_tablespace.stu_info (
ID NUMBER(10),
NAME VARCHAR2(30)
);
DECLARE
v_sql_insert VARCHAR2(500);
BEGIN
-- 模拟插入语句
v_sql_insert := 'INSERT INTO test_tablespace.stu_info (id, NAME) VALUES (:b1, :b2)';
FOR i IN 1 .. 100000 LOOP
EXECUTE IMMEDIATE v_sql_insert
USING i, 'a' || i;
END LOOP;
END;
错误截图:
4 扩展
参考语句:
1. 修改表空间名
ALTER TABLESPACE old_name RENAME TO new_name;
2. 设置数据库的默认表空间
ALTER DATABASE DEFAULT TABLESPACE mytbs;
3. 设置数据库的默认临时表空间
ALTER DATABASE TEMPORARY TABLESPACE temptbs;
4. 查询数据库的默认表空间
SELECT t.username, t.default_tablespace, t.temporary_tablespace FROM dba_users t;
5. 允许数据文件自动扩展
ALTER DATABASE DATAFILE 'D:\oracle\tbs01_1.dbf' AUTOEXTEND ON NEXT 10m MAXSIZE 100m;
6. 使用表空间脱机/联机 (有效/无效)
ALTER TABLESPACE tbs01 ONLINE; -- 联机、有效
ALTER TABLESPACE tbs01 OFFLINE; -- 脱机、无效
7. 使表空间只读(仍可执行 drop 删除对象操作)
ALTER TABLESPACE tbs01 READ ONLY;
8. 使表空间可读写(脱机状态的表空间不能修改为读写状态)
ALTER TABLESPACE tbs01 READ WRITE;
4.1 常见疑问
1. 是自动扩展,为什么还会提示空间不足?
- 超过了
maxsize
,参考上述实例 3.1 表无法在表空间中扩展
AUTOEXTEND ON NEXT 1m MAXSIZE 2m
2.autoextend on 默认的 next 值是多少?
- 当
allocation_type = SYSTEM
时,next 值由系统统一分配,不固定 - 当
allocation_type = UNIFORM
时,next 值固定,如下
extent management local uniform size 8m -- next = 8m