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
时间: 2024-10-01 07:14:53

postgresql----数据库表约束----PRIMARY KEY的相关文章

PostgreSQL数据库中跨库访问解决方案

PostgreSQL跨库访问有3种方法:Schema,dblink,postgres_fdw. 方法A:在PG上建立不同SCHEMA,将数据和存储过程分别放到不同的schema上,经过权限管理后进行访问. 方法A的示例如下: 测试1(测试postgres超级用户对不同schema下对象的访问) 查看当前数据库中的schema postgres=# \dn List of schemas Name | Owner -------------------+--------- dbms_job_pro

PostgreSQL介绍以及如何开发框架中使用PostgreSQL数据库

最近准备下PostgreSQL数据库开发的相关知识,本文把总结的PPT内容通过博客记录分享,本随笔的主要内容是介绍PostgreSQL数据库的基础信息,以及如何在我们的开发框架中使用PostgreSQL数据库,希望大家多多提意见. 1.PostgreSQL数据库介绍 PostgreSQL是以加州大学伯克利分校计算机系开发的 POSTGRES,现在已经更名为PostgreSQL.它具有很多不错的特点: 开源:PostgreSQL 是一个自由的对象-关系数据库服务器(数据库管理系统),它在灵活的 B

AVAYA AEP运维之PostgreSQL数据库相关

由于AEP EPM所有相关的报表数据(应用运行日志,呼叫清单,会话清单),配置信息等都存在本地PostgreSQL上,了解PostgreSQL的相关基本使用方法,有助于日常运维能力的提升.本篇主要总结如何开启本地登陆,开启远端登陆,基本命令,数据备份和清理. 如何开启本地和远端登陆 在EPM安装的过程中,会把PostgreSQL也一并安装掉,过程中会提示输入用户名postgres的密码,以及创建一个报表用户.当时当你本地使用PostgreSQL去登陆数据库时,始终登陆不上:通过PostgreSQ

PostgreSQL数据库Streaming Replication流复制主备延迟测试

PostgreSQL数据库流复制主库和备库之间的延迟时间是多少,无论对HA还是负载均衡来说都应该做个评估.比如单纯的HA架构,当主库发生故障时,我们允许多少时间内的数据丢失.不废话,直接进入本次实验测试. 测试环境: 主库:内存:32G,CPU:8核,IP:192.168.122.101 备库:内存:32G,CPU:8核,IP:192.168.122.102 数据库配置:默认 测试准备: 在两台服务器上安装好PostgreSQL数据库,安装过程不清楚的可以参考文章<PostgreSQL数据库编译

Go 连接PostgreSQL数据库

先在PostgreSQL数据库中建一个表,可以使用PostgreSQL官方的pgAdmin来完成: CREATE TABLE userinfo ( uid serial NOT NULL, username character varying(100) NOT NULL, departname character varying(500) NOT NULL, Created date, CONSTRAINT userinfo_pkey PRIMARY KEY (uid) ) WITH (OIDS

MYSQL数据库迁移到POSTGRESQL数据库(人工迁移)

产品即将上线,可项目经理说要换数据库,要把mysql数据库的内容全部搬到Postgresql中去. 有一个python的工具可以实现迁移(但是存储过程无法迁移.数据类型也无法灵活对应,还要改程序),为了节约时间采用人工迁移的方式,闲话少说,以下是迁移过程,没图,对不起. 利用Navicat for Mysql工具(其它工具也可以,比如mysqldump)将数据库模式导出(只导表结构不含数据)方法略,生成的文件名为mysql.sql 利用linux sed工具把导出的脚本中的所有COMMENT及m

访问GitLab的PostgreSQL数据库

1.登陆gitlab的安装服务查看配置文件 cat /var/opt/gitlab/gitlab-rails/etc/database.yml production: adapter: postgresql encoding: unicode collation: database: gitlabhq_production //数据库名 pool: 10 username: 'gitlab' //用户名 password: host: '/var/opt/gitlab/postgresql' /

Python 操作 PostgreSQL 数据库

我使用的是 Python 3.7.0 PostgreSQL可以使用psycopg2模块与Python集成. sycopg2是用于Python编程语言的PostgreSQL数据库适配器. psycopg2是非常小,快速,稳定的. 您不需要单独安装此模块,因为默认情况下它会随着Python 2.5.x版本一起发布. pip3 install python-psycopg2pip3 install psycopg2-binary 连接到数据库 以下Python代码显示了如何连接到现有的数据库. 如果数

SQL PRIMARY KEY 约束\SQL FOREIGN KEY 约束\SQL CHECK 约束

SQL PRIMARY KEY 约束 PRIMARY KEY 约束唯一标识数据库表中的每条记录. 主键必须包含唯一的值. 主键列不能包含 NULL 值. 每个表都应该有一个主键,并且每个表只能有一个主键. SQL PRIMARY KEY Constraint on CREATE TABLE 下面的 SQL 在 "Persons" 表创建时在 "Id_P" 列创建 PRIMARY KEY 约束: MySQL: CREATE TABLE Persons ( Id_P i