Tôi có thể phân hủy bảng này không?


10

Tôi đã vấp phải một vấn đề thiết kế cơ sở dữ liệu nằm ngoài liên minh của mình, và chuyên gia về DBA của tôi đã tắt máy khoan.

Về bản chất, tôi có một bảng với khóa chính sau (PK cho ngắn gọn):

child_id   integer
parent_id  integer
date       datetime

child_idparent_idlà khóa ngoại cho bảng thực thể. Bản thân bảng "con" cũng chứa một khóa ngoại đối với bảng "cha mẹ" và lo, mỗi bảng child_idluôn tham chiếu giống parent_idnhư dự kiến ​​của bảng trên. Trong thực tế, hóa ra có một số mã bổ sung giữ cho cả hai đồng bộ.

Điều này làm cho người mới bình thường hóa quá nhiệt tình này nói rằng "Tôi nên loại bỏ sự dư thừa thay vào đó!"

Tôi phân hủy như sau:

Table_1 PK:
child_id   integer
date       datetime

Table_2 PK:
parent_id  integer
date       datetime

Table_3: (already exists)
child_id   integer PRIMARY KEY
parent_id  integer FOREIGN KEY

Và lo, khi tôi tham gia cùng những người này theo cách tự nhiên, tôi phục hồi bảng ban đầu. Chính sự hiểu biết của tôi đã tạo nên 5NF này.

Tuy nhiên, bây giờ tôi nhận ra có một quy tắc kinh doanh ẩn.

Thông thường, các ngày được liên kết với một ngày nhất định child_idphải là tập hợp con của các ngày được liên kết với tương ứng parent_id. Bạn có thể thấy rằng bảng đầu tiên thực thi quy tắc này.

Sự phân tách của tôi không thực thi quy tắc, bởi vì bạn có thể tự do thêm vào Bảng 1 cho đến khi ngày quá lớn.

Điều này dẫn tôi đến đây, với các câu hỏi sau:

  1. Đây có phải là sự phân hủy 5NF? Mặc dù tôi nói rằng nó cho phép chèn dị thường, nhưng dường như nó cũng tuân theo ví dụ Wiki, chính nó tuân theo hướng dẫn này . Cụm từ (nhấn mạnh của tôi) "chúng tôi có thể tái tạo lại tất cả các sự kiện thực tế từ một hình thức chuẩn hóa bao gồm ba loại hồ sơ riêng biệt" mang lại cho tôi sự tạm dừng đặc biệt, vì cho dù tôi có bơm bao nhiêu rác Table_1, thì sự tham gia tự nhiên vẫn bỏ qua nó.

  2. Giả sử tôi không thích sự phân rã này (tôi không). Tôi tự do thừa nhận rằng giải pháp thực tế là rời khỏi bảng và mã như hiện tại. Nhưng, về mặt lý thuyết, có cách nào để phân tách và / hoặc thêm các ràng buộc để tôi thoát khỏi bảng đầu tiên duy trì các quy tắc kinh doanh của mình không?


1
Các khóa trong bảng gốc của bạn là gì? Những gì phụ thuộc là nó phải satsify? Có vẻ như bạn đang nói rằng child_id-> Parent_id, trong trường hợp đó child_id và Parent_id không thể là một phần của cùng một khóa trong bảng đó.
nvogel

1
@trevor: Bạn đã bao giờ xem lại câu trả lời ở đây chưa? Nhìn thấy lần cuối 19 phút sau khi hỏi. Các câu trả lời đến sau.
gbn

Câu trả lời:


9

Bình thường hóa dựa trên các phụ thuộc chức năng. Phụ thuộc chức năng phải làm với ngữ nghĩa; họ phải làm gì với ý nghĩa của dữ liệu . Khi bạn đơn giản hóa một vấn đề trong thế giới thực đến mức "Parent_id, child_id, date" và bạn không bao gồm bất kỳ dữ liệu mẫu nào, bạn thực sự giới hạn mức độ mà một nhà thiết kế cơ sở dữ liệu có lương tâm có thể cung cấp cho bạn.

Việc bạn có một khóa {child_id, Parent_id, date} trong một bảng và bạn có (dường như) một cặp duy nhất {child_id, Parent_id} trong bảng con không nhất thiết có nghĩa là một phần của kết hợp là dư thừa . Điều đó có thể có nghĩa là trong bảng có {child_id, Parent_id, date} là khóa chính, cặp thuộc tính {child_id, Parent_id} nên tham chiếu bảng con ở vị trí đầu tiên.

Nếu đó là trường hợp, bạn có thể sử dụng FOREIGN KEY (child_id, parent_id) REFERENCES child (child_id, parent_id). Để làm điều đó, bạn cần một ràng buộc ĐỘC ĐÁO đối với cặp cột (child_id, Parent_id) trong bảng "con", đây không phải là vấn đề nếu child_id là khóa chính của nó.

Nhưng không có cách nào để nói mà không biết dữ liệu nghĩa là gì và bạn là người duy nhất trong chuỗi này biết điều đó. (Nhưng chúng tôi rất vui lòng để bạn giải thích cho chúng tôi.)

Theo như bảng gốc có liên quan, dường như bạn đang nói rằng child_id -> Parent_id. Nếu đó là trường hợp, tại sao cha_id trong bảng gốc ở vị trí đầu tiên? Tại sao không phải là khóa chỉ (child_id, ngày), với tham chiếu khóa ngoài đến bảng "con"? Đối với tôi, có vẻ như loại dư thừa mà bạn đang nói đến có thể được giải quyết bằng cách bỏ cột "Parent_id".

SQL DDL và dữ liệu mẫu dưới dạng câu lệnh INSERT giúp chúng tôi giúp bạn. Các câu lệnh DDL và INSERT chính xác hơn các mô tả.


1
+2 cho lời nhắc "phụ thuộc chức năng"
jcolebrand

3

Thử đi...

  • Thêm ràng buộc duy nhất (child_id,parent_id)vào bảng con
  • Bảng hiện tại của bạn (PK,FK:child_id, PK,FK:parent_id, PK:date)vẫn như cũ, FK nằm trên 2 cột với ràng buộc duy nhất mới

hoặc là

  • Xóa FK khỏi bảng con hiện tại
  • Tạo một bảng mới (PK,FK:child_id, FK:parent_id)là 1: 1 với con
  • Bảng hiện tại của bạn (PK,FK: child_id, PK,FK: parent_id, PK:date)vẫn như cũ. nhưng FK nằm trên 2 cột vào bảng mới

Nếu không có gì khác, nó có thể truyền cảm hứng cho bạn ...

Nếu tôi hiểu đúng, nó sẽ loại bỏ sự dư thừa và mã ...

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.