รู้จักกับ Constraints

บทความโดย: 9Expert Team

รู้จักกับ Constraints

Constraints คืออะไร เรียนรู้ Integrity Constraints กฎข้อบังคับ Database เพื่อความถูกต้องสมบูรณ์ของข้อมูล

9Expert Team 3 นาที

ผู้เขียนได้รับมอบหมาย ให้เขียนบทความเกี่ยวกับ Constraints ซึ่งผู้เขียนขอเรียกว่า Integrity Constraints

โดยหากแปลกันเป็นคำ ๆ Constraint จะแปลว่า "ข้อบังคับ" หรือ "ข้อจำกัด" ขณะที่คำว่า Integrity จะแปลว่า "ความถูกต้องสมบูรณ์" หรือ "ความบูรภาพ" ถ้าเอาสองคำนี้มาผสมกันเป็น Integrity Constraints ก็จะได้ความหมายว่า กฎข้อบังคับต่างๆ ที่ทำให้เกิดความถูกต้องสมบูรณ์ (ของข้อมูล)

การบังคับ Integrity Constraints สำหรับฐานข้อมูลเชิงสัมพันธ์ (Relational Database) นั้นจุดเริ่มต้นมาจากเอกสารชื่อ Codd's Twelve Commandments (เป็นกฎ 13 ข้อ นับจาก 0 - 12) ของ Edgar F. Codd ซึ่งเป็นผู้ริเริ่ม Relational Model สำหรับฐานข้อมูล

เอกสารดังกล่าวได้พูดถึงการออกแบบระบบจัดการฐานข้อมูลเชิงสัมพันธ์ (RDBMS ย่อมาจาก Relational Database Management System) ต้องมีอะไรหรือทำอะไรได้บ้าง ในข้อที่ 5 ระบุว่าระบบจะต้องมีภาษาที่สามารถกำหนด Integrity Constraints ส่วนในข้อที่ 10 ระบุภาษานั้นจะต้องสร้าง Integrity Constraints ขึ้นและจัดเก็บเอาไว้ได้ใน Data Catalog ไม่ใช่อยู่ในฝั่ง Application

ปัจจุบันภาษาที่ใช้สร้าง Database Objects บน Relational Database คือภาษา SQL (Structured Query Language) ซึ่งมีมาตรฐานรับรองทั้ง ANSI และ ISO/IEC และอาจมีการพัฒนาเพิ่มเติมจากผู้ผลิต เช่น Microsoft SQL Server จะเรียกภาษา SQL ของตนเองว่า Transact-SQL หรือ Oracle ก็เรียกภาษา SQL ของตนเองว่า PL-SQL เป็นต้น

Data Integrity

Data Integrity หรือ ความถูกต้องสมบูรณ์ของข้อมูลจำแนกออกเป็น 3 ชนิดด้วยกัน

  1. Entity Integrity เพื่อให้แน่ใจว่าข้อมูลที่ใส่เข้าไปมีความสมบูรณ์ถูกต้อง โดยสามารถระบุถึงแถวข้อมูลภายใน Entity (หรือ Table) ว่าเป็นแถวข้อมูลใดได้

  2. Referential Integrity เพื่อให้แน่ใจว่าข้อมูลที่อ้างอิงกันระหว่างตารางมีความสมบูรณ์ถูกต้อง

  3. Domain Integrity เพื่อให้แน่ใจว่าค่าที่ใส่เข้าไปในคอลัมน์ต้องมีค่าอยู่ในช่วงที่ยอมรับได้

Entity Integrity

Referential Integrity

Domain Integrity

Unique Constraint

Nullability Constraint

Primary Key Constraint

Default Constraint

Foreign Key Constraint

Check Constraint

ตัวอย่าง CREATE TABLE พร้อม Constraints

CREATE TABLE HR.SimpleEmployees
(
      EmpID        int IDENTITY(1,1)   NOT NULL
,     FirstName    nvarchar(30)        NOT NULL
,     LastName     nvarchar(30)        NOT NULL
,     Title        nvarchar(30)        NOT NULL
,     BirthDate    datetime            NOT NULL
,     HireDate     datetime            NOT NULL
,     ModifiedDate datetime            NOT NULL
,     EndDate      datetime            NULL        
      CONSTRAINT PK_Employees PRIMARY KEY (EmpID)
,     CONSTRAINT AK_EmpName UNIQUE (FirstName, LastName)
);

Unique Constraint

ถือเป็นข้อบังคับให้เกิด Entity Integrity เพราะบังคับให้ค่าในแต่ละแถวข้อมูลของคอลัมน์ หรือ กลุ่มของคอลัมน์ที่บังคับด้วย Unique Constraint จะต้องมีค่าไม่ซ้ำกัน และ คอลัมน์ดังกล่าวสามารถระบุถึงแถวข้อมูลว่าเป็นแถวข้อมูลใดได้ แม้ว่าบางแถวข้อมูลที่มีค่าเป็น NULL อาจระบุไม่ได้ก็ตาม

CONSTRAINT AK_EmpName UNIQUE (FirstName, LastName)

จะเป็นการสร้าง Unique Constraint ชื่อ AK_EmpName เพื่อบังคับให้ค่าผสมจากคอลัมน์ FirstName และ LastName จะต้องไม่ซ้ำกับแถวข้อมูลใดเลยในตารางนี้

Nullability Constraint

คอลัมน์ใดไม่อนุญาตให้เว้นว่าง ให้ระบุ NOT NULL ท้ายการประกาศชื่อคอลัมน์ คอลัมน์ใดอนุญาตให้เว้นว่างได้ ให้ระบุ NULL ท้ายการประกาศชื่อคอลัมน์

Primary Key Constraint

ถือเป็นข้อบังคับให้เกิด Entity Integrity มีคุณสมบัติทุกอย่างของ Unique Constraint แต่เพิ่มเงื่อนไขว่าคอลัมน์ หรือกลุ่มของคอลัมน์ จะต้องทำหน้าที่เป็น Unique Identifier ให้กับตาราง และเนื่องจากต้องเป็นตัวระบุแถวข้อมูลซึ่งเป็นค่าว่างหรือ NULL ไม่ได้

CONSTRAINT PK_Employees PRIMARY KEY (empid)
  • Unique Constraint ห้ามซ้ำกัน แต่เป็นค่าว่างได้

  • Primary Key Constraint ห้ามซ้ำกัน และเป็นค่าว่างไม่ได้

Default Constraint

CREATE TABLE Sales.Orders
(
      OrderID      int IDENTITY(1,1)   NOT NULL
,     CustID       int                 NOT NULL
,     Empid        int                 NOT NULL
,     OrderDate    datetime            NOT NULL
      CONSTRAINT DF_OrderDate DEFAULT GETDATE()
,     RequiredDate datetime            NOT NULL
,     ShippedDate  datetime            NULL
,     ModifiedDate datetime            NOT NULL
      CONSTRAINT DF_ModifiedDate DEFAULT GETDATE()
,     EndDate      datetime            NULL
      CONSTRAINT PK_Orders PRIMARY KEY(OrderID)
)

คอลัมน์ OrderDate และ ModifiedDate มีการกำหนด Default Constraint ให้ใช้วันเวลาปัจจุบันหากไม่ใส่ข้อมูลลงในคอลัมน์

INSERT INTO Sales.Orders (CustID,Empid,OrderDate,RequiredDate,ModifiedDate)
VALUES (1,1,DEFAULT,'Aug 5, 2016',DEFAULT)

Foreign Key Constraint

ถือเป็นข้อบังคับให้เกิดทั้ง Referential Integrity และ Domain Integrity คือ เป็นข้อบังคับสำหรับคอลัมน์ที่เป็น Foreign Key ให้ใส่ค่าในคอลัมน์ได้เฉพาะค่าจากคอลัมน์ที่เป็น Primary Key ในตารางที่มีความสัมพันธ์กันเท่านั้น

INSERT INTO Sales.Orders (CustID,Empid,OrderDate,RequiredDate,ModifiedDate)
VALUES (1,4,DEFAULT,'Aug 5, 2016',DEFAULT);

ผลลัพธ์: Msg 547, Level 16, State 0, Line 1 - The INSERT conflicted with the FOREIGN KEY constraint "FK_Orders_Employees". The conflict occurred in database "TestDB", table "HR.SimpleEmployees", column 'EmpID'. The statement has been terminated.

Check Constraint

ถือเป็นข้อบังคับให้เกิด Domain Integrity หรือให้เกิดทั้ง Domain Integrity พร้อมกับ Referential Integrity เหมือน Foreign Key Constraint ก็ได้ ขึ้นอยู่กับการเขียน Expression

Check Constraint ทำหน้าที่เป็น Boolean Expression โดยพิจารณาค่าที่ใส่เข้ามา หากตรวจสอบแล้วเป็น False หรือหาค่าไม่ได้ ก็จะปฏิเสธค่านั้น แต่หากเป็น True ก็จะยอมรับค่านั้น

INSERT INTO HR.SimpleEmployees (FirstName,LastName,Title,Salary,BirthDate,HireDate,ModifiedDate)
VALUES ('Phakkhaphong','Krittawat','Mr.',150000,'Aug 5,1974',GETDATE(),GETDATE())

ผลลัพธ์: Msg 547 - The INSERT conflicted with the CHECK constraint "CK_Salary". แสดงให้เห็นว่าการใส่ค่า 150000 ให้แก่คอลัมน์ Salary ทำให้ Boolean Expression ใน Check Constraint ได้ค่าเป็น False ทำให้ปฏิเสธค่าดังกล่าว

Check Constraint กับ Referential Integrity

กรณีนี้ใช้ Function ร่วมด้วย โดยสร้าง Function ที่รับพารามิเตอร์ @EmpID แล้วนำไปสืบค้นในตาราง SimpleEmployees ว่ามีแถวข้อมูลใดในคอลัมน์ EmpID มีค่าตรงกับ @EmpID ถ้ามีแม้เพียงแถวข้อมูลเดียวก็ให้คืนค่าเป็น 1 แต่หากไม่พบก็ให้คืนค่าเป็น 0 จากนั้นนำ Function นี้ไปใช้ใน Check Constraint เพื่อบังคับ Referential Integrity ระหว่างตาราง

บทความที่เกี่ยวข้อง