bảng đơn có thêm cột so với nhiều bảng trùng lặp lược đồ


13

Tôi đang làm việc trên một dự án, tại một thời điểm nào đó, tôi cần đưa ra quyết định về việc có hay không, trong cơ sở dữ liệu, tôi nên có một bảng duy nhất có nhiều cột mà không phải bản ghi nào cũng sử dụng hoặc nhiều bảng có lược đồ trùng lặp.

Tôi đang tạo một ứng dụng thông tin Thể thao có thể xử lý nhiều môn thể thao. Chúng ta có thể xử lý NBA, NHL, MLB, NFL chẳng hạn. Mỗi môn thể thao có các khái niệm rất giống nhau - Đội, Lịch thi đấu, Chấn thương, Thông tin người chơi ..

Tất nhiên nguồn dữ liệu của chúng tôi không cung cấp cho chúng tôi từng phần dữ liệu trong cùng một lược đồ. Mỗi môn thể thao có một Lược đồ khác nhau mà chúng tôi nhận được dữ liệu từ nhà cung cấp của chúng tôi.

Vì không có đủ thời gian (nhu cầu của khách hàng) để phân tích trước các nguồn cấp dữ liệu để xác định điểm chung, tôi đã đặt cược và lấy 'đặt cược an toàn' và tạo các bảng riêng biệt cho mỗi môn thể thao thay vì một bộ tất cả các bảng thể thao sử dụng.

Kết quả là lược đồ trùng lặp trong một số bảng và do đó, giao diện trùng lặp với cơ sở dữ liệu (ví dụ: procs lưu trữ) là tốt. Tôi có một cái gì đó như NBA_Game, NFL_Game, NBA_Team, NFL_Team, v.v. mỗi bảng có thể có một vài thuộc tính mà bảng kia không có, và một số thuộc tính được chia sẻ. nó tiếp tục cho biết 5-10 bàn trên 4 hoặc 5 môn thể thao. Tôi vẫn không chắc chắn liệu đây có phải là một điều xấu hay không - sự thay thế, có một bộ bàn duy nhất có các thuộc tính mà không phải môn thể thao nào cũng sử dụng, cũng có thể khó sử dụng.

Có ai đã làm điều này chạy vào cạm bẫy của loại thiết kế này và có thể chia sẻ kinh nghiệm của họ ở đây? Những điều có thể giúp tôi biết bây giờ thay vì học một cách khó khăn trên đường? Bạn đã làm theo cách khác, có một bảng / bộ bảng lớn, với các cột mà không phải bản ghi nào cũng sử dụng? Những cạm bẫy nào bạn đã chạy vào làm điều đó?

Có một số thay thế như kế thừa bảng mà bạn đã sử dụng trong quá khứ làm việc tốt hơn?

Cảm ơn

Câu trả lời:


12

Cuối cùng, nó đi xuống để sử dụng và kiến ​​trúc.

Ngành kiến ​​trúc

Hệ thống có xử lý "môn thể thao nào" không? Có phải ý tưởng mà bạn đội chiếc mũ phi hành gia kiến ​​trúc của bạn, và xây dựng một hệ thống chung có thể xử lý bất kỳ loại thể thao nào trong tương lai thậm chí không tồn tại ngày nay?

Nếu vậy, rõ ràng việc có các bảng được đặt tên động là một nỗi đau rất lớn, do đó, sẽ có ý nghĩa khi có một lược đồ hỗ trợ n môn thể thao, nếu cần.

Điều đó nói rằng, tôi có một thành kiến ​​rất mạnh mẽ đối với phương pháp này: điều này hầu như luôn luôn làm việc nhiều hơn và dẫn đến kết quả kém hơn. Tạo một UI, lược đồ, v.v., cho mỗi môn thể thao cuối cùng sẽ dẫn đến trải nghiệm người dùng tốt hơn và dễ duy trì mã hơn, ngay cả khi điều đó có nghĩa là một số lượng trùng lặp hời hợt (làm thế nào để tránh / giảm thiểu đây là một câu hỏi riêng biệt).

Làm thế nào để bạn xử lý những người chơi chơi nhiều môn thể thao? Họ có nhận được hai mục (ví dụ: bạn đối xử như những người khác nhau) hoặc bạn đang cố gắng làm điều gì đó cụ thể với họ?

Sử dụng

Vì vậy, giả sử bạn không chơi thể thao một cách linh hoạt (ví dụ: nếu ai đó muốn thêm một môn thể thao mới, nó đòi hỏi nỗ lực phát triển để thêm nó).

Có khi nào bạn hiển thị người chơi (hoặc bất kỳ đối tượng nào khác mà bạn đã đề cập) từ nhiều môn thể thao cùng một lúc không?

Tôi có thể thấy điều này cho chức năng tìm kiếm, nơi bạn có thể tìm kiếm theo tên người chơi hoặc tên đội (bất kể môn thể thao nào), nhưng ngoài ra tôi không thể tưởng tượng được nhiều trường hợp sử dụng.

Nếu bạn không bao giờ cần phải làm điều này, thì cách tiếp cận của bạn là hoàn toàn tốt. Bạn có thể dừng đọc ở đây.

Lược đồ thay thế

Lượt xem

Tôi là một fan hâm mộ của KISS. Trong hơn 15 năm phát triển phần mềm, tôi tiếp tục quay trở lại với triết lý "xây dựng điều đơn giản nhất có hiệu quả".

Vì vậy, phản ứng ban đầu của tôi, giả sử chức năng tìm kiếm đa môn thể thao thực sự là trường hợp sử dụng duy nhất, là tạo ra các lượt xem:

SELECT PlayerName, 'NFL' as [Sport], TeamName FROM NFL_Players JOIN NFL_Teams ... 
UNION  
SELECT PlayerName, 'NHL' as [Sport], TeamName FROM NHL_Players JOIN NHL_Teams ... 
UNION ....

Tất nhiên, nếu bạn thêm một môn thể thao mới, bạn phải thêm vào chế độ xem. Nó cũng có thể hữu ích để bao gồm các thông tin phổ biến khác nhưng thực sự phụ thuộc vào những gì cần được hiển thị.

Tôi sẽ cố gắng giữ tất cả nội dung dành riêng cho thể thao trong định nghĩa Chế độ xem, vì vậy mã tìm kiếm không cần phải có nhiều hoặc bất kỳ mã cụ thể nào (ngoài việc có thể biết cách liên kết với /nhl/players/player-namevs /nfl/...hoặc tuy nhiên ứng dụng của bạn làm điều đó).

Bảng kế thừa

Kế thừa bảng có thể làm việc, nhưng khá phức tạp. Tôi không có nhiều kinh nghiệm với nó và trên thực tế, tôi nghĩ rằng mỗi lần tôi tham gia vào việc đánh giá nó, chúng tôi lại làm một việc đơn giản hơn (như tôi đang gợi ý ở đây).

Vì vậy, cá nhân tôi vẫn chưa tìm thấy lý do tại sao điều này sẽ hữu ích, nhưng có lẽ có một trường hợp sử dụng thuyết phục (mà tôi không biết) chứng minh sự phức tạp (ví dụ, kế thừa Bảng giải quyết trường hợp sử dụng tốt hơn bất kỳ giải pháp nào khác) .

Các bảng riêng biệt cho các thuộc tính dành riêng cho thể thao

Bạn có thể thực hiện một playersbảng duy nhất có các thuộc tính chung cho tất cả người chơi của tất cả các môn thể thao và sau đó một nhóm bảng nhl_players_detailskhác có chứa một playerId và các cột có thông tin bổ sung về người chơi. Nếu có rất nhiều thuộc tính phổ biến hoặc bạn có nhiều cách sử dụng "tất cả người chơi từ tất cả các môn thể thao" thì điều này có thể có ý nghĩa.

Các cặp giá trị chính cho các thuộc tính dành riêng cho thể thao

Cách tiếp cận hoàn toàn khác: có một playersbảng (một lần nữa, với các thuộc tính thông thường như tên) và sau đó một player_databảng mà có PlayerId, Sport, Attribute, Value. Tên thuộc tính được nhập sẽ là đặc trưng cho thể thao. Điều này cho phép bạn về cơ bản thêm các thuộc tính mới mà không cần sửa đổi lược đồ (mã của bạn vẫn phải biết để tải / hiển thị chúng tất nhiên). Hạn chế là bạn mất một số tính toàn vẹn: giá trị thường là trường chuỗi, vì vậy mã ứng dụng của bạn sẽ phải linh hoạt và xử lý các lỗi tiềm ẩn khi chuyển chuỗi valuethành loại dữ liệu cụ thể (như số nguyên).

Khái niệm này tất nhiên có thể áp dụng cho Đội, Trò chơi, v.v.


Tìm kiếm một giải pháp cho một dự án cũ sẽ có nhiều loại và bảng xác thực, đề cập đến các khung nhìn ở đây, mà tôi đã quên, đã thực sự giúp đưa ra một giải pháp khả thi khác cho nghiên cứu của tôi. Cảm ơn bạn.
FullStackFool

5

Bạn đang nói về bình thường hóa cơ sở dữ liệu . Bạn có thể cảm thấy nhẹ nhõm khi biết rằng không có thứ gọi là mô hình dữ liệu hoàn hảo và việc chuẩn hóa nhiều hơn không phải lúc nào cũng tốt hơn. Chuẩn hóa có thể áp đặt chi phí về mặt rõ ràng của mô hình dữ liệu và hiệu suất cơ sở dữ liệu. Do đó, mô hình tốt nhất để chọn sẽ phụ thuộc vào yêu cầu sử dụng của bạn.

Nhìn bề ngoài, các ví dụ của bạn có vẻ tương tự nhau về khái niệm (X_Game vs Y_Game và X_Team vs Y_Team) rằng chi phí hoạt động thêm của một vài cột có vẻ không hợp lý. Điều đó nói rằng, nếu mỗi môn thể thao sẽ thêm vài chục cột bổ sung vào bảng, nó thực sự sẽ khó sử dụng.

Trong trường hợp đó, bạn có thể muốn xem xét một mô hình lai, trong đó dữ liệu chung được giữ trong một bảng trung tâm, nhưng dữ liệu dành riêng cho thể thao được giữ trong cấu trúc dữ liệu được liên kết. Cái gì đó như:

table Game {
    gameId int,
    teamId1 int fk,
    teamId2 int fk
}

table HockeyGame {
    gameId int fk,
    penaltyMinutes int
}

table BasketballGame {
    gameId int fk,
    freeThrows int
}

Đây là những gì tôi sẽ đề xuất, cộng với có lẽ một cột trong bảng Trò chơi cho biết loại trò chơi. Tôi nhận ra rằng nó có thể được suy luận bằng cách tham gia vào các bảng khác, nhưng nếu số lượng loại trò chơi tăng lên, điều đó bắt đầu trở nên tẻ nhạt.
Rory Hunter

Hoàn toàn - đây chỉ là một mô hình bộ xương để minh họa các mối quan hệ cốt lõi và một số ví dụ về những gì có thể là dữ liệu phổ biến so với dữ liệu cụ thể về thể thao.
Midnotion
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.