Vấn đề mối quan hệ thực thể


19

Tôi có 4 bảng liên quan như thế này (đây là một ví dụ):

Company:
ID
Name
CNPJ

Department:
ID
Name
Code
ID_Company 

Classification:
ID
Name
Code
ID_Company

Workers:
Id 
Name
Code
ID_Classification
ID_Department

Giả sử tôi có một classificationvới id = 20, id_company = 1. Và một departmentcái có id_company = 2(đại diện cho một công ty khác).

Điều này sẽ cho phép tạo ra một công nhân từ hai công ty vì phân loại và bộ phận được liên kết với công ty một cách riêng biệt. Tôi không muốn điều đó xảy ra, vì vậy tôi nghĩ rằng tôi có vấn đề với các mối quan hệ của mình và tôi không biết làm thế nào để giải quyết nó.


1
'Phân loại' là gì?
Jehad Keriaki

1
Tôi đoán classificationlà tương tự như vị trí tức là thư ký, người gác cổng, người thừa kế, v.v.
Erik

Bạn có muốn thực thi rằng một công nhân phải thuộc cùng một bộ phận như phân loại không?
Lennart

Có lẽ Khởi hành, Phân loại (và thậm chí Công nhân) nên được xem là các thực thể yếu, tất cả phụ thuộc vào Công ty. Sau đó, khóa Công ty sẽ là một phần của các khóa Khởi hành, Phân loại và Công nhân. Một thực thể yếu là một thực thể có sự tồn tại phụ thuộc vào sự tồn tại của một thực thể khác.
phép lạ173

Câu trả lời:


9

Vấn đề của bạn bắt nguồn từ thực tế là có một loại thực thể bị thiếu trong mô hình của bạn. Hãy xem xét ERD sau:

ERD

Lưu ý rằng tôi đã thêm một loại thực thể giao nhau giữa DEPARTMENTCLASSIFICATION. Loại thực thể mới này: POSITIONcung cấp thông tin ẩn trong mô hình của bạn, rằng một bộ phận cụ thể có một tập hợp các công việc phân loại khác nhau.

Thêm POSITIONvào mô hình của bạn như một thực thể rõ ràng có một vài lợi thế.

  1. Nó tránh được vấn đề mà bạn quan tâm với WORKERkhả năng được giao cho các phòng ban và phân loại ở các công ty khác nhau.
  2. Nó cung cấp cho bạn một vị trí cho các vị từ khác có thể áp dụng cho một vị trí, chẳng hạn như mức lương, v.v.
  3. Nó cho phép bạn ghi lại thực tế rằng một vị trí tồn tại, ngay cả khi WORKERhiện tại không có vị trí nào, đây là thông tin khá hữu ích.

Lưu ý rằng để tránh vấn đề về vị trí được xác định cho một bộ phận và phân loại ở các công ty khác nhau, tôi đã mở rộng các khóa của cả hai DEPARTMENTCLASSIFICATION, điều này tốt cho những lý do bạn có thể đọc về câu trả lời của Todd Everett.

THƯỞNG Mô hình ở trên giả định đơn giản hóa. Cụ thể, nó giả định rằng mỗi vị trí chỉ được ghi lại một lần. Điều này có thể hoặc có thể không phù hợp với quy tắc kinh doanh của bạn. Nếu bạn cần nhiều POSITIONhồ sơ cho cùng một bộ phận và phân loại trong một công ty, thì bạn có thể giới thiệu khóa thay thế POSITION.


24

Tôi không nghĩ rằng bạn có vấn đề với các mối quan hệ. Tôi nghĩ thay vào đó, vấn đề là bằng cách sử dụng các khóa thay thế (ví dụ Id) cho mỗi bảng, cơ sở dữ liệu kết quả không thể ngăn Công nhân được chèn vào Bộ phận của một Công ty trong khi Phân loại là của một Công ty khác và ngược lại. Một cách tốt để hiểu điều này là trực quan hóa lược đồ bằng công cụ Lập biểu đồ ER. Tôi sẽ sử dụng công cụ Oracle Data Modeler , một bản tải xuống miễn phí.

Sơ đồ ER

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

Khi nó đứng, bạn có thể có 2 công ty - nói IBMMicrosoft. IBMcó thể có một Software Developmentbộ phận và Microsoft có thể có một Desktop Softwarebộ phận. IBM có thể có một Software Engineerphân loại và Microsoft có thể có một Software Developerphân loại. Bây giờ, vì bạn có một khóa thay thế cho DepartmentClassification, thực tế đó Software Developmentlà một IBMbộ phận và Desktop Softwarelà một Microsoftbộ phận bị mất cho các mối quan hệ trẻ em trong tương lai. Đây cũng là trường hợp với Classification. Do đó, rất dễ để vô tình gán Harlan Mills, ai là IBMnhân viên trong Software Developmentbộ phận, phân loại trong Software Developerđó là mộtMicrosoftphân loại! Tương tự như vậy, công nhân có thể được phân loại đúng và sai bộ phận! Đây là một sơ đồ hiển thị ví dụ đầu tiên:

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

1 Id đại diện IBMvà 2 Id đại diện Microsoft. Tôi đã đánh dấu màu đỏ vào kịch bản trong đó Harlan MillsBill Gatesđược gán cho các bộ phận sai, được hiển thị bằng Id bộ phận 10 được liên kết với 200 Id phân loại và ngược lại.

Tùy chọn để giải quyết

Vì vậy, các tùy chọn để ngăn chặn anh ta xảy ra là gì? Có hai lựa chọn ngay lập tức. Đầu tiên là nhận ra rằng bằng cách sử dụng khóa thay thế cho mỗi bảng, vấn đề này tồn tại và giới thiệu chương trình bổ sung để xác minh nó không xảy ra. Điều này có thể được thực hiện trong ứng dụng, nhưng nếu việc chèn và cập nhật có thể xảy ra bên ngoài ứng dụng thì các liên kết không chính xác vẫn có thể xảy ra. Một cách tiếp cận tốt hơn sẽ là tạo ra một trình kích hoạt kích hoạt tính năng chèn và cập nhật của nhân viên để đảm bảo rằng bộ phận được phân công thuộc cùng công ty với phân loại được chỉ định và nếu không thất bại trong việc chèn hoặc cập nhật.

Tùy chọn thứ hai là không sử dụng các khóa thay thế cho mỗi bảng. Thay vào đó, chỉ sử dụng các khóa thay thế cho Companybảng, đây là cơ bản và không có cha mẹ, sau đó tạo các mối quan hệ xác định cho các bảng con DepartmentClassificationbảng con. Các bảng DepartmentClassificationbây giờ có PK Company Idcộng với Số thứ tự hoặc Tên để phân biệt chúng. Sau đó, các mối quan hệ từ DepartmentClassificationđể Workercũng trở thành identifyingvà do đó các PK của Workertrở thành Company Id, cộng với Department Number(Tôi đang sử dụng một số thứ tự trong ví dụ này), cộng với Classification Number. Kết quả là chỉ có one Company Idtrong Workerbảng. Bây giờ không thể chỉ định mộtWorkermột Departmenttrong một Companyvà một Classificationtrong một khác Company.

Tại sao điều này là không thể? Nó là không thể bởi vì các lược đồ thực hiện toàn vẹn tham chiếu giữa WorkerDepartmentClassification. Nếu một nỗ lực được thực hiện để chèn một Workercho một Departmenttrong một Companyvà và Classificationcủa người khác, sự kết hợp đó không tồn tại trong bảng cha tương ứng sẽ kích hoạt một sự vi phạm toàn vẹn tham chiếu và chèn sẽ không làm việc.

Dưới đây là sơ đồ cập nhật về việc thực hiện tùy chọn thứ hai: nhập mô tả hình ảnh ở đây

Tùy chọn ưa thích

Trong hai tùy chọn, tôi hoàn toàn thích cách thứ hai - sử dụng các mối quan hệ xác định và khóa xếp tầng - vì hai lý do. Đầu tiên, tùy chọn này đạt được quy tắc mong muốn mà không cần lập trình bổ sung. Phát triển một kích hoạt là không tầm thường. Nó phải được mã hóa, thử nghiệm và duy trì. Đảm bảo logic kích hoạt là tối ưu để không ảnh hưởng đến hiệu suất cũng không phải là nhỏ. Cuốn sách Toán học ứng dụng cho các chuyên gia cơ sở dữ liệu cung cấp rất nhiều chi tiết về sự phức tạp của một giải pháp như vậy. Thứ hai, các quy tắc ngụ ý rằng Bộ và Phân loại không thể tồn tại bên ngoài bối cảnh của Company, và vì vậy lược đồ bây giờ phản ánh chính xác hơn thế giới thực.

Đây là một câu hỏi tuyệt vời bởi vì nó cho thấy chính xác lý do tại sao chỉ cần giả sử mỗi bảng yêu cầu khóa thay thế là một ý tưởng tồi. Fabian Pascal có một bài đăng blog tuyệt vời về chủ đề này cho thấy rằng khóa không chỉ có thể là một ý tưởng tồi từ quan điểm toàn vẹn dữ liệu mà còn có thể khiến một số truy xuất chậm hơnở cấp độ vật lý chính xác bởi vì các phép nối được yêu cầu rằng, có các khóa được xếp tầng chính xác, sẽ không cần thiết. Một chủ đề thú vị khác mà câu hỏi này tiết lộ là một cơ sở dữ liệu không thể đảm bảo rằng tất cả dữ liệu được chèn vào đó là chính xác đối với thế giới thực. Thay vào đó, nó chỉ có thể đảm bảo rằng dữ liệu được chèn vào nó phù hợp với các quy tắc được khai báo. Trong trường hợp này, chúng ta có thể làm tốt nhất có thể bằng cách sử dụng cách tiếp cận khóa xếp tầng để đảm bảo DBMS có thể giữ dữ liệu phù hợp với quy tắc rằng một Workertrong những Companynhu cầu nhất định phải được chỉ định ClassificationDepartmenttương tự Company. Nhưng, nếu trong thế giới thực Microsoftcó một bộ phận được gọi Desktop Softwarenhưng người dùng cơ sở dữ liệu sẽ xác nhận bộ phận đó làSoftware Development DBMS không thể làm gì khác ngoài việc cho rằng nó đã được đưa ra một sự thật.


1

Cách tôi hiểu câu hỏi là, trường ID_Classification của bảng 'Công nhân' chỉ nên cho phép phân loại được xác định cho công ty của công nhân tương ứng. Do đó, xác thực (bằng cách đính kèm một RULE hoặc thông qua TRIGGERS), thông tin được chèn / cập nhật vào Workers.ID_Classification là đủ để giải quyết yêu cầu này.


1

Từ các bài đọc của tôi, tôi vẫn không hiểu Phân loại này là gì và tại sao cần phải có ID_Company . Nếu nó giống như một vị trí như ai đó đã đề cập ở đây, tôi nghĩ rằng một bảng tĩnh để chứa tất cả các vị trí sẽ tốt hơn.

Nếu bạn đang làm điều này để dễ dàng tìm thấy một phân loại / vị trí trong một công ty, vui lòng thêm một truy vấn / chế độ xem đơn giản để kết nối các bộ phận công nhân-phân loại và lấy id công ty của phân loại.

ngày nay, có các chế độ xem hoặc công nghệ thông minh hơn như các khung nhìn cụ thể hóa và các chỉ mục tham gia, vì vậy nếu vấn đề của bạn là hiệu năng của truy vấn, hãy sử dụng chúng.

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.