1

我有两张表,其中包含两个不同游戏的游戏数据。为了简单起见,假设它们只共享一个名为的列Timestamp(特别是它们具有不同数量的列)。我想呈现一个包含两个表中信息的列表,同时按Timestamp.

我目前正在做的工作,但我几乎可以打赌有更好的方法来做到这一点。我最关心的是某个时候的性能(移动应用程序)。这是一个代表结构的存根——相信我,我知道这看起来有多可怕。我只是想先让它工作,现在我正在寻找改进。;)

var readyA,
    readyB = false;

var dataA, 
    dataB;

function doLoop () {
    setTimeout(renderData, 100);
}

function renderData () {
    if (!readyA || !readyB) {
        doLoop();
        return;
    }

    var dataAll = dataA.concat(dataB);
    dataAll.sort(function (a,b) {
        return a['Timestamp'] <= b['Timestamp'];
    });

    // pass data into a template depending on from which game it is and render it
    // ...
}

// wait for both queries to finish
doLoop();

// select data from game A
myDatabaseClass.query('SELECT ... FROM GameA', function (results) {
    dataA = new Array(results.rows.length);
    for (var i=0; i<results.rows.length; i++) { 
        dataA[i] = results.rows.item(i); 
    }

    readyA = true;
});

// select data from game B
myDatabaseClass.query('SELECT ... FROM GameB', function (results) {
    dataB = new Array(results.rows.length);
    for (var i=0; i<results.rows.length; i++) { 
        dataB[i] = results.rows.item(i); 
    }

    readyB = true;
});

现在的问题是我是否可以通过某种方式UNIONJOIN在查询中以某种方式简化这一点。显然,这个Timeout结构很糟糕,但是如果查询可以在一个查询中完成(或至少一个事务——数据库类可以处理),它会自动折叠为一个简单的回调函数。

编辑:我确实找到了这个(从两个不同的表和订单中拉出),但这整个NULL AS some_column感觉很脏。真的没有更好的选择吗?

4

2 回答 2

2

查询的结果始终是具有固定列数的单个表,因此所有SELECTs 必须具有相同的列数:

SELECT a1, a2, a3,   Timestamp FROM GameA
UNION ALL
SELECT b1, b2, NULL, Timestamp FROM GameB
ORDER BY Timestamp

UNION ALL比它更快,UNION因为它不会尝试删除重复项。)

于 2012-11-30T14:28:52.760 回答
1

你的代码很不错。从像我这样的 SQL 黑客的角度来看,您正在客户端执行 UNION 和 ORDER BY。这没什么不好。你似乎做的几乎是对的。您的“concat”是 UNION 的客户端等价物,而您的“排序”是 ORDER BY 的等价物。

你说NULL as missing-column如果你使用服务器端UNION操作,构造感觉有点脏。但是,显然要将两个不同的结果集视为相同,以便您可以对它们进行排序,以便您必须以某种方式使它们彼此一致。您a['Timestamp'] <= b['Timestamp']在排序函数中的排序标准也是使两个结果集相互一致的方案。它的性能可能比使用 UNION 低。

不要害怕使用NULL as missing-column使 UNION 中的两个结果集相互一致。它不脏,也不贵。

请考虑以某种方式限制您的 SELECT 操作,也许是通过一系列时间戳。这将允许您的系统扩展,特别是如果您在用于限制 SELECT 的列上放置索引。

(顺便说一句,你的排序函数有一个错误。排序函数需要返回-1、0或+1,具体取决于第一项小于、等于还是大于第二项。你是返回一个真/假值。这不能正常工作。)

(您将两个查询并行化到同一个 MySQL 实例。这很聪明,但实际上可能是随着游戏规模扩大而重载 MySQL 的公式。请记住,游戏的每个用户都有自己的运行 Javascript 的机器,但它们都分享你的 MySQL。)

于 2012-11-30T14:33:06.643 回答