MySQL触发,查看,单独表格或忠诚点的即时计算?

时间:2016-08-12 08:14:17

标签: mysql database-design view triggers

从两个表中计算点总和的资源最少的方法是什么?通过在表points中添加点并从表points_redeemed中减去点来计算总点计数。

points

CREATE TABLE IF NOT EXISTS points(
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    user__id INT,
    tx__id INT,
    points INT
) ENGINE=MyISAM;

points_redeemed

CREATE TABLE IF NOT EXISTS points_redeemed(
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    user__id INT,
    points INT
) ENGINE=MyISAM;

(上面的两个表都大大简化了。)

在事务中填充

points(记录在不同的表中)。当事务值更改或无效时,points中的相应行也会更新。

当用户兑换积分以获得奖励时,

points_redeemed会被填充。

用例:

  • 向用户和管理员显示统计信息:总计,已兑换和未兑换积分
  • 根据用户启动的兑换请求检查未兑换的积分

我提出的选项是:

a)触发器。 创建一个表points_sum,每个user.id有一行,并添加三个触发器:

  • 插入points
  • 更新points
  • 插入points_redeemed

我听说MySQL触发器不是那么高效,所以我不确定这是不是一个好主意。

b)查看。 创建一个计算points.points - points_redeemed.points的视图。不确定这是否比在飞行中更好。

c)总和表。 创建一个表points_sum,并在每次插入和更新pointspoints_redeemed时按照单独的查询对其进行更新。这感觉就像是效率最低的方式,但是我又错了,这可能是最好的方式。

d)即时。 快速查询两个表中的点并计算差异。这是最简单,也可能是最准确的方法,但是当表格大小增加时,它可能会堵塞管道。那么,在这方面,还有其他任何选择吗?

修改:这些是当前即时查询。

首先,来自points_redeemed的非常直接的查询:

SELECT  *
FROM    points_redeemed
WHERE   user__id = 1

其次,查询points表:

(
SELECT  p.*,
        tx.*

FROM    points p
        INNER JOIN tx ON p.tx__id = tx.id

WHERE   p.user__id = '1'
  AND   p.tx_is_external IS NULL

ORDER BY p.date DESC
)

UNION

(
SELECT  p.*,
        tx.*

FROM    points p
        INNER JOIN tx_external tx ON p.tx__id = tx.id

WHERE   p.user__id = '1'
  AND   p.tx_is_external = '1'

ORDER BY p.date DESC
)

(有几个名为SELECT的列,我在这里被删除了。在第二个查询中,每行提取大约40列。)

在此之后,我循环遍历两个结果集并在应用层上添加/减去点。

我担心的是,两个单独的查询以及第二个查询中的连接可能会堵塞管道"当tx表的大小增加时(以及点表)。这就是为什么我试图想出一种更好的方法来节省资源。

我考虑的越多......交易和积分插入可能比查找当前点状态的用户更频繁地发生。在那种情况下,触发器可能会产生相反的效果。

我很欣赏任何形式的见解。谢谢!

1 个答案:

答案 0 :(得分:0)

  • WHERE user__id = 1需要INDEX(user__id)在桌面上。
  • ( SELECT ... ORDER BY ... ) UNION ( SELECT ... ORDER BY ... )没有特定的订单;你需要移动ORDER BY外面吗?
  • txtx_external需要id才能编入索引(PRIMARY KEY?)
  • 你真的想要UNION DISTINCT吗?这是默认值。 UNION ALL更快。

修复这些,然后看看你是否还需要讨论触发器等。