PostgresSql更改字段位置后,数据库异常
2024-10-21 09:36:27
SQL server的studio有一个功能,可以随意拖拽表字段,更改其位置并使之重新排序,有同事问起,Postgres是否也可以。Postgres每个字段的顺序是在系统表pg_attribute里面定义,下面实际操作一下看是否支持。
数据准备:
postgres=# create table tbl_kenyon(id int,vname varchar(30),remark text);
CREATE TABLE
postgres=# insert into tbl_kenyon select generate_series(1,10),'Kenyon_good','Nothing is impossible';
INSERT 0 10
postgres=# select attrelid,attname,attnum from pg_attribute where attrelid = (select relfilenode from pg_class where relname = 'tbl_kenyon');
attrelid | attname | attnum
----------+----------+--------
24894 | tableoid | -7
24894 | cmax | -6
24894 | xmax | -5
24894 | cmin | -4
24894 | xmin | -3
24894 | ctid | -1
24894 | id | 1
24894 | vname | 2
24894 | remark | 3
(9 行记录)
postgres=# select ctid,* from tbl_kenyon;
ctid | id | vname | remark
--------+----+-------------+-----------------------
(0,1) | 1 | Kenyon_good | Nothing is impossible
(0,2) | 2 | Kenyon_good | Nothing is impossible
(0,3) | 3 | Kenyon_good | Nothing is impossible
(0,4) | 4 | Kenyon_good | Nothing is impossible
(0,5) | 5 | Kenyon_good | Nothing is impossible
(0,6) | 6 | Kenyon_good | Nothing is impossible
(0,7) | 7 | Kenyon_good | Nothing is impossible
(0,8) | 8 | Kenyon_good | Nothing is impossible
(0,9) | 9 | Kenyon_good | Nothing is impossible
(0,10) | 10 | Kenyon_good | Nothing is impossible
(10 行记录)
数据调整,校验:
postgres=# update pg_attribute set attnum = 4 where attrelid = 24894 and attname = 'id';
UPDATE 1
postgres=# update pg_attribute set attnum = 1 where attrelid = 24894 and attname = 'vname';
UPDATE 1
postgres=# update pg_attribute set attnum = 2 where attrelid = 24894 and attname = 'id';
UPDATE 1
postgres=# select attrelid,attname,attnum from pg_attribute where attrelid = (select relfilenode from pg_class where relname = 'tbl_kenyon');
attrelid | attname | attnum
----------+----------+--------
24894 | tableoid | -7
24894 | cmax | -6
24894 | xmax | -5
24894 | cmin | -4
24894 | xmin | -3
24894 | ctid | -1
24894 | vname | 1
24894 | id | 2
24894 | remark | 3
(9 行记录)
但是查询的时候会直接报错
postgres=# select * from tbl_kenyon;
ERROR: invalid memory alloc request size 1870229097
postgres=# select * from tbl_kenyon limit 1;
ERROR: invalid memory alloc request size 1870229097
postgres=# vacuum full verbose analyze tbl_kenyon;
INFO: vacuuming "public.tbl_kenyon"
ERROR: invalid memory alloc request size 1870229097
才10条数据肯定不可能报这种内存不够的错误,其实是表/数据奔溃。
基于这个表再建其他表,同样是不可访问的。
postgres=# create table tbl_kenyon_new as select *from tbl_kenyon;
SELECT 10
postgres=# select * from tbl_kenyon_new;
ERROR: invalid memory alloc request size 1870229097
我们试着把顺序改回来:
postgres=# update pg_attribute set attnum = 4 where attrelid = 24894 and attname = 'id';
UPDATE 1
postgres=# update pg_attribute set attnum = 2 where attrelid = 24894 and attname = 'vname';
UPDATE 1
postgres=# update pg_attribute set attnum = 1 where attrelid = 24894 and attname = 'id';
UPDATE 1
postgres=# select ctid,* from tbl_kenyon;
ctid | id | vname | remark
--------+----+-------------+-----------------------
(0,1) | 1 | Kenyon_good | Nothing is impossible
(0,2) | 2 | Kenyon_good | Nothing is impossible
(0,3) | 3 | Kenyon_good | Nothing is impossible
(0,4) | 4 | Kenyon_good | Nothing is impossible
(0,5) | 5 | Kenyon_good | Nothing is impossible
(0,6) | 6 | Kenyon_good | Nothing is impossible
(0,7) | 7 | Kenyon_good | Nothing is impossible
(0,8) | 8 | Kenyon_good | Nothing is impossible
(0,9) | 9 | Kenyon_good | Nothing is impossible
(0,10) | 10 | Kenyon_good | Nothing is impossible
(10 行记录)
OK,它回来了。目前该系统表的表结构有一个组合主键(attrelid,attrnum),所以不能随便更新attrnum值,极有可能报如下错:
postgres=# update pg_attribute set attnum = 1 where attrelid = 24894 and attname = 'id';
ERROR: duplicate key value violates unique constraint "pg_attribute_relid_attnum_index"
描述: Key (attrelid, attnum)=(24894, 1) already exists.
总结:
目前并不希望用户去更改postgres表字段的顺序,否则极有可能造成数据奔溃或不可访问。要更改表字段的顺序,一般就通过重建表或者创建新字段以及使用视图等其他手段来实现。
最新文章
- JavaScript的Tab切换
- Selenium自动化测试实践 公开班(广州)
- 使用即时文件初始化提高SQL Server性能
- 【读书笔记】iOS-NSString的length
- POJ1976A Mini Locomotive(01背包装+连续线段长度)
- cocos2d-x 2.1.2 bug发现
- WordPress NextGEN Gallery ‘upload.php’任意文件上传漏洞
- NN-Neural Network
- 使用SVG基本操作API
- Coins、Tokens、山寨币:区别在哪里
- ";_OBJC_CLASS_$_MAMapServices";, referenced from: 的问题修复
- PyQt5 QSerialPort子线程操作
- EF三种编程方式的区别Database first ,Model first ,code first
- Mtlab:抛物型方程的交替方向隐格式(ADI)
- io系列之常用流二
- HTML5漫谈(7)——如何保护HTML5应用代码
- JAVA中使用Log4j2日志和Lombok引入日志的方法
- jquery全国省市区三级联动插件distpicker
- 跟我一起使用electron搭建一个文件浏览器应用吧(四)
- hdu-6415 Rikka with Nash Equilibrium dp计数题
热门文章
- 9V,12V输入充3.7V单节锂电池电路和芯片
- .net做一个基于ChatGpt的微信机器人吧~[全教程]
- EXACT函数
- java中的数值运算
- 学 Rust 要几天?「GitHub 热点速览 v.22.51」
- IdentityServer4 - V4 概念理解及认证授权过程
- 【转载】MSSQL汉字首字母查询处理自定义函数
- [python] CairoSVG使用教程
- [机器学习] Yellowbrick使用笔记8-模型选择可视化
- 1_ES6中拓展运算符的使用