【问题标题】:Logic in the db for maintaining a points system relationship?数据库中用于维护积分系统关系的逻辑?
【发布时间】:2010-05-09 00:19:28
【问题描述】:

我正在制作一个基于 Web 的小游戏,需要确定将检查 sql 数据库中某些基础数据完整性的逻辑放置在何处。

每个用户都会跟踪分配给他的积分,并通过各种任务奖励积分。我会记录每个任务交易以确保它们不会重复,并在完成时跟踪任务的价值,因为个人奖励水平会随着时间的推移而波动。

到目前为止,我的架构如下所示:

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 的触发器?数据库中的逻辑是否太多,应该只在应用程序中维护这种关系?

谢谢。

【问题讨论】:

    标签: sql database schema


    【解决方案1】:

    从关系的角度来看,您希望完全取消 player.player_Points,这样您就不必担心数据的完整性。如果这对性能造成太大负担,那么您可以像以前一样对其进行非规范化,但我会对应用程序进行一些压力测试以确保是这种情况,无需过早优化,并且它是一个非常简单的查询值(不仅在逻辑上,而且从数据库工作负载的角度来看也是如此)。

    就个人而言,即使您采用非规范化路线,我也不会使用触发器,但这只是个人偏见,您当然可以走那条路线。我可能只是设置了一些集成测试,以确保在您执行插入/更新/删除时一切都正确更新,并可能保存一个查询,如果您怀疑有问题,您可以定期运行。

    我还考虑在任务上添加一个日期范围,这样您就不必将 points_value 存储在 task_list 中。

    【讨论】:

      【解决方案2】:

      其实触发建议是最好的。这正是任务触发器最适合的类型(您也可以使用触发器或约束来检查应用程序计算的总数,但它的工作量是相同的,所以为什么还要麻烦将计算工作添加到应用程序中呢?)。

      【讨论】:

        猜你喜欢
        • 2015-12-18
        • 2016-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-24
        相关资源
        最近更新 更多