我必须从4个(或更多)表中打包数据。 据我所知,有两种处理方法。
将所有这些都加入数据库,然后查询一次。
每个表查询一次,然后在后端对其进行管理/组合。
即使第一种方法在某种程度上似乎更合理, 如果它们(连接结果中的任何行)具有相同的父级(父键), 来自联接表的数据仍需要分组在一起。
例如。
// foos and bars from separately query
foos: [ { foo_id: 1, ...(foo1) }, { foo_id: 2, ...(foo2) } ];
bars: [
{ foo_id: 1, bar_id: 1, ...(bar1) },
{ foo_id: 1, bar_id: 2, ...(bar2) },
{ foo_id: 2, bar_id: 3, ...(bar3) },
{ foo_id: 2, bar_id: 4, ...(bar4) }
];
// foo-bars from the join-result using foo_id as join-key
foo_bar: [
{ foo_id: 1, ...(foo1), bar_id: 1, ...(bar1) },
{ foo_id: 1, ...(foo1), bar_id: 2, ...(bar2) },
{ foo_id: 2, ...(foo2), bar_id: 3, ...(bar3) },
{ foo_id: 2, ...(foo2), bar_id: 4, ...(bar4) }
];
应分组为/组合为
foos: [
{
foo_id: 1,
...(foo1),
bars: [
{ bar_id: 1, ...(bar1) },
{ bar_id: 2, ...(bar2) },
]
},
{
foo_id: 2,
...(foo2),
bars: [
{ bar_id: 3, ...(bar3) },
{ bar_id: 4, ...(bar4) },
]
},
];
依次类推其他遗骸表...
因此,无论我如何查询,数据仍然需要在后端进行管理。
因此,目前,我选择了第二种实现方式。 (但仍在寻找更好的应对方式,并在必要时计划进行更改)
为了避免使用嵌套的for循环进行搜索,我将它们与使用parent的键将其自身与值配对的声明新对象分组在一起。
const arrayToObject = (array, key) => {
const object = {};
for (let i = 0; i < array.length; i += 1) {
object[array[i][key]] = array[i];
}
return object;
};
所以我的捆绑包for-loop看起来像..
const bundling = async() => {
// foo.fetch() & bar.fetch() is models that
// call db.query('SELECT * FROM foo/bar')
const [rawFoo, rawBar] = await Promise.all([foo.fetch(), bar.fetch()]);
const foos = arrayToObject(rawFoo, 'foo_id');
// create blank child list in each parent
for (let i = 0; i < rawFoo.lenght; i += 1) {
rawFoo[i].bars = [];
}
// this similar to nested for-loop that
// outer iteration is pointing to each parent member
// and inner one is pointing to each child member
// then check if they have same parent key >> do something
for (let i = 0; i < rawBar.length; i += 1) {
foos[ rawBar[i].foo_id ].bars.push( rawBar[i] );
}
return rawFoo;
}
根据另一个问题, Which is more expensive? For loop or database call? 连接数据库存在开销,这将导致我当前的解决方案比其他解决方案更糟糕。
但是JOIN queries vs multiple queries的第二个答案使我感到困惑,当我考虑联接输出大小与每个查询的总和大小时哪个更好。
SQL代码示例
# join table
# note that child table has parent id
SELECT * FROM foo
LEFT JOIN bar ON foo.foo_id = bar.foo_id
LEFT JOIN baz ON bar.bar_id = baz.bar_id
LEFT JOIN qux IN baz.baz_id = qux.baz_id
# several query for manage on backend
SELECT * FROM foo;
SELECT * FROM bar;
SELECT * FROM baz;
SELECT * FROM qux;
每个表的表结构彼此相似。
每个表都包含3个主要部分:parent_id, own_id, ...other_props
other_props的数量