處理二次計算數據的模式/結構
我正在嘗試為我的彈球聯盟設計一個基於 LAMP 的網站,該聯盟每週都會在比洞賽中進行競技彈球比賽。
我們聯賽的特點之一是我們將原始分數轉換為賽點。例如,假設有四個玩家進行一場比賽,他們的分數是:
- 14,325,320
- 35,332,110
- 34,003,990
- 11,345,920
那麼他們的匹配點將分別為 2、4、3、1。
有時我們可能想要一個更複雜的匹配點算法,它可能基於原始分數的屬性(例如,如果最高分數優於所有其他分數的總和,則獎勵一個額外的匹配點)。
顯然,無論我使用什麼數據庫模式,我都希望它不僅可以儲存原始分數,還可以輕鬆顯示與該分數相關的匹配點。
我感到困惑的是計算這些匹配點的最佳位置。我是不是該:
- 每次將原始分數輸入數據庫時設置一個 SQL 觸發器,然後有一些複雜的邏輯來確定是否應該計算匹配點,然後根據需要修改行?我不確定 SQL 是否一定可以輕鬆處理我們的匹配點算法。
- 根本不將匹配點儲存在數據庫中,而是在每次請求時動態計算它們?這似乎是對計算能力的浪費。
- 在 SQL 中有一個計劃的事件,或者在伺服器上有一個 cron 作業,它通過數據庫併計算匹配點,然後根據需要將該數據添加到數據庫中?這似乎具有需要等待該計算發生的缺點。
現在我能想到的最好的方法是 2 和 3 的混合,在比賽期間不儲存比賽點,而是即時計算,然後在每週比賽結束時有一個人為觸發器計算所有匹配點並將它們放入數據庫中。可能的錯誤可能是我必須小心重用相同的程式碼,否則數據庫分數可能與臨時分數不同。此外,在人為錯誤的情況下,觸發器可能不會被拋出。
似乎我不可能是唯一需要一些自動化業務邏輯來解析數據庫條目,然後顯示它們的人。從某種意義上說,理想的結果應該類似於 SQL 視圖,但我可以在其中添加自己的邏輯。我不知道是否存在類似的東西。
有沒有更好的想法?
我認為根據您的要求,選項 2 的衍生產品將是理想的,這些要求似乎僅用於展示而不是進一步計算。
您在數據庫中查詢 match 的所有分數,
X
並將它們從高到低排序。然後在 Web 應用程序的表示層中,只需將排名數字分配添加到它們,從1
第一行開始,然後n+1
從結果集中獲取的每一行。查詢可能是
SELECT name, score FROM matches WHERE matchId = 'X' ORDER BY score DESC
在決定之前,您需要考慮一些事情:
- 我們在談論多少行?
- 整個表有多少個
- 有多少是同一錦標賽的一部分(假設您將在此表中有多個錦標賽,並且每個錦標賽都會分配積分)
- 每場比賽增加了多少參賽作品?
如果您將匹配點儲存在表中,這將告訴我們有多少“更新”操作會命中該表。 3. 人們將查看這些條目多少次?
這將告訴我們如果使用 View 隱藏計算,或者將計算保留在應用層而不是儲存在此表中,我們將計算多少次即時匹配點。
如果您將插入 100 次,但人們會每隔幾秒鐘查看(即計算)錦標賽的執行(想想人們不斷重新載入以查看他們的排名是否隨著新條目的添加而改變),這可能是數千或數以萬計的重複計算,那麼儲存起來似乎更好。
這聽起來也像是計算是數據驅動的,至少到目前為止的兩個例子是。在這種情況下,您可以擁有一個要保存的欄位和一個接受並重新計算該欄位
match_points
的儲存過程。該儲存過程可以由 INSERT 觸發器啟動*,並且*可以手動執行(在更改公式的情況下)。更新觸發器,假設它可以告訴您該欄位是否是已更新的欄位,則可以為已更改其欄位的行再次執行儲存過程。tournament_id``match_points``WHERE tournament_id = @tournament_id``match_points``tournament_id``match_points
當然,如果您確實有真正複雜的規則,那麼最好從應用程序中進行更新,但公式有多複雜?到目前為止提到的兩個實際上在數據庫中完成得更好/更快(假設 MySQL 可以執行
RANK
視窗功能)。