Oracle OCP认证考试题目详解082系列第16题

一、题目相关

1.英文题目和英语选项和答案

Question #16, Topic 1

Which three statements are true about dropping and unused columns in an Oracle database? (Choose three.)

Options:

  • A. A primary key column referenced by another column as a foreign key can be dropped if using the CASCADE option. (Most Voted)
  • B. An UNUSED column's space is reclaimed automatically when the block containing that column is next queried.
  • C. An UNUSED column's space is reclaimed automatically when the row containing that column is next queried.
  • D. Partition key columns cannot be dropped. (Most Voted)
  • E. A DROP COLUMN command can be rolled back
  • F. A column that is set to UNUSED still counts towards the limit of 1000 columns per table (Most Voted)

Correct Answer: A, D, F


2.题目和选项的翻译,答案

题干翻译:

关于 Oracle 数据库中删除列(dropping)和未使用列(unused columns) ,下面哪三个陈述是正确的?(选三个)

选项翻译:

  • A. 如果一个主键列被另一个列以外键方式引用 ,那么使用 CASCADE 选项就可以把它删掉。
  • B. 当一个包含 UNUSED 列的数据块(block)下一次被查询时,该列占用的空间会被自动回收
  • C. 当一个包含 UNUSED 列的行(row)下一次被查询时,该列占用的空间会被自动回收
  • D. **分区键列(partition key columns)**不能被删除。
  • E. DROP COLUMN 命令可以回滚(rolled back)
  • F. 被设置为 UNUSED 的列,仍然计入每张表 1000 列的上限之中。

答案:A、D、F

💡 一句话剧透:这道题考的就是 Oracle 对"删列"和"闲置列"的一堆硬性规矩。A(级联删主键列)、D(分区键不能动)、F(闲置列也算名额)是铁律;而 B/C(自动回收空间)和 E(能回滚)是典型的"想当然"陷阱。


3.考察的知识点摘要

序号 知识点 一句话理解
1 SET UNUSEDDROP COLUMN 的区别 SET UNUSED = "标记退役,不真删";DROP COLUMN = 真正删除
2 CASCADE CONSTRAINTS 删被外键引用的主键列时,靠它级联清除约束
3 分区键列不可删除 删分区键会报 ORA-12984
4 DDL 不可回滚 DROP COLUMN 是 DDL,自动提交,ROLLBACK 无效
5 UNUSED 列仍占 1000 列限额 不真正 DROP,它就一直"占坑"
6 UNUSED 空间回收方式 只能靠 ALTER TABLE ... DROP UNUSED COLUMNS 显式回收,查询不会自动回收

4.题目解析

咱们先把 6 个选项挨个"过堂",配合真实实验场景 👇

🔹 A. 被外键引用的主键列,用 CASCADE 就能删 ------ ✅ 正确(Most Voted)

主键列如果被别的外键"盯上"(引用),直接 DROP COLUMN 会报错。但只要加上 CASCADE CONSTRAINTS (题里说的 CASCADE option),Oracle 就会连带着把引用它的外键约束一起干掉,列也就删掉了。所以 A 对。

🔹 D. 分区键列不能删 ------ ✅ 正确(Most Voted)

分区表的分区键 决定了数据按哪个键值分到哪个分区,是分区的"命根子"。你要是把它删了,整个分区结构就崩了。Oracle 直接甩你一个 ORA-12984: cannot drop partitioning column。所以 D 对。

🔹 F. UNUSED 列仍计入 1000 列上限 ------ ✅ 正确(Most Voted)

SET UNUSED 只是给列打个"退役"标记,物理上它还在表里躺着 ,并不释放"每表最多 1000 列"的名额。官方文档原话:"Until you actually drop these columns, they continue to count toward the absolute limit of 1000 columns." 所以 F 对。

🔹 B. block 被查询时自动回收 UNUSED 空间 ------ ❌ 错误

查询(query)不会触发空间回收 。UNUSED 列的空间,要么等你显式执行 ALTER TABLE ... DROP UNUSED COLUMNS,要么(在 19c 某些场景下)是更新(update)行时才可能清理------绝不是"查一下就回收"。而且 B 说的是"block 级别查询",更不对。

🔹 C. row 被查询时自动回收 UNUSED 空间 ------ ❌ 错误

跟 B 一伙的坑。同样是"查询自动回收"这个错误前提。就算 19c 有延迟清理,触发条件是 UPDATE 不是 QUERY。所以 C 错。

🔹 E. DROP COLUMN 可以回滚 ------ ❌ 错误

DROP COLUMNDDL 语句 ,Oracle 执行 DDL 时会先隐式 COMMIT,执行完再隐式 COMMIT,根本没法 ROLLBACK。这是所有 DDL 的通病,E 错。

⚠️ 一个易混点(考试常挖坑)

  • SET UNUSED ≠ 真删:只是标记,列还占坑(对应 F 正确)、空间不释放(对应 B/C 错)。
  • 想彻底清理,必须再来一条 ALTER TABLE ... DROP UNUSED COLUMNS------这才是"唯一允许对 unused 列做的操作",也才真正回收磁盘空间。

5.考察的知识点详情

下面用 Oracle 实操场景逐个击破,帮你把这套"删列/闲置列"彻底玩明白。假设以普通用户登录,先建两张测试表:

sql 复制代码
CREATE TABLE orders (
    ord_no    NUMBER PRIMARY KEY,
    cust_no   NUMBER,
    amount    NUMBER
);

CREATE TABLE order_items (
    item_no  NUMBER,
    ord_no   NUMBER,
    product  VARCHAR2(50),
    CONSTRAINT fk_ord FOREIGN KEY (ord_no) REFERENCES orders(ord_no)
);

INSERT INTO orders VALUES (1, 100, 999);
INSERT INTO order_items VALUES (1, 1, 'Keyboard');
COMMIT;

1️⃣ CASCADE CONSTRAINTS 删被引用的主键列(对应选项 A)

❌ 不加 CASCADE ------ 报错:

sql 复制代码
ALTER TABLE orders DROP COLUMN ord_no;
-- ORA-12991: column is referenced by a constraint (fk_ord)

✅ 加 CASCADE CONSTRAINTS ------ 成功:

sql 复制代码
ALTER TABLE orders DROP COLUMN ord_no CASCADE CONSTRAINTS;
-- 主键列删掉了,order_items 上的外键约束 fk_ord 也被一并级联删除

📌 这就是 A 选项的正确姿势:CASCADE = "连引用它的约束一起带走"。

2️⃣ 分区键列不能删(对应选项 D)

sql 复制代码
CREATE TABLE sales (
    sale_id   NUMBER,
    sale_date DATE
) PARTITION BY RANGE (sale_date) (
    PARTITION p1 VALUES LESS THAN (DATE '2023-01-01'),
    PARTITION p2 VALUES LESS THAN (DATE '2024-01-01')
);

ALTER TABLE sales DROP COLUMN sale_date;
-- ORA-12984: cannot drop partitioning column

📌 sale_date 是分区键,删它 Oracle 直接拒绝。要改分区键只能重建表。D 对。

3️⃣ DDL 不可回滚(对应选项 E)

sql 复制代码
ALTER TABLE orders DROP COLUMN cust_no;   -- 假设列存在
ROLLBACK;
-- 没用!DROP COLUMN 是 DDL,早已自动提交,列已经没了

📌 记住口诀:DDL = 自动提交 = 无法回滚 。E 错得彻彻底底。想"后悔"只能靠闪回(Flashback)备份恢复,ROLLBACK 帮不上忙。

4️⃣ SET UNUSED vs DROP COLUMN(对应 F、B、C)

sql 复制代码
-- 先给 orders 加几列方便演示
ALTER TABLE orders ADD (col_a NUMBER, col_b NUMBER);

-- 方式一:SET UNUSED(标记退役,不真删)
ALTER TABLE orders SET UNUSED (col_a);
-- 此时 col_a 已不可访问,但仍占 1000 列的名额 → 对应 F 正确

-- 方式二:真正删除
ALTER TABLE orders DROP COLUMN col_b;   -- DDL,立即生效且不可回滚

验证 F(UNUSED 仍占 1000 列限额):

sql 复制代码
-- 当表接近 1000 列时,把一些列 SET UNUSED 并不会腾出"列数名额"
-- 只有真正 DROP 掉,名额才释放
SELECT COUNT(*) FROM user_tab_cols WHERE table_name = 'ORDERS';

验证 B/C(空间不会因查询自动回收):

sql 复制代码
SELECT * FROM orders;   -- 随便查,col_a 的空间纹丝不动 ❌不会回收

-- 唯一正确的回收姿势:显式 DROP UNUSED COLUMNS
ALTER TABLE orders DROP UNUSED COLUMNS;   -- ✅ 这时才真正移除列、回收磁盘空间

📌 B/C 为什么错 :关键词是"queried(查询) "。查询从来不回收空间;回收要么靠上面这条显式命令,要么 19c 里是"更新行(update)"才可能顺带清理------绝不是查询。所以 B、C 都错。

5️⃣ 完整工作流小结(DBA 必备)

sql 复制代码
-- Step 1:业务低峰期,先标记退役(速度快,不锁太久)
ALTER TABLE huge_table SET UNUSED (old_col);

-- Step 2:空闲时,真正删除并回收空间
ALTER TABLE huge_table DROP UNUSED COLUMNS CHECKPOINT 1000;
-- CHECKPOINT 分批提交,避免大表长时间锁表

6️⃣ 几个 DBA 必记的"坑"

  • 🔴 SET UNUSED 是单向操作:标记后列立刻不可访问,数据也读不回来了,慎用。
  • 🔴 UNUSED 列只能通过 DROP UNUSED COLUMNS 清理,没有其他操作允许作用在它身上。
  • 🟡 压缩表 + UNUSED 列 容易撞 ORA-01792(超过 1000 列),MOS 文档 Doc ID 2259600.1 有专门说明------这正是 F 选项的现实来源。
  • 🟡 CASCADE 会连带删约束,生产环境先查 user_constraints 确认影响,别盲目级联。

好问题!这个 UNUSED 是 Oracle 里一个特别实用、但又容易让人迷糊的概念。一句话先给结论:

UNUSED 列 = 被"打上退役标签"的列------Oracle 假装它不存在了,但它其实还躺在表里没走。

下面我用 DBA 小白最好懂的方式讲透它。


二、UNUSED 列是啥?

1.先搞清楚:为什么要"闲置列"这种东西?

想象一下这个场景👇

你有一张几十亿行的大表,现在业务改造,决定不要某一列了。如果你直接:

sql 复制代码
ALTER TABLE huge_table DROP COLUMN old_col;

会发生什么?Oracle 得逐行扫描、把每一行的这个列数据抠掉 ------几十亿行啊,耗时巨久、锁表巨长、日志巨多,业务直接卡死

于是 Oracle 想了个聪明的折中方案:

"要不咱先不真删,只是给它贴个'退役'标签,让所有人当它不存在?等哪天业务不忙了,再偷偷彻底删掉?"

这个"退役标签",就是 UNUSED


2.UNUSED 列到底是什么状态 🔍

用一句话 + 一个比喻:

UNUSED 列 ≈ 公司里的"退休员工" :花名册上还占着编制(占名额),工位也还没腾(占空间),但门禁卡注销了、谁也联系不上他了(不能访问)。

具体来说,一列被 SET UNUSED 后:

维度 表现
能不能 SELECT / INSERT / UPDATE? ❌ 不行,像"消失"了一样
还在不在表结构里? ✅ 还在,占着"每表 1000 列"的名额
磁盘空间释放了吗? ❌ 没释放,数据还占着块
还能恢复回来吗? ❌ 不行,标记不可逆
怎么才能真正删掉? ALTER TABLE ... DROP UNUSED COLUMNS

3.动手看看:UNUSED 列长啥样

1️⃣ 建表 + 标记退役

sql 复制代码
CREATE TABLE employees (
    emp_id   NUMBER,
    name     VARCHAR2(50),
    old_phone NUMBER,       -- 打算废弃的旧电话列
    salary   NUMBER
);

-- 把它标记为 UNUSED
ALTER TABLE employees SET UNUSED (old_phone);

2️⃣ 试试访问它 → 直接报错

sql 复制代码
SELECT old_phone FROM employees;
-- ORA-00904: "OLD_PHONE": invalid identifier

📌 对外的感觉就像"这列蒸发了",但其实它还在底层躺着。

3️⃣ 去数据字典里抓它 → 藏在 USER_TAB_COLS

sql 复制代码
SELECT column_name, hidden_column, unused_column
FROM user_tab_cols
WHERE table_name = 'EMPLOYEES';

你会看到 old_phoneUNUSED_COLUMN = YES

⚠️ 注意:普通的 USER_TAB_COLUMNS 视图看不到 UNUSED 列,得用 USER_TAB_COLS 才能揪出来。这也是它"对外隐身"的体现。


4.UNUSED 的两大"坑点"(正是上一题考点)

🔴 坑点 1:它占着 1000 列的名额不放

Oracle 规定一张表最多 1000 列 。你以为 SET UNUSED 就腾出名额了?想多了,名额照占!

sql 复制代码
-- 假设表已经有 999 列,再把 1 列 SET UNUSED
ALTER TABLE t SET UNUSED (col_x);   -- col_x 退役了

-- 你以为能加新列?错!
ALTER TABLE t ADD (col_new NUMBER);
-- ORA-01792: maximum number of columns in a table or view is 1000

📌 只有真正 DROP 掉,名额才释放。 这就是上一题 F 选项正确的原因。

🔴 坑点 2:它的空间不会自动回收

你以为放着不管它会慢慢"自己消失"?不会。 查询、更新都不会自动清理它。

唯一的"清道夫"命令:

sql 复制代码
ALTER TABLE employees DROP UNUSED COLUMNS;
-- ✅ 这时 old_phone 才被真正移除,磁盘空间才回收

大表怕锁太久?分批来:

sql 复制代码
ALTER TABLE huge_table DROP UNUSED COLUMNS CHECKPOINT 1000;
-- 每处理 1000 行提交一次,避免长时间锁表

5.SET UNUSED vs DROP COLUMN 对照表 ⚖️

对比项 SET UNUSED DROP COLUMN
速度 ⚡ 极快(只改字典) 🐢 慢(逐行清数据)
锁表时长 很短 很长(大表灾难)
数据是否还在 ✅ 还在(不可访问) ❌ 真删了
空间是否释放 ❌ 不释放 ✅ 释放
能否回滚 否(DDL) 否(DDL)
是否占 1000 名额 ✅ 占 ❌ 不占
适用场景 大表、业务高峰 小表、空闲时

6.标准工作流(DBA 最佳实践)💼

sql 复制代码
-- Step 1【业务运行时】:先快速标记退役,几乎不影响业务
ALTER TABLE huge_table SET UNUSED (old_col);

-- Step 2【业务低谷期】:再彻底清理 + 回收空间
ALTER TABLE huge_table DROP UNUSED COLUMNS CHECKPOINT 1000;

📌 这就是 UNUSED 的设计初衷:把"耗时的真删除"推迟到合适的时间再做,两步走,业务丝滑不断档。


7.一句话总结(背下来)🎯

UNUSED 列 = "假删除 / 退役标记"。

  • 对外:像消失了(不能访问);
  • 对内:还赖着不走(占名额、占空间);
  • 清理:只能靠 DROP UNUSED COLUMNS,查询和更新都不会自动回收。
    顺口溜:"SET UNUSED 贴标签,列还在、名还在、空间还在;想彻底,DROP UNUSED 来清理;名额不腾别怪我,查询不收是真理。"

这样就把上一题 B/C(查询不回收)、E(DDL 不可回滚)、F(占 1000 名额) 三个选项为什么对/错,彻底串起来了------它们本质上都是在考你对 UNUSED 列"赖着不走"这个特性的理解。

最后,各位学习者,点个关注吧!我们一起成长,一起成为大佬!


📌 一句话记忆法(背下来考试稳):

删列三件套 ------ A 能删(CASCADE)、D 不能删(分区键)、F 占坑(1000 限额)

两大陷阱 ------ B/C 查询不回收(要 DROP UNUSED COLUMNS)、E 是 DDL 不能回滚
顺口溜:"SET UNUSED 是标记,DROP 才真离;回收靠命令,查询不搭理;分区键别碰,外键要级联;DDL 不回头,名额照常占。"

相关推荐
搭贝25 分钟前
国资报送责任制怎么建?三级责任矩阵设计
android·数据库·人工智能·线性代数·低代码·矩阵·制造
杨云龙UP26 分钟前
Linux 下 MySQL 常用登录方式及 Socket 排查指南
linux·运维·数据库·mysql·登录·xtrabackup·主从复制
惜分飞40 分钟前
kcratr_nab_less_than_odr和system坏块故障处理
数据库·oracle
q567315231 小时前
Curl 报 CONNECT tunnel failed, response 6xx:排查思路全解
数据库·网络协议·scrapy·http·中间件·http代理
疯狂打码的少年1 小时前
【数据库技术】两级映像与数据独立性(逻辑/物理独立性)
数据库·笔记
Elastic 中国社区官方博客1 小时前
从告警到根因仅需 3 分钟:使用 Elastic Agent Builder 实现自动化根因分析
运维·数据库·人工智能·elasticsearch·自动化·可用性测试
惜分飞1 小时前
obet forcecopy功能抢救硬件故障中的数据文件
数据库·oracle
Elastic 中国社区官方博客1 小时前
驯服 PUNKs:ES|QL 如何查询 Elasticsearch 从未被告知的字段
大数据·sql·elasticsearch·搜索引擎·全文检索
TDengine (老段)2 小时前
TDengine 应用案例 — 能源与电力监控
大数据·数据库·物联网·能源·时序数据库·tdengine·涛思数据