Thứ hai, 14/09/2020 | 00:00 GMT+7

Hiểu các ràng buộc SQL

Khi thiết kế database , có thể có lúc bạn muốn đặt giới hạn về dữ liệu được phép trong các cột nhất định. Ví dụ: nếu bạn đang tạo một bảng chứa thông tin về các tòa nhà chọc trời, bạn có thể cần cột giữ chiều cao của mỗi tòa nhà cấm các giá trị âm.

Hệ thống quản lý database quan hệ (RDBMS) cho phép bạn kiểm soát dữ liệu nào được thêm vào bảng với các ràng buộc . Ràng buộc là một luật đặc biệt áp dụng cho một hoặc nhiều cột - hoặc cho toàn bộ bảng - hạn chế những thay đổi nào có thể được thực hiện đối với dữ liệu của bảng, cho dù thông qua INSERT , UPDATE hoặc DELETE .

Bài viết này sẽ xem xét chi tiết các ràng buộc là gì và cách chúng được sử dụng trong RDBMS. Nó cũng sẽ đi qua từng ràng buộc trong số năm ràng buộc được định nghĩa trong tiêu chuẩn SQL và giải thích các chức năng tương ứng của chúng.

Ràng buộc là gì?

Trong SQL, một ràng buộc là bất kỳ luật nào được áp dụng cho một cột hoặc bảng giới hạn dữ liệu nào có thể được nhập vào nó. Khi nào bạn cố gắng thực hiện một thao tác thay đổi dữ liệu được giữ trong bảng - chẳng hạn như INSERT , UPDATE hoặc DELETE - RDBMS sẽ kiểm tra xem dữ liệu đó có vi phạm bất kỳ ràng buộc hiện có nào không và nếu có, trả về lỗi.

Người quản trị database thường dựa vào các ràng buộc đảm bảo rằng database tuân theo một tập hợp các quy tắc nghiệp vụ xác định . Trong ngữ cảnh của database , luật kinh doanh là bất kỳ policy hoặc thủ tục nào mà một doanh nghiệp hoặc tổ chức khác tuân theo và dữ liệu của nó cũng phải tuân theo. Ví dụ: giả sử bạn đang xây dựng database sẽ lập danh mục hàng tồn kho của khách hàng. Nếu khách hàng chỉ định rằng mỗi bản ghi sản phẩm phải có một số nhận dạng duy nhất, bạn có thể tạo một cột có ràng buộc UNIQUE sẽ đảm bảo không có hai mục nhập nào trong cột đó giống nhau.

Các ràng buộc cũng hữu ích với việc duy trì tính toàn vẹn của dữ liệu . Tính toàn vẹn của dữ liệu là một thuật ngữ rộng thường được sử dụng để mô tả độ chính xác, tính nhất quán và tính hợp lý tổng thể của dữ liệu được lưu trữ trong database , dựa trên trường hợp sử dụng cụ thể của nó. Các bảng trong database thường có liên quan chặt chẽ với nhau, với các cột trong một bảng phụ thuộc vào các giá trị trong bảng khác. Bởi vì việc nhập dữ liệu thường dễ mắc phải các ràng buộc do lỗi của con người rất hữu ích trong những trường hợp như thế này, vì chúng có thể giúp đảm bảo không có dữ liệu nhập sai nào có thể ảnh hưởng đến các mối quan hệ như vậy và do đó gây hại cho tính toàn vẹn dữ liệu của database .

Hãy tưởng tượng bạn đang thiết kế một database với hai bảng: một bảng để liệt kê các học sinh hiện tại của một trường học và một bảng để liệt kê các thành viên của đội bóng rổ của trường đó. Bạn có thể áp dụng ràng buộc FOREIGN KEY cho một cột trong bảng đội bóng rổ tham chiếu đến một cột trong bảng trường. Điều này sẽ cài đặt mối quan hệ giữa hai bảng bằng cách yêu cầu bất kỳ mục nhập nào vào bảng group tham chiếu đến mục nhập hiện có trong bảng sinh viên.

User xác định các ràng buộc khi họ lần đầu tiên tạo một bảng hoặc họ có thể thêm chúng sau này bằng ALTER TABLE miễn là nó không xung đột với bất kỳ dữ liệu nào đã có trong bảng.Khi bạn tạo một ràng buộc, hệ thống database sẽ tự động tạo tên cho nó, nhưng trong hầu hết các triển khai SQL, bạn có thể thêm tên tùy chỉnh cho bất kỳ ràng buộc nào. Các tên này được dùng để chỉ các ràng buộc trong ALTER TABLE khi thay đổi hoặc loại bỏ chúng.

Tiêu chuẩn SQL chính thức xác định chỉ năm ràng buộc:

  • PRIMARY KEY
  • FOREIGN KEY
  • UNIQUE
  • CHECK
  • NOT NULL

Lưu ý : Nhiều RDBMS bao gồm từ khóa DEFAULT , được sử dụng để xác định giá trị mặc định cho một cột khác với NULL nếu không có giá trị nào được chỉ định khi chèn hàng. Tài liệu của một số hệ quản trị database này đề cập đến DEFAULT là một ràng buộc, vì việc triển khai SQL của chúng sử dụng cú pháp DEFAULT tương tự như cú pháp của các ràng buộc như UNIQUE hoặc CHECK . Tuy nhiên, về mặt kỹ thuật, DEFAULT không phải là một ràng buộc vì nó không hạn chế dữ liệu nào có thể được nhập vào một cột.

Đến đây bạn đã có hiểu biết chung về cách sử dụng các ràng buộc, ta hãy xem xét kỹ hơn từng trong số năm ràng buộc này.

PRIMARY KEY

Ràng buộc PRIMARY KEY yêu cầu mọi mục nhập trong cột đã cho vừa là duy nhất vừa không phải NULL và cho phép bạn sử dụng cột đó để xác định từng hàng riêng lẻ trong bảng

Trong mô hình quan hệ, khóa là một cột hoặc tập hợp các cột trong bảng trong đó mọi giá trị được đảm bảo là duy nhất và không chứa bất kỳ giá trị NULL nào. Khóa chính là một khóa đặc biệt có giá trị được sử dụng để xác định các hàng riêng lẻ trong bảng và cột hoặc các cột bao gồm khóa chính được dùng để xác định bảng trong toàn bộ phần còn lại của database .

Đây là một khía cạnh quan trọng của database quan hệ: với khóa chính, user không cần biết nơi dữ liệu của họ được lưu trữ vật lý trên máy và DBMS của họ có thể theo dõi từng bản ghi và trả lại chúng trên cơ sở đặc biệt. Ngược lại, điều này nghĩa là các bản ghi không có thứ tự logic xác định và user có khả năng trả lại dữ liệu của họ theo bất kỳ thứ tự nào hoặc thông qua bất kỳ bộ lọc nào họ muốn.

Bạn có thể tạo một khóa chính trong SQL với ràng buộc PRIMARY KEY , về cơ bản là sự kết hợp của các ràng buộc UNIQUENOT NULL . Sau khi xác định khóa chính, DBMS sẽ tự động tạo một chỉ mục được liên kết với nó. Chỉ mục là một cấu trúc database giúp truy xuất dữ liệu từ một bảng nhanh hơn. Tương tự như một index trong sách giáo khoa, các truy vấn chỉ phải xem xét các mục nhập từ cột được lập index để tìm các giá trị liên quan. Đây là những gì cho phép khóa chính hoạt động như một định danh cho mỗi hàng trong bảng.

Một bảng chỉ có thể có một khóa chính nhưng giống như các khóa thông thường, khóa chính có thể bao gồm nhiều hơn một cột. Như đã nói, một đặc điểm xác định của khóa chính là chúng chỉ sử dụng tập hợp tối thiểu các thuộc tính cần thiết để xác định duy nhất từng hàng trong bảng. Để minh họa ý tưởng này, hãy tưởng tượng một bảng lưu trữ thông tin về học sinh tại một trường học sử dụng ba cột sau:

  • studentID : được sử dụng để giữ số nhận dạng duy nhất của mỗi học sinh
  • firstName : dùng để giữ tên của mỗi học sinh
  • lastName : dùng để giữ họ của mỗi học sinh

Có thể một số học sinh ở trường có thể dùng chung tên, làm cho cột firstName trở thành một khóa chính không được lựa chọn.Điều này cũng đúng với cột lastName . Một khóa chính bao gồm cả firstNamelastName cột có thể làm việc, nhưng vẫn có một khả năng rằng hai sinh viên có thể chia sẻ một tên đầu tiên và cuối cùng.

Một khóa chính bao gồm các studentID và một trong hai firstName hoặc lastName cột có thể làm việc, nhưng kể từ khi mã số của mỗi học sinh đã được biết tới là duy nhất, bao gồm một trong các cột tên trong khóa chính sẽ là không cần thiết. Vì vậy, trong trường hợp này, tập hợp các thuộc tính tối thiểu có thể xác định từng hàng và do đó sẽ là lựa chọn tốt cho khóa chính của bảng, chỉ là cột studentID của riêng nó.

Nếu một khóa được tạo thành từ dữ liệu ứng dụng có thể quan sát được (tức là dữ liệu đại diện cho các thực thể, sự kiện hoặc thuộc tính trong thế giới thực) thì nó được gọi là khóa tự nhiên . Nếu khóa được tạo bên trong và không đại diện cho bất kỳ thứ gì bên ngoài database , nó được gọi là khóa thay thế hoặc khóa tổng hợp . Một số hệ thống database khuyến nghị không nên sử dụng các khóa tự nhiên, vì ngay cả các điểm dữ liệu dường như không đổi cũng có thể thay đổi theo những cách không thể đoán trước.

FOREIGN KEY

Ràng buộc FOREIGN KEY yêu cầu mọi mục nhập trong cột đã cho phải đã tồn tại trong một cột cụ thể từ bảng khác.

Nếu bạn có hai bảng mà bạn muốn liên kết với nhau, một cách bạn có thể thực hiện là xác định foreign keys với ràng buộc FOREIGN KEY . Khóa ngoại là một cột trong một bảng (bảng “con”) có giá trị đến từ một khóa trong bảng khác (“cha”). Đây là một cách để thể hiện mối quan hệ giữa hai bảng: ràng buộc FOREIGN KEY yêu cầu các giá trị trong cột mà nó áp dụng phải đã tồn tại trong cột mà nó tham chiếu.

Sơ đồ sau đây nêu bật mối quan hệ như vậy giữa hai bảng: một bảng dùng để ghi thông tin về nhân viên tại một công ty và bảng khác dùng để theo dõi doanh số của công ty. Trong ví dụ này, khóa chính của bảng EMPLOYEES được tham chiếu bởi foreign keys của bảng SALES :

Sơ đồ ví dụ về cách khóa chính của bảng EMPLOYEE hoạt động như foreign keys  của bảng SALES

Nếu bạn cố gắng thêm bản ghi vào bảng con và giá trị được nhập vào cột foreign keys không tồn tại trong khóa chính của bảng mẹ, thì câu lệnh chèn sẽ không hợp lệ. Điều này giúp duy trì tính toàn vẹn ở cấp độ mối quan hệ, vì các hàng trong cả hai bảng sẽ luôn có liên quan chính xác với nhau.

Thông thường, foreign keys của bảng là khóa chính của bảng mẹ, nhưng điều này không phải lúc nào cũng đúng. Trong hầu hết các RDBMS, bất kỳ cột nào trong bảng mẹ có ràng buộc PRIMARY KEY hoặc UNIQUE được áp dụng cho nó đều có thể được tham chiếu bởi foreign keys của bảng con.

UNIQUE

Ràng buộc UNIQUE cấm mọi giá trị trùng lặp được thêm vào cột đã cho.

Như tên gọi của nó, ràng buộc UNIQUE yêu cầu mọi mục nhập trong cột đã cho phải là một giá trị duy nhất. Bất kỳ nỗ lực nào để thêm một giá trị đã xuất hiện trong cột sẽ dẫn đến lỗi.

UNIQUE ràng buộc UNIQUE hữu ích để thực thi mối quan hệ 1-1 giữa các bảng. Như đã đề cập trước đây, bạn có thể cài đặt mối quan hệ giữa hai bảng bằng foreign keys , nhưng có nhiều loại mối quan hệ có thể tồn tại giữa các bảng:

  • một đối một : Hai bảng được cho là có mối quan hệ một đối một nếu các hàng trong bảng mẹ có liên quan đến một và chỉ một hàng trong bảng con
  • một-nhiều : Trong mối quan hệ nhiều-bất kỳ, một hàng trong bảng mẹ có thể liên quan đến nhiều hàng trong bảng con, nhưng mỗi hàng trong bảng con chỉ có thể liên quan đến một hàng trong bảng mẹ.
  • nhiều-nhiều : Nếu các hàng trong bảng mẹ có thể liên quan đến nhiều hàng trong bảng con và ngược lại, cả hai được cho là có mối quan hệ nhiều-nhiều

Bằng cách thêm ràng buộc UNIQUE vào cột mà ràng buộc FOREIGN KEY đã được áp dụng, bạn có thể đảm bảo mỗi mục nhập trong bảng mẹ chỉ xuất hiện một lần trong bảng con, do đó cài đặt mối quan hệ 1-1 giữa hai bảng.

Lưu ý bạn có thể xác định các ràng buộc UNIQUE ở cấp bảng cũng như cấp cột. Khi được xác định ở cấp bảng, ràng buộc UNIQUE có thể áp dụng cho nhiều cột. Trong những trường hợp như thế này, mỗi cột có trong ràng buộc có thể có các giá trị trùng lặp nhưng mỗi hàng phải có một tổ hợp giá trị duy nhất trong các cột bị ràng buộc.

CHECK

Ràng buộc CHECK xác định một yêu cầu đối với một cột, được gọi là một vị từ , mà mọi giá trị được nhập vào nó phải đáp ứng.

CHECK vị từ ràng buộc CHECK được viết dưới dạng một biểu thức có thể đánh giá là TRUE , FALSE hoặc có khả năng là UNKNOWN . Nếu bạn cố gắng nhập một giá trị vào một cột có ràng buộc CHECK và giá trị khiến vị từ đánh giá thành TRUE hoặc UNKNOWN (xảy ra đối với các giá trị NULL ), thao tác sẽ thành công. Tuy nhiên, nếu biểu thức chuyển thành FALSE , nó sẽ không thành công.

CHECK vị từ CHECK thường dựa vào toán tử so sánh toán học (như < , > , <= , OR >= ) để giới hạn phạm vi dữ liệu được phép đưa vào cột đã cho. Ví dụ: một cách sử dụng phổ biến cho các ràng buộc CHECK là ngăn các cột nhất định giữ giá trị âm trong trường hợp giá trị âm không có ý nghĩa, như trong ví dụ sau.

Câu CREATE TABLE này tạo một bảng có tên productInfo với các cột cho tên, số nhận dạng và giá của từng sản phẩm. Vì sẽ không hợp lý nếu một sản phẩm có giá âm, câu lệnh này áp đặt ràng buộc CHECK đối với cột price đảm bảo rằng nó chỉ chứa các giá trị dương:

  • CREATE TABLE productInfo (
  • productID int,
  • name varchar(30),
  • price decimal(4,2)
  • CHECK (price > 0)
  • );

Không phải mọi vị từ CHECK đều phải sử dụng toán tử so sánh toán học. Thông thường, bạn có thể sử dụng bất kỳ toán tử SQL nào có thể đánh giá là TRUE , FALSE hoặc UNKNOWN trong một vị từ CHECK , bao gồm LIKE , BETWEEN , IS NOT NULL và các hàm khác. Một số triển khai SQL, nhưng không phải tất cả, thậm chí còn cho phép bạn bao gồm một truy vấn con trong một vị từ CHECK . Tuy nhiên, hãy lưu ý hầu hết các triển khai không cho phép bạn tham chiếu đến một bảng khác trong một vị từ.

NOT NULL

Ràng buộc NOT NULL cấm mọi giá trị NULL được thêm vào cột đã cho.

Trong hầu hết các triển khai SQL, nếu bạn thêm một hàng dữ liệu nhưng không chỉ định giá trị cho một cột nhất định, theo mặc định, hệ thống database sẽ biểu thị dữ liệu bị thiếu là NULL . Trong SQL, NULL là một từ khóa đặc biệt được sử dụng để biểu thị một giá trị không xác định, bị thiếu hoặc không xác định. Tuy nhiên, NULL không phải là một giá trị mà thay vào đó là trạng thái của một giá trị không xác định.

Để minh họa sự khác biệt này, hãy tưởng tượng một bảng được sử dụng để theo dõi khách hàng tại một đại lý tài năng có các cột cho họ và tên của mỗi khách hàng. Nếu khách hàng sử dụng một từ đơn - như “Cher”, “Usher” hoặc “Beyoncé” - administrator database có thể chỉ nhập từ đơn vào cột tên, khiến DBMS nhập NULL trong cột họ. Database không coi họ của khách hàng có nghĩa đen là "Null." Nó chỉ nghĩa là giá trị cho cột họ của hàng đó không xác định hoặc trường không áp dụng cho bản ghi cụ thể đó.

Như tên gọi của nó, ràng buộc NOT NULL ngăn bất kỳ giá trị nào trong cột đã cho là NULL . Điều này nghĩa là đối với bất kỳ cột nào có ràng buộc NOT NULL , bạn phải chỉ định giá trị cho cột đó khi chèn một hàng mới. Nếu không, thao tác INSERT sẽ không thành công.

Kết luận

Ràng buộc là công cụ cần thiết cho bất kỳ ai muốn thiết kế database với mức độ toàn vẹn và bảo mật dữ liệu cao. Bằng cách giới hạn dữ liệu nào được nhập vào một cột, bạn có thể đảm bảo mối quan hệ giữa các bảng sẽ được duy trì chính xác và database tuân theo các luật nghiệp vụ xác định mục đích của nó.

Để biết thêm thông tin chi tiết về cách tạo và quản lý các ràng buộc SQL, bạn có thể xem lại hướng dẫn của ta về Cách sử dụng các ràng buộc trong SQL . Nếu bạn muốn tìm hiểu thêm về SQL nói chung, ta khuyên bạn nên xem loạt bài của ta về Cách sử dụng SQL .


Tags:

Các tin liên quan