postgresql中的ctid解读
作者:瀚高PG实验室 (Highgo PG Lab)
这篇文章主要介绍了postgresql中的ctid使用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
postgresql中的ctid
ctid表示
数据行在它所处的表内的物理位置,ctid字段的类型是tid。
尽管ctid可以快速定位数据行,每次vacuum full之后,数据行在块内的物理位置就会移动,即ctid会发生变化,所以ctid不能作为长期的行标识符,应该使用主键来标识一个逻辑行。
查看ctid
示例如下:
mydb=# select ctid,id from t1 ; ctid | id -------+---- (0,1) | 10 (0,2) | 11 (2 rows)
由上可知,ctid由两个数字组成,第一个数字表示物理块号,第二个数字表示在物理块中的行号。tid类型可以使用字符串输入,如想查询表t1中0号物理块中第11行内容,
示例如下:
mydb=# select ctid,id from t1 where ctid='(0,11)'; ctid | id --------+---- (0,11) | 19 (1 row)
利用ctid可以删除一个表中的重复数据,
例如表t1有以下数据
mydb=# select id,count(*) from t1 group by id; id | count ----+------- 34 | 2 43 | 2 25 | 2 32 | 2 12 | 1 1 | 1 10 | 1 26 | 2 42 | 2 11 | 1 18 | 1 16 | 1 39 | 2 54 | 2 47 | 2 13 | 1 49 | 2 22 | 3 24 | 2 14 | 1 45 | 2 46 | 2 27 | 2 48 | 2 55 | 2 17 | 1 28 | 2 36 | 2 15 | 1 38 | 2 30 | 2 50 | 2 33 | 2 40 | 2 56 | 2 53 | 2 19 | 1 29 | 2 21 | 1 57 | 2 51 | 2 23 | 2 41 | 2 31 | 2 35 | 2 52 | 2 20 | 1 44 | 2 37 | 2 (49 rows)
删除重复数据的SQL为:
mydb=# delete from t1 a where a.ctid <>(select min(b.ctid) from t1 b where a.id=b.id); DELETE 37 mydb=# select id,count(*) from t1 group by id; id | count ----+------- 34 | 1 43 | 1 25 | 1 32 | 1 12 | 1 1 | 1 10 | 1 26 | 1 42 | 1 11 | 1 18 | 1 16 | 1 39 | 1 54 | 1 47 | 1 13 | 1 49 | 1 22 | 1 24 | 1 14 | 1 45 | 1 46 | 1 27 | 1 48 | 1 55 | 1 17 | 1 28 | 1 36 | 1 15 | 1 38 | 1 30 | 1 50 | 1 33 | 1 40 | 1 56 | 1 53 | 1 19 | 1 29 | 1 21 | 1 57 | 1 51 | 1 23 | 1 41 | 1 31 | 1 35 | 1 52 | 1 20 | 1 44 | 1 37 | 1 (49 rows)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。