我有两张桌子可以存放两种不同游戏的游戏数据。为简单起见,假设它们只共享一个名为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;
});
现在的问题是,如果我可以通过查询中的某种UNION
或JOIN
以某种方式简化此操作。显然,Timeout
构造很糟糕,但是如果查询可以在一个查询中完成(或者至少有一个事务 - 数据库类可以处理它),那么它将自动折叠成一个简单的回调函数。
编辑:我确实找到了这个(Pull from two different tables and order),但整个NULL AS some_column
感觉很脏。真的没有更好的选择吗?
答案 0 :(得分:2)
查询的结果始终是具有固定列数的单个表,因此所有SELECT
必须具有相同的列数:
SELECT a1, a2, a3, Timestamp FROM GameA
UNION ALL
SELECT b1, b2, NULL, Timestamp FROM GameB
ORDER BY Timestamp
(UNION ALL
比UNION
快,因为它不会尝试删除重复项。)
答案 1 :(得分:1)
你的代码非常好。从像我这样的SQL黑客的角度来看,你在客户端做UNION和ORDER BY。这没什么不对。你似乎做得差不多。你的“concat”是客户端的UNION等价物,你的“sort”相当于ORDER BY。
如果你使用服务器端NULL as missing-column
操作,你说UNION
结构有点脏。但是,显然要将两个不同的结果集视为相同,这样您就可以对它们进行排序,以使它们必须以某种方式使它们相互适应。排序函数中的a['Timestamp'] <= b['Timestamp']
排序排序标准也是一种使两个结果集相互符合的方案。它的性能可能低于使用UNION。
不要害怕使用NULL as missing-column
使UNION中的两个结果集相互一致。它不脏,而且价格不贵。
请考虑以某种方式限制SELECT操作,可能是通过一系列时间戳。这将允许您的系统向上扩展,特别是如果您在用于限制SELECT的列上放置索引。
(顺便说一句,你的sort函数有错误.sort函数需要返回-1,0或+1,具体取决于第一项是小于,等于还是大于第二项。你正在返回一个真/假值。这不能正常工作。)
(你将两个查询并行化到同一个MySQL实例。这很聪明,但实际上可能是一个在游戏扩展时重载MySQL的公式。请记住,游戏的每个用户都有自己的机器在运行Javascript但他们都共享你的MySQL。)