目录
- postgresql中的ctid
- ctid表示
- 查看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)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持悠久资源。