PostgreSQL

Ràng buộc UNIQUE – Giá trị được lưu trữ trong cột có phải là giá trị duy nhất hay không

Ràng buộc UNIQUE - Giá trị được lưu trữ trong cột có phải là giá trị duy nhất hay không
Được viết bởi Minh Hoàng

Series chia sẻ về PostgreSQL – Cơ sở dữ liệu mã nguồn mở tiên tiến nhất thế giới.

Nếu thêm ràng buộc UNIQUE (DUY NHẤT) vào cột khi tạo bảng, thì bạn không thể lưu trữ các giá trị trùng lặp trong cột.

Bài viết này sẽ giải thích cách sử dụng ràng buộc UNIQUE trong PostgreSQL để đảm bảo rằng các giá trị được lưu trữ trong một cột hoặc một nhóm cột là duy nhất trên các hàng trong bảng.

Đôi khi, bạn muốn đảm bảo rằng các giá trị được lưu trữ trong một cột hoặc một nhóm cột là duy nhất trên toàn bộ bảng, chẳng hạn như địa chỉ email hoặc tên người dùng username.

PostgreSQL cung cấp cho bạn ràng buộc UNIQUE duy trì tính duy nhất của dữ liệu một cách chính xác.

Khi có ràng buộc UNIQUE, mỗi khi bạn chèn một hàng mới, nó sẽ kiểm tra xem giá trị đã có trong bảng hay chưa, nó sẽ từ chối thay đổi và đưa ra lỗi nếu giá trị đã tồn tại.

Khi bạn thêm ràng buộc UNIQUE vào một cột hoặc một nhóm cột, PostgreSQL sẽ tự động tạo một chỉ mục duy nhất trên cột hoặc nhóm cột.

1. Cách sử dụng ràng buộc UNIQUE

1. Cách sử dụng ràng buộc UNIQUE

Khi bạn tạo bảng, việc đặt ràng buộc UNIQUE trên cột sẽ ngăn bạn thêm các giá trị trùng lặp vào cột. Định dạng như sau:

CREATE TABLE [ IF NOT EXISTS ] table_name (
  column_name data_type UNIQUE [, ... ]
);

※Lưu ý rằng trong ràng buộc UNIQUE, ngay cả khi nhiều NULL được lưu trữ, chúng không được coi là giá trị trùng lặp.

Câu lệnh sau tạo một bảng mới có tên person với ràng buộc UNIQUE cho cột email:

CREATE TABLE person (
	id SERIAL PRIMARY KEY,
	name VARCHAR (50),
	email VARCHAR (50) UNIQUE
);

Ràng buộc UNIQUE - Giá trị được lưu trữ trong cột có phải là giá trị duy nhất hay không (1)

Ràng buộc UNIQUE ở trên cũng có thể được viết lại dưới dạng ràng buộc bảng như được hiển thị trong truy vấn sau:

CREATE TABLE person (
	id SERIAL PRIMARY KEY,
	name VARCHAR (50),
	email VARCHAR (50),
        UNIQUE(email)
);

Xem thông tin cột và ràng buộc đã tạo của bảng person:

\d person

Ràng buộc UNIQUE - Giá trị được lưu trữ trong cột có phải là giá trị duy nhất hay không (2)

Chỉ mục (index-インデックス) được tạo tự động khi bạn đặt một ràng buộc trên một bảng. Ở ví dụ này thì bảng person có 2 ràng buộc là PRIMARY KEYUNIQUE, nên có 2 index được tạo tự động tương ứng có tên lần lượt là person_pkeyperson_email_key

Bạn có thể lấy thông tin index theo cú pháp như sau:

\d index_name

Ràng buộc UNIQUE - Giá trị được lưu trữ trong cột có phải là giá trị duy nhất hay không (3)

Thông tin về chỉ mục đã tạo được hiển thị.

Bây giờ, thử thêm một số dữ liệu vào bảng person:

INSERT INTO person(name,email) VALUES
  ('Hoang Ngoc Minh', 'admin@minhhn.com'), 
  ('Minh Hoang Blog', 'minhhn.com@gmail.com');

Ràng buộc UNIQUE - Giá trị được lưu trữ trong cột có phải là giá trị duy nhất hay không (4)

Những dữ liệu này có thể được thêm vào mà không có vấn đề gì vì giá trị của cột email không trùng lặp.

Tiếp theo, thử thêm dữ liệu bằng cách chỉ định giá trị giống như giá trị đã được lưu trữ trong bảng làm giá trị của cột email:

INSERT INTO person(name,email) VALUES ('Minh Minh', 'minhhn.com@gmail.com');

Ràng buộc UNIQUE - Giá trị được lưu trữ trong cột có phải là giá trị duy nhất hay không (5)

việc thêm dữ liệu sẽ thất bại vì đã thêm email minhhn.com@gmail.com đã tồn tại, với thông báo lỗi:

ERROR:  duplicate key value violates unique constraint "person_email_key"
DETAIL:  Key (email)=(minhhn.com@gmail.com) already exists.

Lưu ý rằng NULL không gây ra lỗi ngay cả khi nó được lưu trữ trùng lặp trong cột mà ràng buộc UNIQUE được đặt.

Chúng ta sẽ thêm hai dữ liệu có giá trị NULL cho cột email như sau:

INSERT INTO person(name,email) VALUES
  ('Tokyo', NULL), 
  ('Nagoya', NULL);

Ràng buộc UNIQUE - Giá trị được lưu trữ trong cột có phải là giá trị duy nhất hay không (6)

Dữ liệu đã được thêm thành công mà không có bất kỳ lỗi nào.

2. Cách tạo ràng buộc UNIQUE trên nhiều cột

2. Cách tạo ràng buộc UNIQUE trên nhiều cột

PostgreSQL cho phép bạn tạo ràng buộc UNIQUE cho một nhóm cột bằng cú pháp sau:

CREATE TABLE [ IF NOT EXISTS ] table_name (
  column_name1 data_type1,
  column_name2 data_type2,
  column_name3 data_type3,
  [... ,]
  UNIQUE ( column_name2, column_name3 [, ... ] )
)

Sự kết hợp các giá trị trong cột column_name2column_name3 sẽ là duy nhất trên toàn bộ bảng. Tuy nhiên, từng giá trị riêng lẻ của cột column_name2 hoặc column_name3 không cần phải là duy nhất.

Ví dụ tạo bảng person1:

CREATE TABLE person1 (
	id SERIAL PRIMARY KEY,
	name VARCHAR (50),
	email VARCHAR (50),
	UNIQUE(name, email)
);

Ràng buộc UNIQUE - Giá trị được lưu trữ trong cột có phải là giá trị duy nhất hay không (7)

Xem thông tin chỉ mục person1_name_email_key:

\d person1_name_email_key

Ràng buộc UNIQUE - Giá trị được lưu trữ trong cột có phải là giá trị duy nhất hay không (8)

3. Thêm ràng buộc UNIQUE bằng cách sử dụng một unique index

3. Thêm ràng buộc UNIQUE bằng cách sử dụng một unique index

Đôi khi, bạn có thể muốn thêm một ràng buộc UNIQUE vào một cột hoặc nhóm cột hiện có của một bảng đã tồn tại.

Hãy xem ví dụ sau:

#1/3: Giả sử có một table equipment đã tồn tại có các cột như sau:

CREATE TABLE equipment (
	id SERIAL PRIMARY KEY,
	name VARCHAR (50) NOT NULL,
	equip_id VARCHAR (16) NOT NULL
);

#2/3: Tạo một unique index dựa trên cột equip_id:

CREATE UNIQUE INDEX CONCURRENTLY equipment_equip_id 
ON equipment (equip_id);

#3/3: Thêm ràng buộc UNIQUE đến bảng equipment sử dụng unique index đã tạo equipment_equip_id:

ALTER TABLE equipment 
ADD CONSTRAINT unique_equip_id 
UNIQUE USING INDEX equipment_equip_id;


Lưu ý rằng câu lệnh ALTER TABLE có được một khóa riêng trên bảng. Nếu bạn có bất kỳ giao dịch nào đang chờ xử lý, nó sẽ đợi tất cả các giao dịch hoàn tất trước khi thay đổi bảng.

Do đó, bạn nên kiểm tra bảng pg_stat_activity để xem các giao dịch đang chờ xử lý hiện đang diễn ra bằng cách sử dụng truy vấn sau:

SELECT
	datid,
	datname,
        usename,
	state
FROM
	pg_stat_activity;

Bạn nên nhìn vào kết quả để tìm cột state có giá trị không hoạt động trong giao dịch. Đó là những giao dịch đang chờ hoàn thành.

Cảm ơn bạn đã theo dõi. Đừng ngần ngại hãy cùng thảo luận với chúng tôi!

Giới thiệu

Minh Hoàng

Xin chào, tôi là Hoàng Ngọc Minh, hiện đang làm BrSE, tại công ty Toyota, Nhật Bản. Những gì tôi viết trên blog này là những trải nghiệm thực tế tôi đã đúc rút ra được trong cuộc sống, quá trình học tập và làm việc. Các bài viết được biên tập một cách chi tiết, linh hoạt để giúp bạn đọc có thể tiếp cận một cách dễ dàng nhất. Hi vọng nó sẽ có ích hoặc mang lại một góc nhìn khác cho bạn[...]

2 bình luận

Translate »