一个用于多个用户的嵌套集表

时间:2015-05-25 14:13:45

标签: php mysql laravel nested-sets

如果之前有人问过我,我很抱歉,但是我想知道是否有人对可能有数千名用户拥有一个嵌套集表的性能有任何见解?

我需要每个注册用户都能够创建无限的嵌套类别。现在,我的结构是belongsToMany()关系:

users -> user_categories (pivot) -> categories

用户只能访问其类别,并且无法修改其他用户类别。

对于(可能)一个嵌套集表中的数万条记录,是否会有巨大的性能损失?每个用户应该获得自己的嵌套集类别表吗?

提前致谢!

1 个答案:

答案 0 :(得分:2)

嵌套集允许在单个查询中获取节点的所有后代,因此对于读取类别,性能命中将类似于普通(非嵌套集)表上的性能命中。当您插入时,会出现嵌套集的缺点,因为它需要在插入后更新表中所有记录的左右值。

因此,性能影响将取决于您插入的频率以及您的插图的大小。

如果没有一个大树,每个用户有一个根节点,所有存储在同一个表中,那么插入将只涉及更新一个小子树,这可以显着减少开销。

如果您想自己测试性能,可以使用Laravel Baum包并使用此播种机查看插入26 * 10 * 3类别的效果如何:

<?php

use App\Category;
use Illuminate\Database\Seeder;

class CategoriesTableSeeder extends Seeder
{
    public function run()
    {
        // Helper function to populate model attributes
        $node = function () {
            $args = implode(' ', func_get_args());

            return ['name' => "Category $args"];
        };

        // Create first level nodes
        foreach(range('A', 'Z') as $letter)
        {
            $node0 = Category::create($node($letter));

            // Create second level nodes
            foreach(range(1, 10) as $number)
            {
                $node1 = $node0->children()->create($node($letter, $number));

                // Create third level nodes
                foreach(['Δ', 'Σ', 'Ω'] as $greek)
                {
                    $node2 = $node1->children()->create($node($letter, $number, $greek));
                }
            }
        }
    }
}