Postgres 14:删除information_schema.columns记录会删列吗?与ALTER TABLE等价吗?
Postgres批量删除列:ALTER TABLE vs 直接修改information_schema的区别
两组操作完全不等价,且第二组无法执行
你想直接DELETE FROM information_schema.columns的思路行不通——information_schema下的所有对象都是系统视图,本质是对Postgres底层系统表(比如pg_attribute、pg_class)的封装,这些视图是只读的,不允许执行DELETE、UPDATE这类DML操作,尝试执行会直接报错。
而第一组的ALTER TABLE DROP COLUMN是Postgres官方支持的合法删列方式,会真正修改表结构。
ALTER TABLE DROP COLUMN的额外操作
执行ALTER TABLE DROP COLUMN时,Postgres会做这些关键操作:
- 物理层面处理列数据:标记列已删除(Postgres不会立即回收存储空间,后续
VACUUM操作会释放) - 维护依赖关系:如果被删列关联了索引、触发器、视图或外键,默认会报错阻止操作;若加了
CASCADE参数,则会自动删除依赖该列的对象 - 更新系统元数据:同步修改
pg_attribute等底层系统表,保证数据库元数据的一致性 - 持有表锁:默认会获取表的
ACCESS EXCLUSIVE锁,执行期间会短暂阻塞该表的读写操作(锁的持有时间取决于表大小,小表几乎无感)
实现批量删列的正确方式
既然需要用WHERE筛选批量删列,你可以通过生成动态SQL来实现,比如用PL/pgSQL写个脚本:
DO $$ DECLARE rec record; BEGIN FOR rec IN SELECT table_name, column_name FROM information_schema.columns WHERE table_name IN ('some_table_1', 'some_table_2') AND column_name IN ('column_1', 'column_2') LOOP EXECUTE format('ALTER TABLE %I DROP COLUMN IF EXISTS %I;', rec.table_name, rec.column_name); END LOOP; END $$;
这个脚本会自动遍历符合条件的列,逐个执行ALTER TABLE DROP COLUMN操作,既满足批量筛选的需求,又符合Postgres的规范。
内容的提问来源于stack exchange,提问作者Prosto_Oleg
相关产品推荐
相关产品推荐

