首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >最有效的分层乘积表

问最有效的分层乘积表
EN

Stack Overflow用户
提问于 2012-09-10 16:04:53
回答 2查看 208关注 0票数 0

我已经建立了一些产品数据库,但我从来没有真正对数据库的效率感到满意。我最好的方法是有一个products表,一个category表,然后是一个关系表,即:

产品表:

代码语言:javascript
复制
id    product_name     data
1     Some prod        More info...
2     Another prod     Even more...

类别表:

代码语言:javascript
复制
id    parent_id   cat_name
1     0           Main cat 1
2     1           Sub cat 1
3     1           Sub cat 2
4     3           Sub sub cat 1
5     0           Main cat 2

关系表:

代码语言:javascript
复制
id    prod_id    cat_id
1     1          2
2     1          4
3     2          5
etcetera...

这使得检索产品变得又快又容易,也很容易将一个产品分配到多个类别。

然而,创建类别列表的结构并不像我希望的那样简单。首先,我需要循环主类别,然后相应地循环所有子类别。我只喜欢显示分配了产品的类别,但如果子级别包含产品,我当然也需要显示所有父类别。这导致了大量的查询、连接和条件例程来呈现当前的类别。我想知道是否有更有效的结构化方法来解决这个问题?你不需要写我的代码,我只是想知道有什么更好的原则?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-10 16:10:18

典型的递归方法是邻接表和多对多表。

典型的非递归方法是多对多祖先表和nested sets。

辅助列表是那些包含"parent_id“引用的结构。

递归读取多对多表是您的方法。

祖先表是多对多表,但它们也包含子-祖父连接,并指定每个连接的级别。它们允许最大的灵活性和最快的读/写速度。

嵌套集是一种非常不同的方法,它们只允许严格的树结构,而不允许图形。它们在写操作上的开销也更大,但在读操作上却非常容易。

另外,对于嵌套集合,手动维护结构是相当困难的。您需要实现几个函数并选择何时使用每个函数,因为在子列表末尾插入节点需要一个函数(appendNodeTo($parentNode)),而在子列表中间插入节点需要另一个函数。移动节点取决于节点是终端节点(叶),还是具有具有特定功能的子节点(分支)。

票数 2
EN

Stack Overflow用户

发布于 2012-09-10 16:14:39

这不是最有效的方法,但是这种方法只需要一个sql请求(查询)

代码语言:javascript
复制
 public function get_menu_data()
    {
        $result = mysql_query(" 
            SELECT 
                id, parent, name 
            FROM 
                category 
            ORDER BY 
                parent, name 
        "); 
        //$cat = $this->db->get("category");
        $menuData = array( 
            'items' => array(), 
            'parents' => array() 
        ); 

        while ($menuItem = mysql_fetch_assoc($result)) 
        { 
           $menuData['items'][$menuItem['id']] = $menuItem; 
           $menuData['parents'][$menuItem['parent']][] = $menuItem['id']; 
        } 
        return $menuData;

    }

function buildMenu($parentId, $menuData)
{
    $html = '';
    if (isset($menuData['parents'][$parentId]))
    {
        $html = '<ul>';
        foreach ($menuData['parents'][$parentId] as $itemId)
        {
            $html .= '<li>' . $menuData['items'][$itemId]['name'];
            // find childitems recursively
            $html .= $this -> buildMenu($itemId, $menuData);
            $html .= '</li>';
        }
        $html .= '</ul>';
    }
    return $html;
}

如下所示:显示所有类别:

代码语言:javascript
复制
buildMenu(0,get_menu_data());

显示categorie 1的子类别:

代码语言:javascript
复制
buildMenu(1,get_menu_data());

祝你好运,我希望这段代码能帮助你

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12347525

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档