在 PostgreSQL 和 NodeJS 中检索问题和投票
本文探讨了使用 PostgreSQL 和 NodeJS 将问题及其相关投票作为单个 JSON 对象获取的有效方法。 我们将研究几种方法,权衡它们的性能影响。
应用场景涉及用户提问和投票(赞成或反对)。目标是检索每个问题及其投票数组。
方法一:多次查询(pg-promise)
此方法使用 pg-promise
执行多个查询。 首先,它检索所有问题。然后,对于每个问题,它都会获取相应的投票。
<code class="language-javascript">function buildTree(t) { const v = q => t .any('SELECT id, value FROM votes WHERE question_id = ', q.id) .then((votes) => { q.votes = votes; return q; }); return t.map('SELECT * FROM questions', undefined, v).then((a) => t.batch(a)); } db.task(buildTree) .then((data) => { console.log(data); }) .catch((error) => { console.log(error); });</code>
或者,使用 ES7 async/await
:
<code class="language-javascript">await db.task(async (t) => { const questions = await t.any('SELECT * FROM questions'); for (const q of questions) { q.votes = await t.any('SELECT id, value FROM votes WHERE question_id = ', [q.id]); } return questions; });</code>
方法二:单次查询(PostgreSQL JSON 函数)
PostgreSQL 9.4 及更高版本提供了使用 JSON 函数的更高效的单查询解决方案:
<code class="language-sql">SELECT json_build_object('id', q.id, 'content', q.content, 'votes', (SELECT json_agg(json_build_object('id', v.id, 'value', v.value)) FROM votes v WHERE q.id = v.question_id)) FROM questions q;</code>
此查询为每个问题构造一个 JSON 对象,包括投票的聚合数组。 与pg-promise
:
<code class="language-javascript">const query = `SELECT json_build_object('id', q.id, 'content', q.content, 'votes', (SELECT json_agg(json_build_object('id', v.id, 'value', v.value)) FROM votes v WHERE q.id = v.question_id)) json FROM questions q`; const data = await db.map(query, [], (a) => a.json);</code>
性能比较
由于减少了数据库往返次数,单查询方法(方法 2)明显更快。 然而,方法1(多次查询)提供了更好的可读性和可维护性,特别是对于更复杂的场景。
为了在大型数据集上获得最佳性能,请考虑连接子查询等技术以最大限度地减少数据库交互,如有关组合嵌套循环查询的相关资源中所述。
以上是如何使用 NodeJS 在 PostgreSQL 中以单个 JSON 对象的形式高效检索问题及其相关投票?的详细内容。更多信息请关注PHP中文网其他相关文章!