Đây có phải là một cách vô lý để cấu trúc một lược đồ DB, hay tôi hoàn toàn thiếu một cái gì đó?


61

Tôi đã thực hiện một chút công việc với các cơ sở dữ liệu quan hệ và nghĩ rằng tôi hiểu các khái niệm cơ bản của thiết kế lược đồ tốt khá tốt. Gần đây tôi được giao nhiệm vụ tiếp quản một dự án trong đó DB được thiết kế bởi một nhà tư vấn được trả lương cao. Xin vui lòng cho tôi biết nếu ruột của tôi - "WTF ??!?" - được bảo hành, hay anh chàng này là một thiên tài mà anh ta hoạt động ra khỏi vương quốc của tôi?

DB trong câu hỏi là một ứng dụng nội bộ được sử dụng để nhập yêu cầu từ nhân viên. Chỉ cần nhìn vào một phần nhỏ của nó, bạn có thông tin về người dùng và thông tin về yêu cầu được đưa ra. Tôi sẽ thiết kế như thế này:

Bảng người dùng:

UserID (primary Key, indexed, no dupes)
FirstName
LastName
Department

Bảng yêu cầu

RequestID (primary Key, indexed, no dupes)
<...> various data fields containing request details
UserID -- foreign key associated with User table

Đơn giản phải không?

Tư vấn đã thiết kế nó như thế này (với dữ liệu mẫu):

Người dùng

UserID  FirstName   LastName
234     John        Doe
516     Jane        Doe
123     Foo         Bar

Bộ phận

DepartmentID   Name
1              Sales
2              HR
3              IT

UserDepidorTable

UserDepartmentID   UserID   Department
1                  234      2
2                  516      2
3                  123      1

RequestTable

RequestID   UserID   <...>
1           516      blah
2           516      blah
3           234      blah

Toàn bộ cơ sở dữ liệu được xây dựng như thế này, với mỗi phần dữ liệu được gói gọn trong bảng riêng của nó, với ID số liên kết mọi thứ với nhau. Rõ ràng nhà tư vấn đã đọc về OLAP và muốn 'tốc độ tra cứu số nguyên'

Ông cũng có một số lượng lớn các thủ tục được lưu trữ để tham chiếu chéo tất cả các bảng này.

Đây có phải là thiết kế hợp lệ cho SQL DB cỡ nhỏ đến trung bình không?

Cảm ơn đã cho ý kiến ​​/ câu trả lời ...


12
Ôi trời, nếu điều này khiến bạn nói WTF, thì có lẽ bạn đã không thấy các bảng có hơn 200 cột và các thủ tục được lưu trữ dài hơn 1000 dòng.
Công việc

42
+1 vì không xóa sau khi cảm thấy lúng túng. Cảm ơn đã để lại điều này để những người khác có thể học hỏi.
Wayne Koorts

2
@Job - thực ra, tôi chưa - Tôi không phải là một DBA bằng thương mại (khá rõ ràng bây giờ! Lol), vì vậy ngưỡng SQL WTF của tôi khá thấp. Mặc dù, tôi hoàn toàn thiếu quan điểm về thiết kế của nhà tư vấn đã cho tôi khả năng của riêng mình. Bao giờ có một ngày mà bạn chỉ cảm thấy ngớ ngẩn ?
Jim

9
@Jim: Xin chúc mừng, bạn đã biến một ngày ngớ ngẩn thành một ngày giác ngộ .
Wayne Koorts

3
Nguyền rủa những chuyên gia tư vấn được trả lương cao!
ngủ tối

Câu trả lời:


73

Làm cho cảm giác hoàn hảo với tôi. Nó chỉ là rất bình thường, mà truyền tải rất nhiều tính linh hoạt mà bạn sẽ không có. Dữ liệu không chuẩn hóa là một cơn đau ở mông.


câu trả lời của bạn có ý nghĩa hoàn hảo, và nhìn qua câu hỏi của tôi và lược đồ có thể đó chỉ là số lượng bảng mà anh ấy đang sử dụng làm tôi bối rối. Tôi đã đơn giản hóa rất nhiều ví dụ cho câu hỏi của mình, nhưng tôi thấy khái niệm này nghe có vẻ như thế nào - anh ấy chỉ chia nhỏ mọi thứ nhiều hơn tôi có thể. Thở dài, tôi đoán đó là một điều tốt Tôi không phải là một DBA! :)
Jim

Học cách thiết kế theo quy tắc mười phút: "Điều gì đúng bây giờ có lẽ sẽ không còn trong mười phút nữa." Hãy chắc chắn rằng thiết kế của bạn có thể đối phó với sự thay đổi.
Blrfl

1
Lược đồ này thực sự có lợi thế là khi một nhân viên được chèn vào, bộ phận của họ phải tồn tại.
Simon Richter

@SimonRichter: Không đúng. Nhân viên có thể được tạo ra mà không có Bộ phận nào tồn tại, và ngược lại.
Daniel Dinnyes

@SimonRichter Lợi ích của thiết kế này là, thứ nhất, Bộ là một thực thể riêng biệt và thứ hai là có mối quan hệ nhiều-nhiều giữa Bộ và Nhân viên, trái ngược với ví dụ của OP, nơi nó là "nhiều- to-one-ish "(không thể nói nhiều thành một, vì không có thực thể riêng biệt nào mà nó được gọi là mối quan hệ).
Daniel Dinnyes

48

Tôi không nghĩ rằng một WTF được bảo hành hoặc anh chàng đó đang thực hiện bất kỳ kiểu thiết kế thiên tài điên rồ nào - đó là chuẩn hóa cơ sở dữ liệu khá chuẩn.

Lý do cho bảng bộ phận là nếu bạn không đặt các phòng ban vào một bảng riêng biệt, bạn sẽ phải giao dịch với người dùng trong các bộ phận "Bán hàng", "bán hàng", "Nhân viên bán hàng", "Bán hàng" và "Bán hàng", trừ khi bạn làm một cái gì đó để ngăn chặn nó. Và có thêm bảng là (một phần) cách tốt nhất tôi biết để làm điều đó.

Liệu có nên có một bảng UserDepidor là một cuộc gọi khó khăn hơn hay không, điều đó tất nhiên có nghĩa là không có quyết định nào là lối thoát và điên rồ. Một mặt, đó là một nỗi đau khi tất cả thiết kế bảng và logic của bạn đã đảm nhận một bộ phận cho mỗi người dùng và sau đó thay đổi, mặt khác thực hiện thêm một tham gia mà không có lý do trong nhiều năm và là một khả năng thực sự và cũng là một nỗi đau.

Cá nhân tôi đồng ý với bạn rằng bảng UserDepidor có lẽ là quá mức cần thiết. Ngay cả khi được bao gồm, nhiều khả năng mọi người sẽ viết các truy vấn giả định rằng chỉ có một người dùng cho mỗi bộ phận, do đó bạn sẽ kết thúc với điều tồi tệ nhất của cả hai thế giới - tham gia thêm mà không cần lý do trước khi cần bảng và mã không hoạt động dù sao một khi nhiều hơn một bộ phận cho mỗi người dùng được phép.

EDIT - Một yếu tố chính thúc đẩy việc có nên hỗ trợ nhiều mối quan hệ hay không là nếu các quy tắc kinh doanh rõ ràng. Nếu bạn không biết làm thế nào một người dùng trong nhiều phòng ban thậm chí sẽ làm việc thì sẽ không có nhiều điểm trong việc thêm bảng, vì mã của bạn không thể xử lý chính xác các trường hợp người dùng ở nhiều phòng ban.

Hãy tưởng tượng rằng bạn đã cho phép nhiều bộ phận trên mỗi người dùng, chỉ trong trường hợp. Sau đó, bạn đã thực hiện quy tắc kinh doanh để gán hoa hồng, dựa trên bộ phận. Sau đó, nhiều bộ phận đã được cho phép. May mắn thay, bạn cũng có tầm nhìn xa để viết mã hoa hồng của mình theo cách đã tính đến điều này. Thật không may, bạn đã thêm hoa hồng từ mỗi bộ phận cho người dùng ở cả hai. Quản lý muốn bạn dựa trên vai trò của mỗi người cho mỗi lần bán. Vì vậy, có bao nhiêu tốt đã có bảng trước? Còn những bảng khác mà bạn có "chỉ trong trường hợp" không bao giờ cần thiết thì sao?

LATER EDIT - Một lý do khác mà nhà tư vấn có thể muốn thêm tất cả các bảng trung gian được đề cập trong câu hỏi tiếp theo này , câu trả lời đưa ra một số lý do tại sao việc tái cấu trúc cơ sở dữ liệu thường khó hơn mã tái cấu trúc, điều này có xu hướng đẩy bạn về phía phương pháp "đặt trong tất cả các bảng bạn có thể cần".


Tôi nghĩ rằng bạn đã nói ra WTF của tôi là gì - anh chàng đang sử dụng TẤN của các bảng trực quan này, và nó có vẻ rất ngu ngốc đối với tôi. Bây giờ tôi đã chia nó thành một ví dụ nhỏ hơn nhiều cho câu hỏi này, tôi cảm thấy khá ngu ngốc khi đăng nó vì nó dường như không tệ.
Jim

5
Như bạn có thể thấy qua rất nhiều bình luận, có một sự hoài nghi lành mạnh về "sẽ chỉ có một X cho mỗi bình luận". Chuyên gia tư vấn đang tự bảo vệ mình khỏi các khiếu nại "tại sao chỉ có thể có một X mỗi Y". Một số trong đó có thể sẽ đi lên. Nhưng anh ta sẽ không chịu trách nhiệm duy trì mã có nhiều liên kết (không quá tệ, nhưng khó hơn) và điều đó phải đúng với các quy tắc kinh doanh chưa tồn tại (xấu) - hãy tưởng tượng câu hỏi "tại sao người dùng nhận được TẤT CẢ các quyền từ mỗi bộ phận, họ sẽ nhận được mức THẤP NHẤT của mỗi quyền "hoặc một số quyền như vậy.
psr

@psr Tôi nghĩ rằng có một lỗi đánh máy: không nên "truy vấn giả sử chỉ có một người dùng cho mỗi bộ phận" là "truy vấn giả sử người dùng chỉ ở một lần khởi hành"?
BiAiB

@BiAiB - bạn nói đúng, đó là điều tôi muốn nói.
psr

14

Nếu yêu cầu là có nhiều bộ phận cho mỗi người dùng, thiết kế này có ý nghĩa. Nắm bắt duy nhất về nó là UserDepartmentTablecó một khóa thay thế UserDepartmentIDkhông cần thiết (chỉ cần tạo UserIdDepartmentIdmột khóa chính tổng hợp).

Nếu người dùng chỉ thuộc về một bộ phận duy nhất, thiết kế của bạn có ý nghĩa (mặc dù bảng tra cứu bộ phận vẫn sẽ là một điều tốt).


18
... Cho đến khi có nhiều hơn một bộ phận cho mỗi người dùng.
Blrfl

1
Chính xác, @Blrfl. Hôm nay sẽ không bao giờ xảy ra là ngày mai CEO của CEO đang có một chứng phình động mạch-bởi vì nó không làm điều đó.
Adam Crossland

2
Một phần của việc quyết định những gì xứng đáng với cách đối xử đó là hiểu được vấn đề. Trong một số ứng dụng, điều quan trọng cần biết là nhân viên # 3804 đã được công ty biết đến với tên Ann Smith và Ann Jones (sau khi kết hôn), điều này sẽ khiến việc bình thường hóa tên của nhân viên trở thành một việc làm lành mạnh. Trong trường hợp của Jim, có thể đáng để mở rộng bảng ngắt để giữ lịch sử để nếu Ann chuyển từ HR sang IT, thực tế là một yêu cầu cũ gắn liền với cô ấy có thể phản ánh rằng đó thực sự là yêu cầu của HR chứ không phải IT.
Blrfl

8
YAGNI - cơ sở dữ liệu có thể được cấu trúc lại.
JeffO

2
@Oded, Một số trình ánh xạ ORM như Entity Framework không hoạt động tốt với các bảng có khóa chính tổng hợp.
maple_shaft

5

Một số yêu cầu không rõ ràng trong câu hỏi của bạn. Câu trả lời đúng phụ thuộc vào những gì khách hàng của bạn muốn - Nếu tôi là bạn, tôi sẽ hỏi khách hàng về điều này:

0-Sự khác biệt giữa người dùng và nhân viên là gì?

1-Giả sử một nhân viên = người dùng, nếu nhân viên thay đổi phòng ban thì sao?

2-Một nhóm nhân viên có thể đưa ra 1 yêu cầu không?

3-Một nhân viên có thể thuộc nhiều bộ phận không? CEO thì sao

4-Có tập hợp nhân viên nào được phép đưa ra yêu cầu không?

5-Điều gì xảy ra với yêu cầu khi hồ sơ nhân viên bị xóa (nếu có)?

6-Bạn có thể xóa một yêu cầu? Điều gì xảy ra khi yêu cầu bị hủy (đảm bảo bạn không xóa hồ sơ nhân viên bằng RI)

7-Nhân viên có thể thực hiện yêu cầu "giống nhau" nhiều lần không (xác định "giống")

8-Cách xử lý yêu cầu cho nhân viên khi họ rời công ty (hủy yêu cầu của họ hoặc xóa yêu cầu?)

Có thể có nhiều câu hỏi hơn, nhưng quan điểm của tôi là giải pháp phụ thuộc vào yêu cầu chính xác và phạm vi dự án. Khi đã được xác định, lược đồ có thể được dẫn xuất trực tiếp. Theo đó cả hai giải pháp được trình bày có thể đúng.


+1 đây là những câu hỏi lớn cần được làm rõ trước khi thiết kế loại lược đồ này. Tôi thích dòng logic của bạn.

@ Surfer513: Tôi đánh giá cao nhận xét tốt đẹp của bạn.
NoChance

1

Tôi muốn thêm một vài ghi chú dạng điểm nói chuyện rõ ràng về một số lợi thế tiềm năng của việc sử dụng bảng tham gia theo cách mà nhà tư vấn được trả lương cao của bạn đã làm.

  • Được lập chỉ mục chính xác (ví dụ: nếu UserDepidorTable lập chỉ mục hai khóa ngoại), chỉ có một sự mất hiệu suất nhỏ của bảng tham gia như thế này do các khóa ngoại không phải là duy nhất. Nếu các khóa ngoại được đảm bảo là duy nhất, theo lý thuyết cơ sở dữ liệu nhỏ mà tôi biết, việc tìm kiếm UserDepartmentTable.Departmentkhông "khó" hơn tìm kiếm bất kỳ cột nào khác trong Userbảng.
  • Bảng tham gia cho phép bạn linh hoạt hơn để thiết lập thông tin khác về sự liên kết giữa người dùng và bộ phận (ví dụ: dấu thời gian khi tạo).
  • Bảng tham gia cho phép bạn "phiên bản" liên kết khá dễ dàng (ví dụ: khi người dùng thay đổi các phòng ban, kích hoạt một số cờ boolean chỉ mục như UserDepartmentTable.Activesai và tạo một liên kết mới đang hoạt động). Cũng có thể có phiên bản liên kết bộ phận với mô hình hai bảng (chỉ Người dùng và Bộ), nhưng khó hơn và cần thêm ít nhất một cột hoặc thực hiện các thao tác nhào lộn cơ sở dữ liệu để tránh trùng lặp các khóa chính.
  • Nó cho phép bạn chỉ định liên kết một-nhiều hoặc nhiều-một hoặc nhiều-nhiều-khá dễ dàng.

Điều đó đang được nói, có một số lý do KHÔNG làm những gì mà nhà tư vấn được trả lương cao của bạn đã làm.

  • Tất cả những lợi ích trên đều là dự đoán về những nhu cầu có thể có trong tương lai, những điều quá phức tạp cho ngày nay. Nó không tuân thủ YAGNI. Sau này, việc viết một di chuyển chuyển từ mô hình hai bảng của bạn sang mô hình bảng tham gia là một khó khăn không đáng kể. Bạn có thể làm điều đó khi nhu cầu kinh doanh xuất hiện. Để làm điều đó trước đó có thể gây nhầm lẫn.
  • Nó gây nhầm lẫn cho các nhà phát triển khác. Mặc dù, vâng, tôi muốn nói rằng kỳ vọng cho một nhà phát triển web có tầm vóc của bạn (nơi bạn đang xem xét các quyết định của chuyên gia tư vấn) sẽ hiểu và nhận ra một bảng tham gia, nó vẫn phức tạp hơn mức cần thiết và xem xét việc thiếu nhu cầu kinh doanh, nó gây nhầm lẫn.

phân tích hay - tuy nhiên, tôi sẽ không nói rằng tôi có tầm vóc như một nhà phát triển trong công việc hàng ngày của mình, ngoại trừ tôi là người duy nhất ở đây biết bất cứ điều gì về db ​​/ c # / vb / vv ... vì vậy hãy đoán tôi là một phần thời gian dev theo mặc định. Đây là một dự án khá nhỏ, vì vậy các chuyên gia tư vấn số lượng bàn và tham gia đã để lại cho tôi nói "wtf" (nhưng nhờ có bạn dân gian tốt, giờ tôi đang nói "oic ...")
Jim

Khá là một chủ đề cũ, nhưng vẫn có liên quan ... tái cấu trúc có thể rất khó, hãy tưởng tượng bạn cần nhiều phòng ban trong tương lai thay vì một, nhưng chỉ có ID bộ phận trong Người dùng là FK. Bạn có thể sẽ kết thúc với các giới thiệu trùng lặp (Users.DeptID và UsersDepecesTable) hoặc rác hoàn chỉnh, như các danh sách được phân tách bằng dấu phẩy trong Users.DeptID hoặc XML. Không thể dễ dàng thêm giải pháp chính xác, như được đề xuất bởi YAGNI hoặc KISS, nhưng sẽ bị cản trở.
Erik Hart

0

Không có cấu trúc đầy đủ của thông tin cần thiết, tôi không thể nói nó có khủng khiếp hay không. Nhưng ít nhất phần được hiển thị không phải là thiết kế "WTF". Nó chỉ có vẻ như là dạng cấu trúc dữ liệu thông thường thứ 3 (vâng, về mặt lý thuyết chúng ta cũng có thứ 4 và thứ 5)

Một số cuộc thảo luận có thể có chỗ cho UserDepidorTable giữa hai trường khóa "tự nhiên" và "nhân tạo" trong phần hiển thị. Không có gì hơn, như tôi có thể thấy

Chuẩn hóa là quy tắc của nhà phát triển / nhà thiết kế DB giỏi vì nhiều lý do, * de * bình thường hóa đôi khi được sử dụng ở giữa các phát triển để giành chiến thắng tốc độ

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.