我正在构建一个包含许多列的数据库系统,这些列之间具有数学关系。例如(这是我编写的国际象棋游戏存储示例),一列称为“num_pawns”,一列称为“num_nights”,一列称为“num_castles”,一列称为“piece_score”。 piece_score中的值由以下公式确定:1 *(num_pawns)+ 3 *(num_knights)+ 5 *(num_castles)。我想知道如何设置一个规则,每当更新其他列之一时重新计算piece_score的值。例如,在第1行中,前三列的相应值为{6,2,1},并且骑士被移除{6,1,1},piece_score的值应在值之后自动从17更新为14。 num_knights列已更新。我意识到在PHP或C中执行此操作可能更有效,但我将数据库模型设计为可移植的。它可以在具有MySQL和PHP的服务器上,也可以在具有SQLite和Java的移动设备上。有没有办法使用严格的SQL来完成这些类型的查询后更新?
更新:
为了澄清和阐述上面的例子,想象另外两列:score_rank和skill_level。上述计算的原因是,每行可以基于其得分与其他行相比在score_rank中分配值(最高得分为1,第二得到2等)。在分配排名后,前5个分数在skill_level中被赋值为1,分数6-10被赋予值2,11-15被赋予3,等等。这在SQL中是否可以进行比较和排序?我猜测触发器是正确的方法,但是如何在UPDATE之后执行整个表的排序和分配?正如我所提到的,这个数据库需要是可移植的和自包含的,因此理想情况下,应该在数据库中维护排序和排序抽象。这样就可以根据score_rank列或skill_level列进行查询,并假设这些值反映了表的当前状态。
答案 0 :(得分:2)
除非你有一个非常非常大的表(想想几十万或几百万行),否则你可能希望将它作为一个视图而不是同步这些值。视图将是这样的:
CREATE VIEW v
AS
SELECT t.*,
( num_paws * 1 + 3 * num_knights + 5 * num_castles ) AS piece_score
FROM table t;
要将此作为单独的列执行,需要编写触发器来处理每行中的插入,更新和删除。更容易在需要时计算价值。并且,鉴于所有值都在一行上,将值存储在另一列中并使用触发器使其保持最新没有性能优势。
答案 1 :(得分:0)
事实证明,触发器是解决我问题的最现实的解决方案。可以使用
获取某一行的score_rankSELECT (SELECT COUNT(*) FROM table_name AS p2 WHERE p2.num_pawns + 3*p2.num_knights + 5*num_castles > p1.num_pawns + 3*p2.num_knights + 5*num_castles) FROM table_name AS p1 where p1.rowid=x); where x is a rowid
类似地,技能水平可以通过除以5来计算。这可能是理想的方法,因为它更符合DRB的理论基础。但是,如果以这种方式计算多个列,则每次需要时都会重新计算相同的值,这会在添加更多列时浪费时间。因此,我决定使用一个触发器,在所有必要的列被填充后更新score_rank,然后另一个触发器在score_rank填充后仅仅通过将score_rank除以5等来更新skill_level。这减少了冗余计算。