我的情况是,我目前正在SQL数据库中存储层次结构,该数据库快速接近15000个节点(5000个边缘).此层次结构根据树中的用户位置定义我的安全模型,授予对下面项目的访问权限.因此,当用户请求所有安全项目的列表时,我正在使用CTE将其递归到数据库中(并展平所有项目),这将开始显示其年龄(慢).
层次结构不经常更改,所以我试图将其移动到RAM(redis)中.请记住,我有许多需要这个安全调用的子系统,以及用于为CRUD操作构建树的UI.
第一次尝试
我的第一次尝试是将关系存储为键值对(这是它存储在数据库中的方式)
E / \ F G / \ / \ H I J K mapped to: E - [F, G] F - [H, I] G - [J, K]
因此,当我想要E及其所有的死者时,我递归地让它的孩子和他们的孩子使用钥匙,它允许我从任何节点开始向下移动.这个解决方案提供了很好的速度提升但是有15,000个节点,在代码中重建我的树大约有5000个缓存命中(更糟糕的情况......从E开始.性能基于起始节点位置,导致超级用户看到最糟糕的表现).这仍然很快,但似乎很健谈.我喜欢这样一个事实,即我可以通过将其从键列表中弹出而无需重建我的整个缓存来随时删除节点.这也可以快速点亮,在UI上直观地构建树.
第二次尝试
我的另一个想法是从数据库中获取层次结构,构建树并将其存储在RAM(redis)中,然后将整个内容拉出内存(大小约为2 MB,序列化).这给了我一个单独的调用(不是很健谈)到redis中拉出整个树,找到用户父节点,然后下降以获取所有子项.这些调用很频繁,在网络层传递2 MB似乎很大.这也意味着我无法轻松添加/删除和项目,而无需拉下树并编辑并将其全部推回.同时根据需要通过HTTP建立树木意味着每个请求必须下拉2MB才能获得直接子项(使用第一个解决方案非常小).
那么您认为哪种解决方案是更好的方法(长期因为它继续增长).两者都更加快速,并从数据库中减轻一些负担.或者他们是一个更好的方法来实现这一点,我没有想过?
谢谢