例子1:
有這樣一個需求,在很多電子商務網站上都要對用戶進行誠信評估,誠信分為五級(五個星),這樣就要求某欄位插入的數據0,1,2,3,4,5。“0”表示該用戶沒用評估。
-- ======================================================
-- 'trust'
-- ======================================================
Create table "trust"
(
"id" Serial NOT NULL UNIQUE,
"uid" integer NOT NULL Default 0,
"rate" Varchar(20) Default '0' Check (rate in ('0','1','2','3','4','5')),
primary key ("id")
);
Alter table "trust" add foreign key ("uid") references "user" ("id") on update restrict on delete restrict;
member=> Insert into trust (uid) values((select id from "user" where userid='netkiller'));
INSERT 111237 1
member=> Insert into trust (uid,rate) values((select id from "user" where userid='netkiller'),5);
INSERT 111220 1
member=> Insert into trust (uid,rate) values((select id from "user" where userid='netkiller'),2);
INSERT 111236 1
member=> Insert into trust (uid,rate) values((select id from "user" where userid='netkiller'),6);
ERROR: ExecInsert: rejected due to CHECK constraint "trust_rate" on "trust"
member=> Insert into trust (uid,rate) values((select id from "user" where userid='netkiller'),10);
ERROR: ExecInsert: rejected due to CHECK constraint "trust_rate" on "trust"
member=> select * from trust;
id | uid | rate
----+-----+------
1 | 257 | 2
4 | 257 | 0
5 | 257 | 5
(3 rows)
當插入數據不在枚舉的範圍內,提示ERROR: ExecInsert: rejected due to CHECK constraint "trust_rate" on "trust"。
例子2:
檢查某欄位,不允許出現數值,使用not in 來完成。
DROP TABLE ctoc.bid CASCADE;
CREATE TABLE ctoc.bid(
id Serial NOT NULL UNIQUE,
salesroom_id integer DEFAULT '1' NOT NULL, -- foreign key
bidder integer DEFAULT '1' NOT NULL, -- foreign key
price numeric(8,2) DEFAULT '0.00' NOT NULL,
quantity Integer DEFAULT '1' NOT NULL Check (quantity not in ('0')),
created timestamp DEFAULT current_timestamp::timestamp (0) without time zone,
status boolean DEFAULT true,
PRIMARY KEY (id),
FOREIGN KEY (salesroom_id) REFERENCES ctoc.salesroom (id) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (bidder) REFERENCES person (uid) ON UPDATE CASCADE ON DELETE CASCADE
);
netkiller=> insert into ctoc.bid(salesroom_id,bidder,price,quantity,status) values(1,8,100,0,true);
ERROR: ExecInsert: rejected due to CHECK constraint "bid_quantity" on "bid"
單欄位約束
這個例子對groupname欄位做唯一操作。
-- ======================================================
-- 'group'
-- ======================================================
Create table "group"
(
"id" Serial NOT NULL UNIQUE,
"groupname" Varchar(20) NOT NULL,
"description" Varchar(255),
UNIQUE (groupname),
PRIMARY KEY ("id")
);
測試:
member=> insert into "group"(groupname,description) values('Admin','xxxxxxxxxxxxxxxxxx');
INSERT 110497 1
member=> insert into "group"(groupname,description) values('Admin','xxxxxxxxxxxxxxxxxx');
ERROR: Cannot insert a duplicate key into unique index group_groupname_key
member=> insert into "group"(groupname,description) values('Admin','xxxxxxxxxxxxxxxxxx');
ERROR: Cannot insert a duplicate key into unique index group_groupname_key
Psql 命令行返回ERROR: Cannot insert a duplicate key into unique index group_groupname_key唯一約束成功。
多個欄位組合約束
UNIQUE (rid,uid)中有多個參數,是對rid,uid組合約束。
例如:
1,1
1,2
是正確的
1,1
2,1
也是正確的
2,1
1,1
2,2
1,2
1,1
不正確的不允許插入數據“1,1”,數據“1,1”出現了兩次,所以要同時滿足rid,uid兩個條件。
三個欄位以上組合:
1,1,1
1,1,2
1,2,1
2,1,2
2,1,1
2,2,2
正確可以插入數據
1,2,1
2,1,2
2,2,1
1,1,2
2,2,1
“2,2,1”,“2,2,1”出現兩次,違反約束條件,所以不能再次插入數據“2,2,1”。
-- ======================================================
-- 'rolemember'
-- ======================================================
-- drop table rolemember CASCADE ;
Create table "rolemember"
(
"id" Serial NOT NULL UNIQUE,
"rid" integer NOT NULL Default 0,
"uid" integer NOT NULL Default 0,
UNIQUE (rid,uid),
primary key ("id")
);
member=> insert into rolemember(rid,uid) values((select id from role where rolename ='System'),(select id from vuser where userid='sysop'));
INSERT 110954 1
member=> insert into rolemember(rid,uid) values((select id from role where rolename ='System'),(select id from vuser where userid='sysop'));
ERROR: Cannot insert a duplicate key into unique index rolemember_rid_key
member=> insert into rolemember(rid,uid) values((select id from role where rolename ='System'),(select id from vuser where userid='admin'));
ERROR: More than one tuple returned by a subselect used as an expression.
member=> insert into rolemember(rid,uid) values((select id from role where rolename ='System'),(select id from vuser where userid='test'));
INSERT 110956 1
member=> insert into rolemember(rid,uid) values((select id from role where rolename ='System'),(select id from vuser where userid='test'));
ERROR: Cannot insert a duplicate key into unique index rolemember_rid_key
唯一約束的注意事項
這個例子對groupname欄位做唯一操作。
-- ======================================================
-- 'group'
-- ======================================================
Create table "group"
(
"id" Serial NOT NULL UNIQUE,
"groupname" Varchar(20) NOT NULL,
"description" Varchar(255),
UNIQUE (id,groupname),
PRIMARY KEY ("id")
);
仔細看這個例子沒有錯。
運行結果:
postgres=# Create table "group"
postgres-# (
postgres(# "id" Serial NOT NULL UNIQUE,
postgres(# "groupname" Varchar(20) NOT NULL,
postgres(# "description" Varchar(255),
postgres(# UNIQUE (id,groupname),
postgres(# PRIMARY KEY ("id")
postgres(# );
NOTICE: CREATE TABLE will create implicit sequence 'group_id_seq' for SERIAL column 'group.id'
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'group_pkey' for table 'group'
NOTICE: CREATE TABLE / UNIQUE will create implicit index 'group_id_key' for table 'group'
CREATE TABLE
運行結果也沒有錯,現在插入數據。
insert into "group"(groupname,description) values('Admin','xxxxxxxxxxxxxxxxxx');
insert into "group"(groupname,description) values('Guest','xxxxxxxxxxxxxxxxxx');
insert into "group"(groupname,description) values('Domain','xxxxxxxxxxxxxxxxxx');
postgres=# insert into "group"(groupname,description) values('Admin','xxxxxxxxxxxxxxxxxx');
INSERT 110466 1
postgres=# insert into "group"(groupname,description) values('Guest','xxxxxxxxxxxxxxxxxx');
INSERT 110467 1
postgres=# insert into "group"(groupname,description) values('Domain','xxxxxxxxxxxxxxxxxx');
INSERT 110468 1
postgres=#
postgres=# insert into "group"(groupname,description) values('Admin','xxxxxxxxxxxxxxxxxx');
INSERT 110469 1
postgres=# insert into "group"(groupname,description) values('Guest','xxxxxxxxxxxxxxxxxx');
INSERT 110470 1
postgres=# insert into "group"(groupname,description) values('Domain','xxxxxxxxxxxxxxxxxx');
INSERT 110471 1
postgres=# insert into "group"(groupname,description) values('Admin','xxxxxxxxxxxxxxxxxx');
INSERT 110472 1
postgres=# insert into "group"(groupname,description) values('Guest','xxxxxxxxxxxxxxxxxx');
INSERT 110473 1
postgres=# insert into "group"(groupname,description) values('Domain','xxxxxxxxxxxxxxxxxx');
INSERT 110474 1
postgres=# insert into "group"(groupname,description) values('Admin','xxxxxxxxxxxxxxxxxx');
INSERT 110475 1
postgres=# insert into "group"(groupname,description) values('Guest','xxxxxxxxxxxxxxxxxx');
INSERT 110476 1
postgres=# insert into "group"(groupname,description) values('Domain','xxxxxxxxxxxxxxxxxx');
INSERT 110477 1
postgres=# insert into "group"(groupname,description) values('Admin','xxxxxxxxxxxxxxxxxx');
INSERT 110478 1
postgres=# insert into "group"(groupname,description) values('Guest','xxxxxxxxxxxxxxxxxx');
INSERT 110479 1
postgres=# insert into "group"(groupname,description) values('Domain','xxxxxxxxxxxxxxxxxx');
INSERT 110480 1
postgres=# select * from "group";
id | groupname | description
----+-----------+--------------------
1 | Admin | xxxxxxxxxxxxxxxxxx
2 | Guest | xxxxxxxxxxxxxxxxxx
3 | Domain | xxxxxxxxxxxxxxxxxx
4 | Admin | xxxxxxxxxxxxxxxxxx
5 | Guest | xxxxxxxxxxxxxxxxxx
6 | Domain | xxxxxxxxxxxxxxxxxx
7 | Admin | xxxxxxxxxxxxxxxxxx
8 | Guest | xxxxxxxxxxxxxxxxxx
9 | Domain | xxxxxxxxxxxxxxxxxx
10 | Admin | xxxxxxxxxxxxxxxxxx
11 | Guest | xxxxxxxxxxxxxxxxxx
12 | Domain | xxxxxxxxxxxxxxxxxx
13 | Admin | xxxxxxxxxxxxxxxxxx
14 | Guest | xxxxxxxxxxxxxxxxxx
15 | Domain | xxxxxxxxxxxxxxxxxx
(15 rows)
但你會發現對groupname欄位的唯一約束不起使用。失效原因:
"id" Serial NOT NULL UNIQUE, (唯一約束)
UNIQUE (id,groupname), (id欄位又做了一次唯一約束)
這就是它失效的原因。正確的腳本寫法是:
Create table "group"
(
"id" Serial NOT NULL UNIQUE,
"groupname" Varchar(20) NOT NULL,
"description" Varchar(255),
UNIQUE (groupname),
PRIMARY KEY ("id")
);
member=> insert into "group"(groupname,description) values('Admin','xxxxxxxxxxxxxxxxxx');
INSERT 110497 1
member=> insert into "group"(groupname,description) values('Admin','xxxxxxxxxxxxxxxxxx');
ERROR: Cannot insert a duplicate key into unique index group_groupname_key
member=> insert into "group"(groupname,description) values('Admin','xxxxxxxxxxxxxxxxxx');
ERROR: Cannot insert a duplicate key into unique index group_groupname_key
![]() | 提示 |
|---|---|
Psql 命令行返回ERROR: Cannot insert a duplicate key into unique index group_groupname_key 唯一約束成功。 |