Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> SQL

Mối quan hệ Unary One-to-One (Một-một đệ quy) trong DBMS


Unary One-to-One Relationship (Mối quan hệ một-một đệ quy) là mối quan hệ giữa các instance của **chính một entity type**, nơi mỗi instance tối đa liên kết với **một** instance khác của cùng entity, và ngược lại. Hai instance đóng **cùng một vai trò (role group)**.

Ví dụ kinh điển: Người kết hôn (Marriage)

Bảng Person:

Person_ID (PK) Person_Name Spouse_ID (FK)
1An2
2Bình1
3CườngNULL
  • An (1) kết hôn với Bình (2) -> Spouse_ID trỏ lẫn nhau.
  • Cường (3) độc thân -> Spouse_ID = NULL.
  • Mối quan hệ MARRIED_TO là đối xứng (symmetric).

Ba trường hợp Participation Constraints (Ràng buộc tham gia)

1. Mandatory - Mandatory (Bắt buộc - Bắt buộc)

  • Mọi Person **phải** có Spouse (Spouse_ID NOT NULL).
  • Mọi Person **phải** là Spouse của một Person khác.
  • → Mọi người đều đã kết hôn, không ai độc thân. Khó thực thi (insert chicken-egg).
  • Thường chỉ dùng trong lý thuyết hoặc hệ thống closed (ví dụ: cặp đôi đồ vật luôn thành đôi).

2. Optional - Optional (Tùy chọn - Tùy chọn) - Phổ biến nhất

  • Person **có thể** có Spouse (kết hôn) hoặc không (độc thân).
  • Person **có thể** là Spouse của ai đó hoặc không.
  • Spouse_ID cho phép NULL.
  • Ví dụ mở rộng: Nộp thuế riêng lẻ hoặc chung. Cặp đôi có tùy chọn nộp chung (Joint) hoặc riêng (Separate). Ít nhất một cặp chọn riêng.

3. Optional - Mandatory (hoặc Mandatory - Optional)

  • Một vai trò bắt buộc tham gia, vai kia tùy chọn.
  • Ví dụ: Mỗi người **phải** có một "Người đại diện pháp lý" (Legal Guardian), nhưng Người đại diện **có thể** đại diện cho nhiều người (thì thành One-to-Many). One-to-One Mandatory-Optional hiếm gặp thực tế.

ER Diagram

Person (Entity)
   |
   | 1 (Spouse)          1 (Spouse)
   |----------------------|
   |      MARRIED_TO      |
   |______________________|
   (Recursive, Symmetric)

Triển khai SQL - Đảm bảo đối xứng (Symmetric)

Vấn đề: Insert An (Spouse=2) và Bình (Spouse=1) cần transaction. Cần trigger/check constraint đảm bảo đối xứng.

CREATE TABLE Person (
  Person_ID INT PRIMARY KEY,
  Person_Name VARCHAR(100) NOT NULL,
  Spouse_ID INT UNIQUE,  -- UNIQUE đảm bảo One-to-One (mỗi người chỉ là spouse của 1 người)
  FOREIGN KEY (Spouse_ID) REFERENCES Person(Person_ID)
    ON DELETE SET NULL   -- Vợ/chồng chết -> người kia độc thân
    ON UPDATE CASCADE
);

-- Trigger đảm bảo đối xứng (PostgreSQL example)
CREATE OR REPLACE FUNCTION enforce_symmetric_spouse()
RETURNS TRIGGER AS $$
BEGIN
  IF NEW.Spouse_ID IS NOT NULL THEN
    -- Cập nhật spouse của người kia trỏ về mình
    UPDATE Person SET Spouse_ID = NEW.Person_ID WHERE Person_ID = NEW.Spouse_ID;
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trigger_symmetric_spouse
AFTER INSERT OR UPDATE OF Spouse_ID ON Person
FOR EACH ROW EXECUTE FUNCTION enforce_symmetric_spouse();

So sánh One-to-One Unary vs Binary

Đặc điểmUnary One-to-One (Đệ quy)Binary One-to-One (2 bảng)
Số bảng1 bảng2 bảng
FKTự tham chiếu (Self-referencing)Bảng con tham chiếu bảng cha
Vai tròCùng một vai trò (Spouse - Spouse)Hai vai trò khác (Person - Passport)
Ví dụKết hôn, Đôi bạn thân, Buddy systemPerson - Passport, User - Profile
Đối xứngThường đối xứngKhông đối xứng

Ví dụ khác: Buddy System (Hệ thống bạn đồng hành)

  • Mỗi nhân viên mới được gán 1 "Buddy" (nhân viên cũ) hướng dẫn.
  • Buddy cũng là Employee.
  • Quan hệ: Employee (Newbie) - Buddy (Mentor). Có thể coi là Unary One-to-One (nếu 1-1) hoặc One-to-Many (1 Buddy hướng dẫn nhiều Newbie).

Best Practices

  1. Dùng UNIQUE constraint trên FK (Spouse_ID) để enforce One-to-One.
  2. Cho phép NULL cho Optional participation.
  3. Dùng Trigger / Application Logic để duy trì đối xứng (nếu cần).
  4. Cân nhắc tách bảng nếu logic phức tạp: Marriage table (Person_ID1, Person_ID2, Start_Date, End_Date) - linh hoạt hơn, hỗ trợ ly hôn, tái hôn, history.