2009-05-07 34 views
5

Tôi đang tìm cách thiết kế cơ sở dữ liệu cho một trang web nơi người dùng sẽ có thể đạt được điểm (danh tiếng) để thực hiện các hoạt động nhất định và đang đấu tranh với thiết kế cơ sở dữ liệu.Cách tốt nhất để lưu trữ/tính toán điểm số của người dùng là gì?

Tôi dự định lưu hồ sơ về những điều người dùng làm để họ có thể có 25 điểm cho một mục họ đã gửi, 1 điểm cho 30 nhận xét họ đã tạo và 10 điểm thưởng khác để trở nên tuyệt vời!

Rõ ràng tất cả dữ liệu sẽ ở đó, nhưng có vẻ như rất nhiều hoặc truy vấn để nhận tổng số điểm cho mỗi người dùng mà tôi muốn hiển thị bên cạnh tên người dùng của họ (ở dạng một cấp). Ví dụ: truy vấn vào bảng mục đã gửi để nhận điểm cho mỗi mục từ người dùng đó, truy vấn vào bảng nhận xét, v.v. Nếu tất cả điều này cần được thực hiện cho mỗi người dùng được đề cập trên một trang .... !

Tôi đã cân nhắc việc giữ một số điểm trong bảng người dùng, có vẻ nhanh hơn rất nhiều để tìm kiếm, nhưng tôi đã ghi nhớ rằng lưu trữ dữ liệu có thể được tính từ dữ liệu khác là BAD!

Tôi đã nhìn thấy rất nhiều trang web làm những việc tương tự (thậm chí tràn ngăn xếp cũng tương tự) vì vậy tôi nghĩ phải có "thực hành tốt nhất" để làm theo. Bất cứ ai có thể đề xuất những gì nó có thể được?

Mọi đề xuất hoặc nhận xét sẽ tuyệt vời. Cảm ơn!

Trả lời

3

Tôi nghĩ rằng đây chắc chắn là một câu hỏi hay. Tôi đã phải xây dựng các hệ thống có hành vi tương tự với điều này - đặc biệt khi bảng với điểm số trong nó được truy cập khá thường xuyên (như trong kịch bản của bạn).Dưới đây là gợi ý của tôi với bạn:

Đầu tiên, tạo một số bảng như sau (tôi đang sử dụng thực hành tốt nhất SQL Server, nhưng tên họ tuy nhiên bạn thấy phù hợp):

UserAccount   UserAchievement 
-Guid (PK)   -Guid (PK) 
-FirstName   -UserAccountGuid (FK) 
-LastName   -Name 
-EmailAddress  -Score 

Một khi bạn đã làm điều này , hãy tiếp tục và tạo chế độ xem trông giống như sau (không, tôi chưa xác minh SQL này, nhưng nó phải là một khởi đầu tốt):

SELECT [UserAccount].[FirstName]  AS FirstName, 
     [UserAccount].[LastName]  AS LastName, 
     SUM([UserAchievement].[Score]) AS TotalPoints 
FROM [UserAccount] 
INNER JOIN [UserAchievement] 
    ON [UserAccount].[Guid] = [UserAchievement].[UserAccountGuid] 
GROUP BY [UserAccount].[FirstName], 
     [UserAccount].[LastName] 
ORDER BY [UserAccount].[LastName] ASC 

Tôi biết bạn đã đề cập đến một số lo ngại về hiệu suất và rất nhiều truy vấn, nhưng nếu bạn xây dựng một cái nhìn như thế này, bạn sẽ không bao giờ cần m quặng hơn một. Tôi khuyên bạn không nên làm cho một cái nhìn vật chất hóa; thay vào đó, chỉ cần lập chỉ mục các bảng của bạn để các tra cứu mà bạn cần (về cơ bản, UserAccountGuid) sẽ cho phép tổng kết nhanh trên bảng.

Tôi sẽ thêm một điểm nữa - nếu bảng UserAccount của bạn trở nên rất lớn, bạn có thể xem xét truy vấn thông minh hơn một chút sẽ kết hợp tên của tài khoản bạn cần để nhận danh sách. Điều này sẽ làm cho nó có thể không trả lại tập dữ liệu khổng lồ cho trang web của bạn khi bạn chỉ hiển thị, bạn biết đấy, thông tin của 3-10 người dùng trên trang. Tôi phải suy nghĩ thêm một chút về cách làm điều này một cách tao nhã, nhưng tôi khuyên bạn nên tránh xa các câu lệnh "IN" vì điều này sẽ gọi một tìm kiếm tuyến tính của bảng.

1

Đối với tỷ lệ đọc/ghi rất cao, việc bình thường hóa là một tùy chọn rất hợp lệ. Bạn có thể sử dụng chế độ xem được lập chỉ mục và dữ liệu sẽ được giữ đồng bộ theo kiểu khai báo (vì vậy bạn không bao giờ phải lo lắng về việc có dữ liệu điểm số kém). Nhược điểm là nó được giữ đồng bộ .. vì vậy các bản cập nhật cho tổng số cửa hàng là một khía cạnh đồng bộ của cam kết hành động điểm số. Điều này thường sẽ khá nhanh, nhưng đó là một quyết định thiết kế. Nếu bạn không chuẩn hóa bản thân, bạn có thể chọn nếu bạn muốn có một số loại hệ thống cập nhật bị trì hoãn.

Cá nhân tôi sẽ đi với một chế độ xem được lập chỉ mục để bắt đầu, và sau đó bạn có thể thay thế nó khá liền mạch với một bảng cụ thể nếu nhu cầu của bạn ra lệnh.

+0

Xin lỗi, tôi câm - không nhận thấy khía cạnh mysql. Tôi không nghĩ rằng đã có chỉ số xem được nêu ra. Các thay thế bình thường để buộc nó để giữ đồng bộ là để thiết lập kích hoạt. – ahains

+0

Kích hoạt khiến bé khóc khóc. Vâng, họ làm cho tôi khóc, anyway. Ngay cả khi nó không được lập chỉ mục, một khung nhìn là bạn của bạn ở đây. – Adrien

0

Trong quá khứ, chúng tôi luôn sử dụng một số công việc cron hàng đêm hoặc perodic để tính toán điểm hiện tại và lưu nó vào cơ sở dữ liệu - giống như dạng xem liên tục của SUM trên bảng hoạt động. Giống như hầu hết "thực hành tốt nhất" họ chỉ đơn giản là hướng dẫn và nó thường tốt hơn và thực tế hơn để đi chệch khỏi một thực hành mũi nhọn cứng cụ thể trên các lĩnh vực rất cụ thể.

Ngoài ra, nó không thực sự là một sự sai lệch nếu bạn sử dụng công việc cron vì nó được xem tốt hơn như một bộ nhớ đệm được lưu trữ trong cơ sở dữ liệu.

0

Nếu bạn có bảng điểm riêng biệt, bạn có thể cập nhật nó mỗi lần một mục được gửi hoặc nhận xét do người dùng đăng. Bạn có thể thực hiện việc này bằng cách sử dụng trình kích hoạt hoặc trong mã trang web.

Điểm của người dùng sẽ được cập nhật liên tục và có thể được truy vấn nhanh để hiển thị.

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