我已经建立了一些产品数据库,但我从来没有真正对数据库的效率感到满意。我最好的方法是有一个products表,一个category表,然后是一个关系表,即:
产品表:
id product_name data
1 Some prod More info...
2 Another prod Even more...类别表:
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关系表:
id prod_id cat_id
1 1 2
2 1 4
3 2 5
etcetera...这使得检索产品变得又快又容易,也很容易将一个产品分配到多个类别。
然而,创建类别列表的结构并不像我希望的那样简单。首先,我需要循环主类别,然后相应地循环所有子类别。我只喜欢显示分配了产品的类别,但如果子级别包含产品,我当然也需要显示所有父类别。这导致了大量的查询、连接和条件例程来呈现当前的类别。我想知道是否有更有效的结构化方法来解决这个问题?你不需要写我的代码,我只是想知道有什么更好的原则?
发布于 2012-09-10 16:10:18
典型的递归方法是邻接表和多对多表。
典型的非递归方法是多对多祖先表和nested sets。
辅助列表是那些包含"parent_id“引用的结构。
递归读取多对多表是您的方法。
祖先表是多对多表,但它们也包含子-祖父连接,并指定每个连接的级别。它们允许最大的灵活性和最快的读/写速度。
嵌套集是一种非常不同的方法,它们只允许严格的树结构,而不允许图形。它们在写操作上的开销也更大,但在读操作上却非常容易。
另外,对于嵌套集合,手动维护结构是相当困难的。您需要实现几个函数并选择何时使用每个函数,因为在子列表末尾插入节点需要一个函数(appendNodeTo($parentNode)),而在子列表中间插入节点需要另一个函数。移动节点取决于节点是终端节点(叶),还是具有具有特定功能的子节点(分支)。
发布于 2012-09-10 16:14:39
这不是最有效的方法,但是这种方法只需要一个sql请求(查询)
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;
}如下所示:显示所有类别:
buildMenu(0,get_menu_data());显示categorie 1的子类别:
buildMenu(1,get_menu_data());祝你好运,我希望这段代码能帮助你
https://stackoverflow.com/questions/12347525
复制相似问题