Làm thế nào để thiết kế cơ sở dữ liệu này để tránh phụ thuộc theo chu kỳ?


12

Có hai bảng:

  1. Người sử dụng
  2. Địa chỉ

Người dùng chứa một tham chiếu đến Địa chỉ.

Địa chỉ chứa các cột createdBy và ModifiedBy, tham chiếu đến Người dùng.

Làm cách nào để thiết kế cơ sở dữ liệu này để tránh phụ thuộc theo chu kỳ?


4
Bạn có chắc chắn ModifiedBy không phải là tham chiếu đến người dùng cơ sở dữ liệu đã thực hiện thay đổi, thay vì người dùng ứng dụng (sẽ nằm trong bảng Người dùng)? Dù bằng cách nào, nó không thực sự quan trọng. Tôi không thấy lý do tại sao có một vấn đề thực tế?
Philᵀᴹ

Cái nào sẽ được tạo trước. Như createdBy ANd Modifiedby là dữ liệu bắt buộc. Và bảng người dùng không nên có địa chỉ là null .. Vấn đề trứng gà. Khi tôi giải quyết điều này bằng cách tạo một bảng mới UserAddress chứa tham chiếu cho userid và addressid
Shashi

2
Bạn luôn có thể sử dụng các ràng buộc hoãn lại nếu DBMS của bạn hỗ trợ chúng.
Colin 't Hart

NB Mô hình quan hệ hỗ trợ thực hiện hai lần chèn hoặc cập nhật dưới dạng một thao tác nguyên tử, thật xấu hổ vì điều này không được hỗ trợ trong SQL (như các ràng buộc hoãn lại - mặc dù tôi đã đề xuất chúng - khá kinh khủng).
Colin 't Hart

Câu trả lời:


7

Thay vì tìm kiếm các mẹo và thủ thuật (bao gồm các ràng buộc hoãn lại) tôi sẽ đề nghị bạn chỉ cần thiết kế theo cách của bạn khỏi "khóa tham chiếu" này - vì vậy hãy thử một cái gì đó như thế này:


Sự kiện

  • Người dùng(UserID) tồn tại.
  • Địa chỉ(AddressID) được tạo bởi người dùng(UserID) .
  • Địa chỉ(AddressID) đã được tạo vào ngày(DateCreated) .
  • Địa chỉ(AddressID) được sửa đổi lần cuối bởi Người dùng(UserID) vào Ngày(ModifiedOn) .
  • Người dùng(UserID) cư trú tại Địa chỉ(AddressID) kể từ Ngày(ValidFrom) .

Những ràng buộc

  • Each Địa chỉ được tạo bởi người exactly one dùng . It is possible that more than one Địa chỉ được tạo bởi người the same dùng .

  • Each Địa chỉ đã được tạo vào exactly one ngày . It is possible that more than one Địa chỉ đã được tạo vào the same ngày .

  • For each Địa chỉ and Ngày , that Địa chỉ đã được sửa đổi bởi at most one Người dùng vào that Ngày .

  • For each and Ngày người dùng , người that dùng cư trú at most one Địa chỉ kể từ that ngày .


Hợp lý

nhập mô tả hình ảnh ở đây


Theo như địa chỉ bắt buộc có liên quan, hãy xác minh rằng trên lớp ứng dụng và bọc các câu lệnh tải vào một giao dịch - theo cách đó bạn sẽ nhận được tất cả hoặc không có gì.


5

Bạn không có lựa chọn nào khác ngoài việc tạo ra sự phụ thuộc theo chu kỳ trong 2 thao tác như dưới đây vì một bảng không tồn tại khi bạn tạo bảng đầu tiên.

CREATE TABLE A (A_ID INT PRIMARY KEY, B_FK INT);
CREATE TABLE B (B_ID INT PRIMARY KEY, A_FK INT REFERENCES A(A_ID));

ALTER TABLE A ADD B_FK INT;

Nếu bạn muốn tránh phụ thuộc theo chu kỳ. Sau đó, bạn cần xóa một ràng buộc TÀI LIỆU THAM KHẢO hoặc bạn có thể thêm một tham chiếu XÓA và CẬP NHẬT CASCADE theo một cách. Bạn cũng có thể triển khai TRIGGER nếu logic của bạn hơi phức tạp.


1
Loại bỏ các ràng buộc loại bỏ sự phụ thuộc theo chu kỳ khỏi định nghĩa, nhưng không phải là thiết kế. Bạn có thể thêm bảng Sự kiện để ghi lại ID người dùng và Địa chỉ ID đã tạo hoặc sửa đổi địa chỉ lần cuối, nhưng điều đó chỉ khiến phụ thuộc thêm một bước nữa. Theo một cách khác, nếu bảng Người dùng có các cột createdBy và ModifiedBy, thì sự phụ thuộc theo chu kỳ sẽ tồn tại trong một bảng. Điều này tương tự như một bảng nhân viên với một cột giám sát trong đó giám sát viên cũng là một nhân viên. Như Phil đã chỉ ra - Không phải là một vấn đề.
Leigh Riffel

@LeighRiffel Tôi đồng ý. Nhưng bảng Sự kiện bạn đề xuất thực sự loại bỏ tất cả các phụ thuộc theo chu kỳ.
ypercubeᵀᴹ

@ypercube Quả thực là vậy; không chắc làm thế nào tôi có được dây đó vượt qua. Để rõ ràng, có lẽ bạn không nên tạo một bảng Sự kiện mặc dù nó loại bỏ sự phụ thuộc theo chu kỳ.
Leigh Riffel

Dù sao, tôi không nghĩ rằng câu trả lời này giải quyết vấn đề. Câu hỏi (tôi nghĩ) là về cách tránh con đường tuần hoàn, chứ không phải làm thế nào để tạo FK với con đường tuần hoàn ở nơi đầu tiên.
ypercubeᵀᴹ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.