Unique Constraints (Ràng buộc Unique) trong sql server

Một unique constraint được sử dụng để đảm bảo những giá trị ở trong một cột (hoặc một bộ nhiều cột) trong một bảng là duy nhất

Cách tạo unique constraint

Chúng ta có thể tạo unique constraint cùng với lúc tạo mới một bảng hoặc chúng ta cũng có thể thêm unique constraint vào bảng đã tồn tại, dưới đây mình sẽ thực hiện tạo unique constraint trong khi tạo mới một bảng 

/*Tất cả ví dụ của bài viết sẽ được thực hiện trên AZSqlserver database nên trước khi đi vào phần demo bên dưới chúng ta sẽ tạo database này */
 
USE master
GO
 
/*Xóa AZSqlserver database nếu database này đã tồn tại trước đó*/
IF DB_ID('AZSqlserver') IS NOT NULL
BEGIN
    ALTER DATABASE AZSqlserver SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    DROP DATABASE AZSqlserver ;
END
 
/*Tạo AZSqlserver database*/
CREATE DATABASE AZSqlserver
GO
  
/*Chúng ta bắt đầu tạo Default Constraints trên cột CreatedDate của bảng Customer*/
USE AZSqlserver

CREATE TABLE dbo.Customer
(
     CustomerId 	   INT UNIQUE
	,CustomerName VARCHAR(50)
)
GO

Trong phần mềm SQL Server Management Studio bạn ấn vào View → Object Explorer → Databases → AZSqlserver → Tables → dbo.Customer → Keys để xem thông tin default constraint vừa mới được tạo ra

Hình 1 

Một điểm đặc biệt là unique constraint được hiển thị trong thư mục Keys, làm cho một số bạn nhầm lẫn giữa unique constraint với primary key, vấn đề nhầm lẫn này mình sẽ trình bày ở phần sau của bài viết, giờ chúng ta cùng phân tích chi tiết tên của unique constraint được sql server tạo tự động

tên của unique constraint trên là UQ__Customer__A4AE64D98270ABAB, trong đó UQ là viết tắt của unique constraint, Customer là tên bảng chứa unique constraint này, A4AE64D98270ABAB là chuỗi ký tự mà sql server tạo tự động để phân biệt tên giữa các unique constraint

để xem thông tin chi tiết của constraint này ta chọn chuột phải → Scripts constraint as → CREATE To → New Query Editor Window 

Hình 2

Kết quả : 

Hình 3

Kết quả cho ta biết một unique constraint được đặt trên cột CustomerId của bảng dbo.Customer, một điều đặc biệt xuất hiện ở đây là chữ NONCLUSTERED trong câu lệnh ADD UNIQUE NONCLUSTERED, khi ta thêm unique constraint thì một nonclustered index được thêm vào cùng với lúc constraint này được tạo, mục đích của nó là phục vụ quá trình kiểm tra giá trị trùng lặp của constraint

để xem chi tiết nonclustered index này,  ta nhấn vào  View → Object Explorer → Databases → AZSqlserver → Tables → dbo.Customer → Indexes

Hình 4

Nhấn chuột phải vào nonclustered index, sau đó chọn properties để thấy thông tin của index

Hình 5 – Xem thông tin chi tiết của nonclustered index được tạo ra cùng với unique constraint

Kết quả : 

Hình 6 – Thông tin chi tiết của nonclustered index được tạo ra

từ kết quả ta thấy một nonclustered index đã được tạo ra, có tên hiển thị ở phần index name giống như tên của unique constraint hiển thị ở hình 1 là UQ__Customer__A4AE64D98270ABAB, phần index type và checkbox unique được chọn cho ta biết đây là unique nonclustered index, phần index key columns hiển thị cột CustomerId, cho ta biết unique nonclustered index UQ__Customer__A4AE64D98270ABAB có  CustomerId là một key columns của nó

Đặt tên cho một unique constraint

Với các đặt tên tự động của sql server như trên, rất khó để chúng ta có thể sử dụng trong các trường hợp như chỉnh sửa nếu cần, để giải quyết vấn đề này ta có thể dùng câu lệnh sau đây để đặt tên unique constraint như ta mong muốn : 

USE AZSqlserver
GO

/*Xóa bảng Customer*/
DROP TABLE IF EXISTS dbo.Customer
GO

/*tạo unique constraint với một tên đặt trước*/
CREATE TABLE dbo.Customer
(
	CustomerId 	  INT 
	,CustomerName VARCHAR(50)
	,CONSTRAINT unq_CustomerId UNIQUE(CustomerId)
)
GO

Kết quả : 

Hình 7 – Unique constraint có tên unq_CustomerId  được tạo ra

Thêm unique constraint vào một bảng đã tồn tại trước đó

bảng dbo.Customer ở ví dụ trên hiện tại đang có constraint unq_CustomerId, giờ ta muốn thêm một unique constraint nữa trên cột CustomerName tên là unq_CustomerName ta dùng câu lệnh sau đây : 

ALTER TABLE dbo.Customer 
ADD CONSTRAINT unq_CustomerName UNIQUE(CustomerName)

Kết quả : 

Hình 8 – Thêm unique constraint unq_CustomerName  vào bảng dbo.Customer

trong trường hợp muốn tạo unique constraint trên một bộ gồm nhiều cột ta thực hiện như câu lệnh sau đây:

ALTER TABLE dbo.Customer 
ADD CONSTRAINT unq_CustomerName_CustomerId UNIQUE(CustomerName, CustomerId)

Kết quả : 

Hình 9 – Tạo unique constraint trên nhiều cột

Khi một unique constraint được tạo ra một unique index cũng được tạo ra , mở rộng thư mục indexes ta sẽ thấy điều này

Hình 10 – ba nonclustered indexes được tạo ra khi tạo ba unique constraints

Ở đây có 3 unique index được tạo ra cùng với 3 unique constraint tương ứng

Cả unique constraint và unique index đều có thể dùng cho mục đích đảm bảo dữ liệu của một cột hoặc một bộ gồm nhiều cột không được trùng lặp trong một bảng, tuy nhiên unique constraint và unique index không giống nhau, mình sẽ trình bày sự khác biệt này trong bài viết Sự khác biệt giữa unique index và unique constraint trong sql server

Ví dụ cho cách hoạt động của unique constraint

giờ chúng ta cùng kiểm tra cách thức hoạt động của unique constraint, trước khi làm điều này ta hãy tạo lại bảng dbo.Customer với unique constraint được đặt trên cột CustomerId 

USE AZSqlserver
GO

/*Xóa bảng Customer*/
DROP TABLE IF EXISTS dbo.Customer
GO

/*tạo unique constraint với một tên đặt trước*/
CREATE TABLE dbo.Customer
(
	CustomerId 	  INT 
	,CustomerName VARCHAR(50)
	,CONSTRAINT unq_CustomerId UNIQUE(CustomerId)
)
GO

Tiếp theo ta insert một dòng vào bảng dbo.Customer

INSERT INTO dbo.Customer
VALUES (1, 'Customer 1')
GO

Hình 11

Câu lệnh đã insert thành công 

Tiếp theo ta sẽ insert thêm 1 dòng nữa, có CustomerId = 1, giống với giá trị ở dòng đầu đã insert

INSERT INTO dbo.Customer
VALUES (1, 'Customer 2')
GO

Hình 12 – Lỗi khi insert giá trị trùng lặp vào cột thuộc unique constraint

lúc này một lỗi đã xuất hiện : 

Lỗi nào báo cho ta biết đã vi phạm unique constraint có tên là unq_CustomerId, lý do chi tiết cho sự vi phạm này là ta đã insert một dòng vào bảng dbo.Customer và dòng này gây trùng lặp, cụ thể giá trị gây trùng lặp là 1 (The duplicate key value is (1)) trên cột customerId

Sự khác nhau giữa unique constraint và primary key constraint

unique constraint và primary key constraint đều thực hiện việc tránh trùng lặp dữ liệu trên một số cột mà ta định nghĩa khi tạo unique constraint hoặc primary key constraint, vậy câu hỏi đặt ra là khi nào ta nên lựa chọn dùng unique constraint hay primary key constraint ?

để có thể lựa chọn đúng, ta cần đi vào 2 điểm khác biệt giữa unique constraint và primary key constraint:

Khác biệt #1 : một unique constraint có thể chứa một giá trị NULL

Một primary key constraint không thể chứa bất kỳ giá trị NULL nào, Nếu bạn insert một giá trị NULL vào một trong những cột thuộc primary key thì bạn sẽ nhận về một lỗi, trong khi đó đối với unique constraint vẫn cho phép bạn làm điều đó 

Ví dụ : Ta thực hiện insert giá trị NULL vào một cột có unique constraint đặt trên nó xem điều gì sẽ xảy ra

/*Insert giá trị NULL vào cột trong unique constraint*/

USE AZSqlserver
GO

/*Xóa bảng Customer*/
DROP TABLE IF EXISTS dbo.Customer
GO

/*tạo unique constraint với một tên đặt trước*/
CREATE TABLE dbo.Customer
(
	CustomerId 	  INT 
	,CustomerName VARCHAR(50)
	,CONSTRAINT unq_CustomerId UNIQUE(CustomerId)
)
GO

/* insert giá trị NULL vào cột CustomerId thuộc unique constraint unq_CustomerId */

INSERT INTO dbo.Customer (CustomerId, CustomerName)
VALUES (NULL, 'Customer 1')

Kết quả : 

Hình 13 – insert thành công giá trị NULL vào cột customerId

Giờ ta cùng thử insert giá trị NULL vào primary key constraint 

USE AZSqlserver
GO

/*Xóa bảng Customer*/
DROP TABLE IF EXISTS dbo.Customer
GO

/*tạo bảng với primary key được đặt trên cột CustomerId*/
CREATE TABLE dbo.Customer
(
	CustomerId 	  INT  PRIMARY KEY
	,CustomerName     VARCHAR(50)
	
)
GO

/* Chạy câu lệnh Insert giá trị NULL vào cột CustomerId*/

INSERT INTO dbo.Customer (CustomerId, CustomerName)
VALUES (NULL, 'Customer 1')

Kết quả :

Hình 14 – Lỗi khi insert giá trị NULL và một cột CustomerId thuộc primary key 

lỗi xuất hiện với nội dung : 

lỗi này cho ta biết không thể insert giá trị NULL vào cột Customerid vì cột này không cho phép giá trị NULL

Khác biệt #2 : Bạn có thể tạo nhiều unique constraint trên một bảng

Bạn chỉ có thể tạo một primary key constraint trên một bảng, nhưng bạn có thể tạo nhiều unique constraint trên bảng đó

Gỡ bỏ một unique constraint : 

Bạn chạy câu lệnh sau đây để gỡ bỏ unique constraint unq_CustomerId  khỏi bảng dbo.Customer

ALTER TABLE dbo.Customer 
DROP CONSTRAINT unq_CustomerId 

Related Post

Leave a Reply

Your email address will not be published. Required fields are marked *