如何在 javascript 中最有效地对规范化数据进行非规范化
Posted
技术标签:
【中文标题】如何在 javascript 中最有效地对规范化数据进行非规范化【英文标题】:How to denormalize normalized data most effectively in javascript 【发布时间】:2021-09-05 06:36:30 【问题描述】:例如我有以下树:
root:
a:
b: null,
c:
d: null
e: null
我以 [child]: parent
的形式收到它:
a: 'root',
e: 'root',
b: 'a',
c: 'a',
d: 'c'
但我没有收到上述订购的产品。不过,我愿意。
如果我知道根项(没有父项)是root
,我可以使用这个函数:
const recurs = (obj, cb, parent = 'root') => Object.entries(obj)
.filter(([child, childsParent]) => childsParent === parent)
.forEach(([child]) =>
cb(child);
recurs(obj, cb, child);
);
但是因为它是递归的,所以它可以填满内存,因为在一切完成之前不会对父母进行垃圾收集。有没有更有效的方法来做这种事情?这可以转换为for循环吗?
【问题讨论】:
"可以将其转换为 for 循环吗?" 可以。但是,为什么您认为这将有助于垃圾收集?通常 GC 会等到循环完成后才会运行。您是否真正观察到问题或者这是过早的优化? “它可以填满内存,因为父母不会被垃圾收集”是什么意思? 无法保证 GC 何时运行。它通常会等待程序不忙。它可能在循环期间运行,但通常会导致性能大大降低(如果它运行一次,它可能会运行更多次。一个大循环会产生很多符合 GC 条件的东西,那就是会有很多 GC 停止)。 这让我们回到“你是否真的注意到这是一个问题”,因为现在听起来你正在尝试优化一些没有实际性能或可用性的东西(dev or 用户)问题,因此不需要花费任何时间。 我认为也许 OP 关心的是调用堆栈而不是 GC,因为问题是关于避免递归? 【参考方案1】:使用在单个线性循环中填充的查找表:
const edges =
a: 'root',
e: 'root',
b: 'a',
c: 'a',
d: 'c'
;
const forest = ;
for (const child in edges)
const parent = edges[child];
forest[parent] ??= ;
forest[child] ??= ;
forest[parent][child] = forest[child];
const tree = forest.root;
【讨论】:
@pilchard 谢谢,已修复以上是关于如何在 javascript 中最有效地对规范化数据进行非规范化的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 PHP 和 MySQL 有效地对大型数据集进行分页?
在有效的 PHP query() XPath 中转换 Javascript XPath |规范化 JS XPath --> PHP