各位看官,今天咱们不聊什么高深的算法,也不扯那些让人头秃的数学公式,咱们来唠唠数据库里一个特别"善变"的操作——ALTER TABLE。
你想想啊,生活中哪有那么多一成不变的事?今天你觉得手机号够用,明天老板就让你把微信号、邮箱、家庭住址全加上;今天你觉得某个字段叫 sdept 挺酷,明天甲方爸爸说这名字不够直观,得改成 sdepartment。数据库表也是一样,建的时候觉得完美,用着用着就会发现各种"当初脑子进了水"的时刻。
好在,Oracle 这位老大哥很贴心,给你准备了一把万能钥匙——ALTER TABLE。有了它,你就能对表进行各种"整容手术":加个字段、删个字段、改个字段名、换种数据类型,甚至还能把整张表搬到另一个"小区"(表空间)去。这玩意儿,简直就是数据库界的"变形金刚"!
不过啊,权力越大,责任越大。普通用户只能改自己那一亩三分地(自己模式下的表),想越权去改别人的表?不好意思,你得先拿到 ALTER ANY TABLE 这个系统权限,就好比你想去别人家搞装修,总得先拿到业主的钥匙吧?
好了,废话不多说,咱们一块儿来看看这个"变脸"大法到底怎么耍。
1. 给字段"整容"——字段管理
字段是什么?你可以把它理解成表格的一列,也就是每一行数据的某个属性。比如学生表里,姓名是一列,学号是一列,班级又是一列。有时候你觉得列不够用了,想加;有时候觉得某列多余了,想删;有时候又觉得某列的名字不够洋气,想改。这些操作在 SQL 里都是靠 ALTER TABLE 配合不同的"暗号"(子句)来实现的。
常用的暗号有四位:ADD(加)、DROP(删)、MODIFY(改)、RENAME(重命名),合起来就是"增删改名"四件套。
1.1 加字段(ADD)——“老板,再给我来一列”
加字段就像你装修房子时觉得储物空间不够,非要再打个柜子。语法长这样:
ALTER TABLE table_name
ADD (
column_name_1 datatype
[, column_name_n datatype] ...
);
举例时刻: 假设咱们有一张 student_1 表,记录学生的基本信息。突然有一天,辅导员说:“你得把学生的手机号、邮箱和通信地址也给我记上!” 你内心 OS:早干嘛去了?但手还是很诚实地敲下了这段 SQL:
ALTER TABLE student_1
ADD (
stelephone CHAR(12),
semail VARCHAR2(20),
saddress VARCHAR2(50)
);
瞅瞅,一口气加了仨字段!手机号用定长 CHAR(12),邮箱用变长 VARCHAR2(20),地址用 VARCHAR2(50)。这就好比你在表格里一口气开辟了三块新地盘,美滋滋。
1.2 改字段名(RENAME)——“换个马甲,换个心情”
有时候你起名字的时候一时手滑,或者后来觉得命名不规范,想把 sdept 改成 sdepartment。这时候就得祭出 RENAME 大法:
ALTER TABLE table_name
RENAME COLUMN column_name TO new_column_name;
举例走一个: 把学生表里"所在系"的字段名从 sdept 改成 sdepartment,让人一眼就能看懂:
ALTER TABLE student_1
RENAME COLUMN sdept TO sdepartment;
这就像你身份证上的名字叫"王大锤",但你嫌土,跑去派出所改成了"王星辰"——字段里的数据一点没变,但是非主键约束、索引这些引用该字段的地方也会跟着自动更新,Oracle 这点做得还是挺厚道的。
当然,你要是把外键引用的字段名给改了,那就得小心连环炸了。
1.3 改数据类型(MODIFY)——“我要扩容,别拦我”
数据类型改了,就跟你说好要买个 20 平米的储物间,后来发现东西太多塞不下,得扩成 30 平米一个道理。语法如下:
ALTER TABLE table_name
MODIFY column_name new_datatype;
实例整起来: 之前咱们把邮箱设成了 VARCHAR2(20),用着用着发现有些人的邮箱地址特别长,20 个字符根本装不下。那就麻溜地给它扩到 30:
ALTER TABLE student_1
MODIFY semail VARCHAR2(30);
注意坑点: 改数据类型可不是随心所欲的。你要是把 VARCHAR2 改成 NUMBER,Oracle 一看里面的数据全是字母,它肯定跟你翻脸。所以一般只建议往"兼容"的方向改,比如字符串扩长度、数字类型精度变高等等。而且改的时候,Oracle 会去检查已有数据能不能正常转过去,转不了就直接报错不让你改,这点还是挺靠谱的。
1.4 删字段(DROP)——“断舍离,优雅地告别”
删字段是件大事儿,因为这操作不可逆!字段一删,里面所有的数据也跟着灰飞烟灭,Oracle 还会把这块存储空间给回收了,相当干脆。语法:
-- 删一个字段
ALTER TABLE table_name DROP COLUMN column_name;
-- 删多个字段(省得一个一个来,太累)
ALTER TABLE table_name DROP (column_name1, column_name2, ...);
举例: 比如你觉得"通信地址"这个字段太鸡肋了,现在都用微信发定位了,谁还填地址啊?删!
ALTER TABLE student_1 DROP COLUMN saddress;
再狠一点,把手机号和邮箱也一起扬了:
ALTER TABLE student_1 DROP (stelephone, semail);
注意啦! 如果你要删的字段是主键,而且被别的表的外键引用着,那 Oracle 会像个保安一样拦住你:"不行,这字段有人依赖,删了会出大事!"你得先把那些外键约束给解了,才能动手删。
1.5 温柔地"假装删"——UNUSED 关键字
有时候你面对的是一张有几千万行数据的大表,正好赶上系统高峰期,直接 DROP COLUMN 会让数据库卡成 PPT,甚至引发血案。这时候该怎么办?
Oracle 给你安排了一个"先标记,后清理"的迂回战术——SET UNUSED。
ALTER TABLE table_name
SET UNUSED (column_name1, column_name2, ...);
你可以把它理解成:你要扔一个很重的柜子,但搬家公司还没来,你只能先给它贴上"待处理"的标签,等搬家公司来了再一口气搬走。
被标记成 UNUSED 的字段,在逻辑上已经"隐身"了——你 DESC 查看表结构时看不到它,也不能对它做任何操作。但物理上,它占用的磁盘空间还没释放,那坨数据还在那儿躺着呢。
等到夜深人静、系统没啥负载的时候,你再偷偷执行:
ALTER TABLE table_name DROP UNUSED COLUMNS;
这一下,Oracle 才真正去清理那些被标记的字段,释放存储空间。
那标记了 UNUSED 还能反悔吗?
理论上能,因为数据物理上还在。但这就像你前任的微信,虽然删了但聊天记录其实还在手机数据库里藏着,想恢复?得动用一些底层的骚操作,改数据字典、重启数据库……总之,特别麻烦,也很危险,强烈不建议这么干。所以在你按下 SET UNUSED 的回车键之前,先问自己三遍:“我真的不要这列了吗?”
2. 给表"变形"——表管理
搞完了字段的整容,咱们再来看看怎么对整张表进行"大变活人"。表级别的操作主要有四种:重命名(换个马甲)、移动(搬家)、截断(一键清空)和删除(彻底消失)。咱们这篇先唠前两个。
2.1 重命名表——“从王大锤到王星辰”
表名改起来那是相当简单,Oracle 给你两条路走:
方法一(RENAME): 直接粗暴,但只能在 SQL*Plus 里用。
RENAME student_1 TO stu;
方法二(ALTER TABLE … RENAME TO): 通用款,SQL*Plus、PL/SQL、Navicat 啥的都能跑。
ALTER TABLE stu RENAME TO student_2;
这就好比你微信昵称从"深夜emo的猪"改成了"阳光开朗大男孩",改完以后所有引用这张表的地方(存储过程、视图、代码里的 SQL)也跟着找不到北了——因为表名变了,它们引用的还是旧名字,肯定会报错。所以改名之前,务必想清楚影响范围!
2.2 移动表空间——“数据库界的搬家公司”
表空间(Tablespace)可以理解成数据库里的"小区"。每张表都住在某个小区里,有时候你觉得现在这个小区太挤了,或者想把相关的表都搬到同一个小区方便管理,这时候就得用 MOVE 操作。
语法:
ALTER TABLE table_name MOVE TABLESPACE tablespacename;
但是在搬家之前,你得先搞清楚:我现在住哪儿?
用下面这条 SQL 查一下表所在的表空间:
SELECT table_name, tablespace_name FROM user_tables;
实操一把,搬个家给大家看看:
先创建个新小区(新建表空间),叫 zzxy,数据文件 50M 大小:
CREATE TABLESPACE zzxy
DATAFILE '/home/shiyanlou/oracle/zzxy.dbf'
SIZE 50M
EXTENT MANAGEMENT LOCAL;
然后把 student_2 这张表搬过去:
ALTER TABLE student_2 MOVE TABLESPACE zzxy;
最后再查一下,确认搬家成功:
SELECT table_name, tablespace_name
FROM user_tables
WHERE table_name = 'STUDENT_2';
搞定!咱们的 student_2 表已经在新家 zzxy 舒舒服服地待着了。
小提醒: 搬家操作会重建索引、锁表,你要是搬一张几千万行的大表,最好也挑个业务低谷的时候干,别在人家双十一秒杀的时候搞事情。
好啦,今天咱们的"变脸"大法就先聊到这儿。记住,ALTER TABLE 虽然功能强大,但每次改动都像给正在飞行的飞机换引擎——能换是能换,但最好先评估一下风险,做好备份。数据库里没有后悔药(或者说后悔药的代价很大),三思而后行,这才是老司机的修养。
下一回,咱们接着唠怎么"截断"表(TRUNCATE)和"删除"表(DROP),这两种操作有什么区别?哪个更快?为啥 TRUNCATE 被称作"暴力清空"?敬请期待!

1882

被折叠的 条评论
为什么被折叠?



