ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

PostgresSql更改字段位置后,数据库异常

2021-12-02 14:02:01  阅读:146  来源: 互联网

标签:PostgresSql good postgres 更改 数据库 Nothing 24894 impossible Kenyon


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表字段的顺序,否则极有可能造成数据奔溃或不可访问。要更改表字段的顺序,一般就通过重建表或者创建新字段以及使用视图等其他手段来实现。

标签:PostgresSql,good,postgres,更改,数据库,Nothing,24894,impossible,Kenyon
来源: https://www.cnblogs.com/zhenren001/p/15632906.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有