2010-05-08 78 views
1

我正在做一個基於網絡的小遊戲,需要確定將sql數據庫中某些基礎數據的完整性檢查的邏輯放在哪裏。db中用於維護點系統關係的邏輯?

每個用戶都記錄分配給他的點數,點數由各種任務授予。我會記錄每項任務交易以確保它們不會重複,並在完成時跟蹤任務的價值,因爲我的個人獎勵級別隨時間波動。

我的模式是這樣的,到目前爲止:

create table player (
    player_ID   serial primary key, 
    player_Points  int not null default 0 
); 

create table task (
    task_ID    serial primary key, 
    task_PointsAwarded int not null 
); 

create table task_list (
    player_ID   int references player(player_ID), 
    task_ID    int references task(task_ID), 
    when_completed  timestamp default current_timestamp, 
    point_value   int not null, --not fk because task value may change later 
    constraint pk_player_task_id primary key (player_ID, task_ID) 
); 

因此,player.player_Points應該總在task_list他的所有累積的任務點。
現在我在哪裏把邏輯強制執行?
我應該完全消除player.player_Points,每次我想知道總分時都會查詢嗎?這看起來很浪費,因爲我會在遊戲過程中做很多的查詢。

或者,在task_list中加上一個觸發器即自動更新player.player_Points?數據庫中是否有過多的邏輯,應該在應用程序中維護這種關係?

謝謝。

回答

0

從關係角度來看,您希望完全避免使用player.player_Points,這樣您就不必擔心數據的完整性。如果這是太多的性能負擔,那麼你可以非規範化它,但是我會在應用上做一些壓力測試以確保是這種情況,不需要過早地進行優化,並且它是一個非常簡單的查詢來獲取值(不僅僅是邏輯上的,而且也來自數據庫工作負載的角度)。

就個人而言,即使你走非規範化的路線我不會使用觸發器,但這只是個人偏見,你當然可以走這條路。我可能只是設置了一些集成測試,以確保每當執行插入/更新/刪除時都能正確更新所有內容,並且如果懷疑存在問題,可能會保存一個定期運行的查詢。

我也會考慮在任務中添加一個日期範圍,以便您不必將points_value存儲在task_list中。

0

其實觸發建議是最好的。這正是觸發器非常適合的任務類型(您也可以使用觸發器或約束來檢查應用程序計算的總計,但工作量相同,所以爲什麼要將計算工作添加到應用程序?)。