开发者

Logic in the db for maintaining a points system relationship?

I'm making a little web based game and need to determine where to put logic that checks the integrity of some underlying data in the sql database.

Each user keeps track of points assigned to him, and points are awarded by various tasks. I keep a record of each task transaction to make sure they're not repeated, and to keep track of the value of the task at the time of completion, since an individual award level my fluctuate over time.

My schema looks like this so far:

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)
);

So, the player.player_Points should be the total of all his cumulative task points in the task_list.

Now where do I put the logic to enforce this?

Should I do away with player.player_Points altogether and do queries every time I want to know the total score? Which seems wasteful since I'll 开发者_JS百科be doing that query a lot over the course of a game.

Or, put a trigger in the task_list that automatically updates the player.player_Points? Is that too much logic to have in the database and should just maintain this relationship in the application?

Thanks.


From a relational standpoint you'd want to do away with player.player_Points altogether so that you don't have to worry about the integrity of the data. If this is too much of a performance burden then you could denormalize it as you have, but I'd do some stress testing on the app to make sure this is the case, no need to prematurely optimize and its a pretty simple query to get the value (not just logically but from a database workload perspective as well).

Personally even if you go with the denormalized route I would not use a trigger, but that's just a personal bias, you certainly could go that route. I'd probably just set up some integration tests to make sure everything is updating properly whenever you perform inserts/updates/deletes, and possibly save a query that you can run periodically if you suspect there is a problem.

I'd also consider adding a daterange on task so that you don't have to store the points_value in the task_list.


Actually the trigger suggestion is the best. That's exactly the kind of task triggers are ideally suited to (you can also use a trigger or constraint to check the totals computed by the app, but it's the same amount of work so why bother adding the computation work to the app?).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜