为PostgreSQL数据库中没有主键的表增加主键

前端之家收集整理的这篇文章主要介绍了为PostgreSQL数据库中没有主键的表增加主键前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Postgresql数据库测试环境中有多张表没有添加主键约束,只有一个serial的自增字段。现在需要把那些没有主键的表都加上,serial类型的字段为id 。

首先是怎么找到Postgresql数据库中哪些表没有主键?我们看下pg_class这个表,里面有个relhaspkey字段,如果为t说明有主键,f即没有主键。例如下面这个sql

SELECTn.nspnameAS"Schema",c.relnameAS"TableName",c.relhaspkeyAS"HasPK"
FROM
pg_catalog.pg_classc
JOIN
pg_namespacen
ON(
c.relnamespace=n.oid
ANDn.nspnameNOTIN('information_schema','pg_catalog')
ANDc.relkind='r'
)
WHEREc.relhaspkey='f'
ORDERBYc.relhaspkey,c.relname
;

然后就是对这些表增加主键约束。删除添加主键的sql如下所示:

altertableserverdropconstraintserver_pkey;
altertableserveraddprimarykey(id);

主键添加完成之后可以通过\d查看。

zhangnq=#\dserver
Table"public.server"
Column|Type|Modifiers
--------+---------------+------------------------------------------------------
id|integer|notnulldefaultnextval('server_int_seq'::regclass)
ip|character(50)|
Indexes:
"server_pkey"PRIMARYKEY,btree(id)

最后就是把这个思路写到脚本里面,运行脚本批量添加。脚本里面把执行失败的表都放在error.log文件中。

脚本:

#!/bin/bash
exportPATH=/opt/Postgresql/93/bin:$PATH
exportPGDATA=/data/pgsql
exportPGHOME=/opt/Postgresql/93
exportPGPORT=5432
dbname=$1
if[!$dbname];then
echo"Pleaseenterthedatabasename."
exit1
fi
psql-c"\dt"-d$dbname>/dev/null
if[$?-ne0];then
exit1
fi
error_log="error.log"
echo"">$error_log
sql=`cat<<EOF
SELECTn.nspnameAS"Schema",c.relnameAS"TableName"
FROM
pg_catalog.pg_classc
JOIN
pg_namespacen
ON(
c.relnamespace=n.oid
ANDn.nspnameNOTIN('information_schema',c.relname
;
EOF`
schemas=`psql-t-A-c"$sql"-d$dbname|cut-d"|"-f1`
tables=`psql-t-A-c"$sql"-d$dbname|cut-d"|"-f1`
forresin`psql-t-A-c"$sql"-d$dbname`
do
schema=`echo$res|cut-d"|"-f1`
table=`echo$res|cut-d"|"-f2`
tablename=`echo"$schema.$table"`
psql-e-c"altertable$tablenameaddprimarykey(id)"-d$dbname
if[$?-ne0];then
echo"$dbname:Addprimarykeyto$tablenameerror.">>$error_log
fi
done

说下碰到的的问题,在测试的时候发现如果把主键drop掉之后pg_class.relhaspkey值还是为t,但是用\d查看确实没有主键了。解决的办法是手动vacuum这个表,即vacuum server 。

zhangnq=#selectrelname,relhaspkeyfrompg_classwhererelname='server';
relname|relhaspkey
---------+------------
server|t
(1row)
zhangnq=#altertableserverdropconstraintserver_pkey;
ALTERTABLE
zhangnq=#selectrelname,relhaspkeyfrompg_classwhererelname='server';
relname|relhaspkey
---------+------------
server|t
(1row)
zhangnq=#vacuumserver;
VACUUM
zhangnq=#selectrelname,relhaspkeyfrompg_classwhererelname='server';
relname|relhaspkey
---------+------------
server|f
(1row)
zhangnq=#altertableserveraddprimarykey(id);
ALTERTABLE
zhangnq=#selectrelname,relhaspkeyfrompg_classwhererelname='server';
relname|relhaspkey
---------+------------
server|t
(1row)

查看pg_class的说明后发现原来pg_class只有在状态由false变成ture的时候会自动修改。这么设计可以提高并发性。

SeveraloftheBooleanflagsinpg_classaremaintainedlazily:theyareguaranteedtobetrueifthat'sthecorrectstate,butmaynotberesettofalseimmediatelywhentheconditionisnolongertrue.Forexample,relhasindexissetbyCREATEINDEX,butitisneverclearedbyDROPINDEX.Instead,VACUUMclearsrelhasindexifitfindsthetablehasnoindexes.Thisarrangementavoidsraceconditionsandimprovesconcurrency.

参考链接

http://www.postgresql.org/message-id/1395116664140-5796526.post@n5.nabble.com

原文地址:http://www.sijitao.net/2026.html

原文链接:https://www.f2er.com/postgresql/194998.html

猜你在找的Postgre SQL相关文章