0

如果术语 m:n 不正确,我很抱歉,如果您知道更好的术语,我会更正。我有以下情况,这是我的原始数据:

gameID
participID
result

数据本身看起来像这样

1     5      10
1     4     -10
2     5     150
2     2    -100
2     1     -50

当我提取这个表时,它很容易有大约 100mio 行和大约 1mio participIDs 或更多。

我需要:

show me all results of all games from participant x, where participant y was present

幸运的是,仅适用于非常有限的参与者,但这些可能会发生变化,所以我需要一张完整的表格,并且可以在第二步中减少。

我的想法如下,它看起来非常未优化

1)获取包含“观点参与者”的游戏列表”

insert into consolidatedtable (gameid, participid, result)
    select gameID,participID,sum(result) from mastertable where participID=x and result<>0

2) 获取包含其他参与者的所有游戏

insert into consolidatedtable (gameid, participid, result)
where gameID in (select gameID from consolidatedtable)
AND participID=y and result<>0

3) 从合并表中删除 count<2 的所有游戏

delete from consolidatedDB where gameID in (select gameid from consolidatedtable where count(distinct(participID)<2 group by gameid)

整件事对我来说就像是儿童的解决方案

  1. 我需要为每个玩家提供一张综合表格
  2. 我将许多游戏的方式插入此表并稍后删除它们
  3. 整个事情需要在整个主表上逐个参与者运行,如果我同时为多个参与者执行此操作,它将不起作用

任何更好的想法,一定是,这个太糟糕了。主表将是 DW 服务器上的 postgreSQL,合并视图将是 mySQL(但数字运算将在 postgreSQL 中完成)


我的问题

1)我如何构建合并表(s - 我需要多个),而不必为每个玩家在整个主表上运行单个查询(我需要为玩家 x、y、z 提供数据,无论如何还有谁在玩) - 这是 DW 服务器的整合任务,它应该为 webserver 创建表(这是压缩的)

2)然后我怎样才能在网络服务器上快速提取(所以(1)的表格设计应该考虑到这一点。我们不是在谈论很多玩家在这里我需要这个信息,也许是 100?(那么我可以要么按玩家 ID 分区,要么只创建单个表)


  • 数据仓库:postgreSQL 9.2(48GB,SSD)
  • 网络服务器:mySQL 5.5(4GB 内存,SSD)

    • 主表:gameid BIGINT、participID、Result INT、particiP ID 上的外键(到参与者表)
  • DW 服务器将保存主表,DW 服务器还应准备合并/提取表(处理能力,ssd 空间不是问题)
  • 网络服务器应该保存合并表(仅适用于我需要信息的 100 名玩家)并以非常有效的方式查询这些数据

在网络服务器上如此高效的查询>> DW服务器的工作量)


我认为这很重要,很抱歉我一开始没有包括它。

DW 服务器上的数据每天都会更新,但我不需要每天都完整地查询整个“主表”。该设置允许我只巩固从不的价值观。eg:昨天盘整到了500,现在的ID=550,所以今天我只盘整501-550。

4

2 回答 2

0

听起来你只想要一个自我加入:

对于所有参与者:

SELECT x.gameID, x.participID, x.results, y.participID, y.results
FROM table as x
JOIN table as y
  ON T1.gameID = T2.gameID
WHERE x.participID <> y.participID

这样做的缺点是你会在每场比赛的每一边得到每个参与者。

对于 2 位特定参与者:

 SELECT x.gameID, x.results, y.results
    FROM (SELECT gameID, participID, results 
          FROM table 
          WHERE t1.participID = 'x'
                and results <> 0)
           as x
    JOIN (SELECT gameID, participID, results 
          FROM table 
          WHERE t1.participID = 'y'
                and results <> 0)
          as y
      ON T1.gameID = T2.gameID

您可能不需要在查询中选择 participID,具体取决于您对结果执行的操作。

于 2013-06-09T18:59:26.703 回答
0

这是另一个可能有效的想法,具体取决于您的数据库(以及我对问题的理解):

SELECT *
FROM   table a
WHERE  participID = 'x'
   AND EXISTS (
      SELECT 1 FROM table b
      WHERE b.participID = 'y'
        AND b.gameID=a.gameID
     );

假设您在两列(participID 和 gameID)上有索引,性能应该不错。

我将它与此进行比较,看看哪个运行得更快:

SELECT *
FROM   table a
JOIN (
   SELECT gameID
   FROM   table
   WHERE  participID = 'y'
   GROUP BY gameID
   ) b
ON a.gameID=b.gameID
WHERE  a.participID = 'x';
于 2013-06-09T19:48:50.783 回答