2010-10-20 36 views
5

Đây là một câu hỏi về thiết kế chuẩn hóa/SQL/Cơ sở dữ liệu khó hiểu đã khiến chúng tôi khó hiểu. Tôi hy vọng tôi có thể tuyên bố nó một cách chính xác.Cách tốt nhất để thiết kế cơ sở dữ liệu/vấn đề SQL cụ thể này là gì?

Bạn có một tập hợp các hoạt động. Đó là những điều cần được thực hiện - danh sách TODO được tôn vinh. Bất kỳ hoạt động cụ thể nào cũng có thể được chỉ định cho một nhân viên.

Mọi hoạt động cũng có một sự ghê tởm đối với hoạt động sẽ được thực hiện. Những hoạt động đó là Liên hệ (người) hoặc Khách hàng (doanh nghiệp). Mỗi hoạt động sau đó sẽ có một liên hệ hoặc một khách hàng cho người mà các hoạt động sẽ được thực hiện. Ví dụ: hoạt động có thể là "Gửi thẻ cảm ơn đến Spacely Sprockets (một khách hàng)" hoặc "Gửi tài liệu tiếp thị tới Tony Almeida (một Liên hệ)".

Từ cấu trúc đó, chúng tôi sau đó cần phải có khả năng truy vấn để tìm tất cả các hoạt động một nhân viên cho có để làm, cách liệt kê chúng trong một mối quan hệ đơn đó sẽ là một cái gì đó như thế này trong nó hình thức đơn giản nhất:

----------------------------------------------------- 
| Activity | Description | Recipient of Activity | 
----------------------------------------------------- 

Ý tưởng ở đây là để tránh có hai cột cho Liên hệ và Khách hàng với một trong số chúng trống.

Tôi hy vọng tôi đã mô tả chính xác điều này, vì điều này không rõ ràng vì nó có vẻ thoáng qua.

Vì vậy, câu hỏi đặt ra là: Thiết kế "đúng" cho cơ sở dữ liệu là gì và bạn sẽ truy vấn nó như thế nào để nhận thông tin được yêu cầu?

+0

Dường như có sự nhầm lẫn về khách hàng và địa chỉ liên hệ. Họ có bàn riêng biệt không? Có mối quan hệ nào giữa khách hàng và người liên hệ không? Chúng có phải là các bảng hiện có mà bạn cần phải làm việc, hoặc các bảng mới hoặc có thể tái cấu trúc được không? – ulty4life

+0

Có, khách hàng và người liên hệ là các thực thể riêng biệt. Có lẽ họ không nên, nhưng họ đang có. ;-) –

Trả lời

2

Đây là đâm của tôi lúc đó:

Về cơ bản bạn cần hoạt động có liên quan đến 1 (tiếp xúc hoặc khách hàng) và 1 nhân viên đó là trở thành một người có trách nhiệm cho hoạt động này . Lưu ý rằng bạn có thể xử lý ràng buộc tham chiếu trong một mô hình như thế này.

Cũng lưu ý rằng tôi đã thêm một bảng kinh doanhBảng kết nối tất cả mọi người và địa điểm. (đôi khi hữu ích nhưng không cần thiết). Lý do đặt bảng businessEntity là bạn có thể tham khảo đơn giản ResponsiblePerson và Người nhận về hoạt động với businessEntity và bây giờ bạn có thể có các hoạt động được tạo và nhận bởi bất kỳ và tất cả mọi người hoặc địa điểm.

alt text

1

Bạn sẽ có một cái gì đó như sau:

Activity | Description | Recipient Type

đâu Recipient Type là một trong những Contact hoặc Customer

Sau đó bạn sẽ thực thi một lệnh SQL lựa chọn công bố như sau:
Select * from table where Recipient_Type = 'Contact';

Tôi nhận ra rằng cần có thêm thông tin.

Chúng tôi sẽ cần một bảng bổ sung đó là đại diện của người nhận (Danh bạ và khách hàng):

Bảng này sẽ giống như sau:

ID | Name| Recipient Type

Recipient Type sẽ là một tài liệu tham khảo quan trọng để bàn ban đầu được đề cập trước đó trong bài đăng này. Tất nhiên sẽ cần phải được thực hiện công việc để xử lý các tầng trên các bảng này, chủ yếu là các bản cập nhật và xóa. Vì vậy, khái quát lại nhanh:

Recipients.Recipient_Type là một FK để Table.Recipient_Type

+1

Nó nói ai là người nhận trong mô hình này? Làm thế nào bạn sẽ quản lý phím nước ngoài để 'Contacts' /' khách hàng'? Bạn sẽ phân biệt giữa chúng? –

+0

Không hoàn toàn chắc chắn là tôi đã theo dõi câu hỏi của bạn Martin, tôi thấy bây giờ – Woot4Moo

+1

Điều này sẽ chảy nhiều hơn và trả lời câu hỏi. Hãy cho tôi biết nếu nó cần giải thích thêm – Woot4Moo

4

Các "quyền" thiết kế cho cơ sở dữ liệu này là phải có một cột cho mỗi, mà bạn nói rằng bạn đang cố gắng để tránh. Điều này cho phép một mối quan hệ khóa ngoài thích hợp được xác định giữa hai cột đó và các bảng tương ứng của chúng. Sử dụng cùng một cột cho một khóa đề cập đến hai bảng khác nhau sẽ làm cho truy vấn xấu xí và bạn không thể thực thi tính toàn vẹn tham chiếu.

hoạt động bảng cần phải có các phím nước ngoài ContactID, CustomerID

Để hiển thị các hoạt động cho người lao động:

SELECT ActivityName, ActivityDescription, CASE WHEN a.ContactID IS NOT NULL THEN cn.ContactName ELSE cu.CustomerName END AS Recipient 
FROM activity a 
LEFT JOIN contacts cn ON a.ContactID=cn.ContactID 
LEFT JOIN customers cu ON a.CustomerID=cu.CustomerID 
+0

Tôi nghĩ rằng có một sự hiểu lầm cơ bản trong những gì một chìa khóa nước ngoài là liên quan đến một cơ sở dữ liệu quan hệ về phía bạn. – Woot4Moo

+0

Không chắc chắn ý của bạn là gì. Tôi có thể đã đưa ra giả thiết về những gì OP đang đề xuất. –

+0

Vấn đề tôi thực hiện lưu ý là giống như trong bài đăng với sơ đồ đẹp. Làm thế nào để điều này không trở thành một vấn đề bảo trì trong tương lai khi nhiều loại Người nhận được thêm vào. Cách thích hợp nhất, xem duy trì, là có một bảng người nhận cho phép bổ sung/sửa đổi cột Recipient_Type không làm hỏng mạnh tinh thần của bất kỳ ai duy trì cơ sở dữ liệu. – Woot4Moo

9

Nghe có vẻ như một mối quan hệ cơ bản nhiều-nhiều và tôi muốn mô hình nó như vậy.

alt text

+0

Quy mô này như thế nào – Woot4Moo

+0

Tôi thích điều này theo nhiều cách, nhưng nó bổ sung thêm hai bảng phụ ... và thêm chức năng. Trừ khi một người cần khả năng có nhiều "người nhận" cho một hoạt động duy nhất tôi nghĩ rằng có hai khóa nước ngoài trên bảng Activity sẽ đơn giản hơn –

+0

@ Woot4Moo: Rõ ràng nó có quy mô bằng cách yêu cầu các bảng bổ sung, nhưng nó tránh được các vấn đề xếp tầng được đề cập trong sol của bạn ution. –

0
[ActivityRecipientRecipientType] 
    ActivityId 
    RecipientId 
    RecipientTypeCode 
     ||| ||| |||_____________________________  
     |  |         | 
     |  --------------------    | 
     |      |    | 
    [Activity]    [Recipient]  [RecipientType] 
    ActivityId    RecipientId  RecipientTypeCode 
    ActivityDescription  RecipientName RecipeintTypeName 


    select 
     [Activity].ActivityDescription 
    , [Recipient].RecipientName 
    from 
     [Activity] 
    join [ActivityRecipientRecipientType] on [Activity].ActivityId = [ActivityRecipientRecipientType].ActivityId 
    join [Recipient] on [ActivityRecipientRecipientType].RecipientId = [Recipient].RecipientId 
    join [RecipientType] on [ActivityRecipientRecipientType].RecipientTypeCode = [RecipientType].RecipientTypeCode 
    where [RecipientType].RecipientTypeName = 'Contact' 
+0

Chăm sóc để giải thích sự cần thiết phải tham gia nhiều và làm thế nào điều này không trở thành cơn ác mộng của DBA? – Woot4Moo

4

Nó không rõ ràng với tôi lý do tại sao bạn đang xác định khách hàng và hệ như những thực thể riêng biệt, khi họ dường như là phiên bản của cùng một thực thể. Dường như với tôi rằng Khách hàng là Người liên hệ có thông tin bổ sung. Nếu có thể, tôi sẽ tạo một bảng Liên hệ và sau đó đánh dấu các bảng là Khách hàng hoặc với một trường trong bảng đó hoặc bằng cách thêm id của chúng vào bảng Khách hàng có thông tin khách hàng được mở rộng trong đó.

Nếu bạn không thể làm điều đó (vì điều này đang được xây dựng trên đầu trang của một hệ thống hiện có, thiết kế được cố định) thì bạn có nhiều lựa chọn. Không có lựa chọn nào là tốt bởi vì chúng không thể thực sự làm việc xung quanh lỗ hổng ban đầu, lưu trữ riêng Khách hàng và Danh bạ.

  1. Sử dụng hai cột, một NULL để cho phép toàn vẹn tham chiếu hoạt động.

  2. Tạo bảng trung gian Hoạt độngLiên hệ với PK và hai cột riêng của nó, một NULL, để trỏ tới Khách hàng hoặc Liên hệ. Điều này cho phép bạn xây dựng một hệ thống hoạt động "sạch", nhưng đẩy sự xấu xí vào bảng trung gian đó. (Nó cung cấp một lợi ích có thể, đó là nó cho phép bạn giới hạn mục tiêu của các hoạt động cho những người được thêm vào bảng trung gian, nếu đó là một lợi thế cho bạn).

  3. Mang lỗi thiết kế ban đầu vào hệ thống Hoạt động và (Tôi đang cắn lưỡi ở đây) có các bảng ContactActivity và CustomerActivity song song. Để tìm tất cả nhiệm vụ được giao của nhân viên, UNION hai bảng đó lại với nhau thành một trong VIEW. Điều này cho phép bạn duy trì tính toàn vẹn tham chiếu, không yêu cầu cột NULL, và cung cấp cho bạn một nguồn để lấy báo cáo của bạn.

0
Actions 
Activity_ID | Description | Recipient ID 
------------------------------------- 
11 | Don't ask questions | 0 
12 | Be cool | 1 

Activities 
ID | Description 
---------------- 
11 | Shoot 
12 | Ask out 

People 
ID | Type | email | phone | GPS |.... 
------------------------------------- 
0 | Troll | [email protected] | 232323 | null | ... 
1 | hottie | [email protected] | 2341241 | null | ... 


select at.description,a.description, p.* from Activities at, Actions a, People p 
where a."Recipient ID" = p.ID 
    and at.ID=a.activity_id 

result: 

Shoot | Don't ask questions | 0 | Troll | [email protected] | 232323 | null | ... 
Ask out | Be cool | 1 | hottie | [email protected] | 2341241 |null | ... 
2

Nếu tôi đã đọc các trường hợp đúng, người nhận là một sự tổng quát của khách hàng và Danh bạ.
Mẫu thiết kế gen-spec được hiểu rõ.

Data modeling question

0

mẫu khác Entity: ActivityRecipient, sẽ được thừa hưởng bởi ActivityRecipientContact và ActivityRecipientCustomer, mà sẽ giữ đúng ID khách hàng/Liên hệ.

Các bảng tương ứng sẽ là:

Table: Activities(...., RecipientID) 

Table: ActivityRecipients(RecipientID, RecipientType) 

Table: ActivityRecipientContacts(RecipientID, ContactId, ...,ExtraContactInfo...) 

Table: ActivityRecipientCustomers(RecipentID, CustomerId, ...,ExtraCustomerInfo...) 

Bằng cách này bạn cũng có thể có các cột khác nhau đối với từng loại người nhận

0

tôi sẽ rà soát lại định nghĩa về khách hàng và liên hệ. Một khách hàng có thể là một người hoặc một doanh nghiệp, phải không? Ở Braxin, có các thuật ngữ 'pessoa jurídica' và 'pessoa física' - trong một bản dịch trực tiếp (và không có đầu óc) trở thành 'pháp nhân' (kinh doanh) và 'thể nhân' (cá nhân). Một bản dịch tốt hơn đã được đề xuất bởi Google: 'pháp nhân' và 'cá nhân'.

Vì vậy, chúng tôi có bảng người và có bảng 'LegalEntity' và 'Individual' (nếu có đủ thuộc tính để biện minh cho nó - ở đây có rất nhiều). Và người nhận trở thành một bảng FK to Person.

Và nơi đã mất địa chỉ liên hệ? Họ trở thành một bảng liên kết với con người. Vì người liên hệ là người liên lạc với người khác (ví dụ: vợ tôi là người liên hệ đã đăng ký của tôi với một số công ty tôi là khách hàng). Mọi người có thể có liên hệ.

Lưu ý: Tôi đã sử dụng từ 'Người' nhưng bạn có thể gọi nó là 'Khách hàng' để đặt tên cho bảng cơ sở đó.

Các vấn đề liên quan