postgresql----數據庫表約束----PRIMARY KEY


五.PRIMARY KEY ---- 主鍵約束

主鍵可以是單個字段,也可以是多個字段的組合。主鍵約束其實是UNIQUE和NOT NULL約束的組合,即主鍵必須是唯一,且各字段都是NOT NULL的。

 

1.創建測試表

create table tbl_primary(
a int not null,
b int,
c int,
constraint pk_tbl_primary_a_b primary key (a,b)
);

 

其中(a,b)是組合主鍵,即a和b的組合必須是唯一的,且a是not null,b也是not null的,雖然表定義中沒有明確b是not null的,但是因為b是主鍵的一部分,增加主鍵時會給b增加not null約束。

測試例

test=# insert into tbl_primary (a,b,c) values (1,1,1);
INSERT 0 1
test=# insert into tbl_primary (a,b,c) values (1,2,1);
INSERT 0 1
test=# insert into tbl_primary (a,b,c) values (1,1,1);
ERROR:  duplicate key value violates unique constraint "pk_tbl_primary_a_b"
DETAIL:  Key (a, b)=(1, 1) already exists.
test=# insert into tbl_primary (a,c) values (1,5);
ERROR:  null value in column "b" violates not-null constraint
DETAIL:  Failing row contains (1, null, 5).
 

 

2.刪除主鍵約束

test=# alter table tbl_primary drop constraint pk_tbl_primary_a_b ;
ALTER TABLE

 

3.增加主鍵約束

向已存在的表中增加主鍵約束就必須考慮已存在的數據不是唯一的,或者有可能是NULL,此時增加主鍵約束就會失敗,所以增加主鍵約束之前先刪除這些臟數據。

如果你看了前一節增加唯一約束前刪除臟數據,那么這一節簡直就是小kiss。

對主鍵來說臟數據包括2個部分:NULL和重復數據,刪除NULL數據比較簡單,使用下面的SQL語句即可

 

test=# delete from tbl_primary where a is null or b is null;

 

 

 

NULL數據刪除后,下面主要講如何刪除重復數據,和UNIQUE處理方式相同,有兩種處理方式:

一、將重復數據刪除到只剩一條

二、將重復數據全部刪除

 

方式一  將重復數據刪除到只剩一條

第一步:利用表的oids屬性,修改表的屬性

 

test=# alter table tbl_primary set with oids;
ALTER TABLE

 

 

 

第二步:刪除主鍵約束,清空表,寫入測試數據

test=# alter table tbl_primary drop constraint pk_tbl_primary_a_b ;
ALTER TABLE
test=# delete from tbl_primary where a is null or b is null;
DELETE 0
test=# insert into tbl_primary (a,b) values (1,1),(1,1),(1,1),(2,2),(2,2);
INSERT 0 5
test=# select oid,* from tbl_primary ;
  oid  | a | b |  c   
-------+---+---+------
 16423 | 1 | 1 |    1
 16424 | 1 | 2 |    1
 16425 | 1 | 1 | NULL
 16426 | 1 | 1 | NULL
 16427 | 1 | 1 | NULL
 16428 | 2 | 2 | NULL
 16429 | 2 | 2 | NULL
(7 rows)

第三步:查詢重復數據中最小oid

test=# select min(oid) from tbl_primary group by a,b;
  min  
-------
 16428
 16423
 16424
(3 rows)

第四步:查詢oid不是最小的重復數據

test=# select oid,* from tbl_primary where oid not in (select min(oid) from tbl_primary group by a,b);
  oid  | a | b |  c   
-------+---+---+------
 16425 | 1 | 1 | NULL
 16426 | 1 | 1 | NULL
 16427 | 1 | 1 | NULL
 16429 | 2 | 2 | NULL
(4 rows)

第五步:刪除oid不是最小的重復數據

將上面語句中的SELECT替換成DELETE即可

test=# delete from tbl_primary where oid not in (select min(oid) from tbl_primary group by a,b);
DELETE 4
test=# select oid,* from tbl_primary ;
  oid  | a | b |  c   
-------+---+---+------
 16423 | 1 | 1 |    1
 16424 | 1 | 2 |    1
 16428 | 2 | 2 | NULL
(3 rows)

第六步:增加主鍵

test=# alter table tbl_primary add constraint pk_tbl_primary_a_b primary key(a,b);
ALTER TABLE

 

方式二  將重復數據全部刪除

第一步:刪除主鍵約束,清空表,寫入測試數據

alter table tbl_primary drop constraint pk_tbl_primary_a_b ;
ALTER TABLE
test=# delete from tbl_primary;
DELETE 8
test=# insert into tbl_primary (a,b) values (1,1),(1,1),(1,1),(2,2),(2,2);
INSERT 0 5
test=# select * from tbl_primary ;
 a | b |  c   
---+---+------
 1 | 1 | NULL
 1 | 1 | NULL
 1 | 1 | NULL
 2 | 2 | NULL
 2 | 2 | NULL
(5 rows)

第二步:查詢重復的數據

test=# select a,b from tbl_primary group by a,b having count(*)>1;
 a | b 
---+---
 2 | 2
 1 | 1
(2 rows)

第三步:查詢所有的重復數據

test=# select * from tbl_primary where exists (select null from (select a,b from tbl_primary group by a,b having count(*)>1) tbl_temp where tbl_primary.a=tbl_temp.a and tbl_primary.b=tbl_temp.b);
 a | b |  c   
---+---+------
 1 | 1 | NULL
 1 | 1 | NULL
 1 | 1 | NULL
 2 | 2 | NULL
 2 | 2 | NULL
(5 rows)

第四步:刪除所有的重復數據

將上面SQL語句中select替換成delete即可。

test=# delete from tbl_primary where exists (select null from (select a,b from tbl_primary group by a,b having count(*)>1) tbl_temp where tbl_primary.a=tbl_temp.a and tbl_primary.b=tbl_temp.b);
DELETE 5

第五步:增加主鍵約束

test=# alter table tbl_primary add constraint pk_tbl_primary_a_b primary key(a,b);
ALTER TABLE

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM