基于左右值无限分类数据库操作

mysql> SELECT node.name
FROM nested_category AS node,
        nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND parent.name = ‘ELECTRONICS‘
ORDER BY node.lft;
+----------------------+
| name                 |
+----------------------+
| ELECTRONICS          |
| TELEVISIONS          |
| TUBE                 |
| LCD                  |
| PLASMA               |
| PORTABLE ELECTRONICS |
| MP3 PLAYERS          |
| FLASH                |
| CD PLAYERS           |
| 2 WAY RADIOS         |
+----------------------+
10 rows in set

mysql> SELECT name
FROM nested_category
WHERE rgt = lft + 1;
+--------------+
| name         |
+--------------+
| TUBE         |
| LCD          |
| PLASMA       |
| FLASH        |
| CD PLAYERS   |
| 2 WAY RADIOS |
+--------------+
6 rows in set

mysql> SELECT parent.name
FROM nested_category AS node,
        nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.name = ‘FLASH‘
ORDER BY parent.lft ASC;
+----------------------+
| name                 |
+----------------------+
| ELECTRONICS          |
| PORTABLE ELECTRONICS |
| MP3 PLAYERS          |
| FLASH                |
+----------------------+
4 rows in set

mysql> SELECT node.name, (COUNT(parent.name) - 1) AS depth
FROM nested_category AS node,
        nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;
+----------------------+-------+
| name                 | depth |
+----------------------+-------+
| ELECTRONICS          |     0 |
| TELEVISIONS          |     1 |
| TUBE                 |     2 |
| LCD                  |     2 |
| PLASMA               |     2 |
| PORTABLE ELECTRONICS |     1 |
| MP3 PLAYERS          |     2 |
| FLASH                |     3 |
| CD PLAYERS           |     2 |
| 2 WAY RADIOS         |     2 |
+----------------------+-------+
10 rows in set

mysql> SELECT CONCAT( REPEAT(‘|--
‘, COUNT(parent.name) - 1), node.name) AS name
FROM nested_category AS node,
        nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;
+-------------------------+
| name                    |
+-------------------------+
| ELECTRONICS             |
| |--TELEVISIONS          |
| |--|--TUBE              |
| |--|--LCD               |
| |--|--PLASMA            |
| |--PORTABLE ELECTRONICS |
| |--|--MP3 PLAYERS       |
| |--|--|--FLASH          |
| |--|--CD PLAYERS        |
| |--|--2 WAY RADIOS      |
+-------------------------+
10 rows in set
mysql> SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
        nested_category AS parent,
        nested_category AS sub_parent,
        (
                SELECT node.name, (COUNT(parent.name) - 1) AS depth
                FROM nested_category AS node,
                nested_category AS parent
                WHERE node.lft BETWEEN parent.lft AND parent.rgt
                AND node.name = ‘PORTABLE ELECTRONICS‘
                GROUP BY node.name
                ORDER BY node.lft
        )AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
        AND sub_parent.name = sub_tree.name
GROUP BY node.name
ORDER BY node.lft;
+----------------------+-------+
| name                 | depth |
+----------------------+-------+
| PORTABLE ELECTRONICS |     0 |
| MP3 PLAYERS          |     1 |
| FLASH                |     2 |
| CD PLAYERS           |     1 |
| 2 WAY RADIOS         |     1 |
+----------------------+-------+
5 rows in set

mysql> SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
        nested_category AS parent,
        nested_category AS sub_parent,
        (
                SELECT node.name, (COUNT(parent.name) - 1) AS depth
                FROM nested_category AS node,
                nested_category AS parent
                WHERE node.lft BETWEEN parent.lft AND parent.rgt
                AND node.name = ‘PORTABLE ELECTRONICS‘
                GROUP BY node.name
                ORDER BY node.lft
        )AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
        AND sub_parent.name = sub_tree.name
GROUP BY node.name
ORDER BY node.lft;
+----------------------+-------+
| name                 | depth |
+----------------------+-------+
| PORTABLE ELECTRONICS |     0 |
| MP3 PLAYERS          |     1 |
| FLASH                |     2 |
| CD PLAYERS           |     1 |
| 2 WAY RADIOS         |     1 |
+----------------------+-------+
5 rows in set

mysql> SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
        nested_category AS parent,
        nested_category AS sub_parent,
        (
                SELECT node.name, (COUNT(parent.name) - 1) AS depth
                FROM nested_category AS node,
                        nested_category AS parent
                WHERE node.lft BETWEEN parent.lft AND parent.rgt
                        AND node.name = ‘PORTABLE ELECTRONICS‘
                GROUP BY node.name
                ORDER BY node.lft
        )AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
        AND sub_parent.name = sub_tree.name
GROUP BY node.name
HAVING depth <= 1
ORDER BY node.lft;
+----------------------+-------+
| name                 | depth |
+----------------------+-------+
| PORTABLE ELECTRONICS |     0 |
| MP3 PLAYERS          |     1 |
| CD PLAYERS           |     1 |
| 2 WAY RADIOS         |     1 |
+----------------------+-------+
4 rows in set

mysql> SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
        nested_category AS parent,
        nested_category AS sub_parent,
        (
                SELECT node.name, (COUNT(parent.name) - 1) AS depth
                FROM nested_category AS node,
                        nested_category AS parent
                WHERE node.lft BETWEEN parent.lft AND parent.rgt
                        AND node.name = ‘PORTABLE ELECTRONICS‘
                GROUP BY node.name
                ORDER BY node.lft
        )AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
        AND sub_parent.name = sub_tree.name
GROUP BY node.name
HAVING depth = 1
ORDER BY node.lft;
+--------------+-------+
| name         | depth |
+--------------+-------+
| MP3 PLAYERS  |     1 |
| CD PLAYERS   |     1 |
| 2 WAY RADIOS |     1 |
+--------------+-------+
3 rows in set

mysql> CREATE TABLE product
(
        product_id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(40),
        category_id INT NOT NULL
);

INSERT INTO product(name, category_id) VALUES(‘20" TV‘,3),(‘36" TV‘,3),
(‘Super-LCD 42"‘,4),(‘Ultra-Plasma 62"‘,5),(‘Value Plasma 38"‘,5),
(‘Power-MP3 5gb‘,7),(‘Super-Player 1gb‘,8),(‘Porta CD‘,9),(‘CD To go!‘,9),
(‘Family Talk 360‘,10);
Query OK, 0 rows affected

Query OK, 10 rows affected
Records: 10  Duplicates: 0  Warnings: 0

mysql> SELECT parent.name, COUNT(product.name)
FROM nested_category AS node ,
        nested_category AS parent,
        product
WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.category_id = product.category_id
GROUP BY parent.name
ORDER BY node.lft;
+----------------------+---------------------+
| name                 | COUNT(product.name) |
+----------------------+---------------------+
| ELECTRONICS          |                  10 |
| TELEVISIONS          |                   5 |
| TUBE                 |                   2 |
| LCD                  |                   1 |
| PLASMA               |                   2 |
| PORTABLE ELECTRONICS |                   5 |
| MP3 PLAYERS          |                   2 |
| FLASH                |                   1 |
| CD PLAYERS           |                   2 |
| 2 WAY RADIOS         |                   1 |
+----------------------+---------------------+
10 rows in set

mysql> LOCK TABLE nested_category WRITE;

SELECT @myRight := rgt FROM nested_category
WHERE name = ‘TELEVISIONS‘;

UPDATE nested_category SET rgt = rgt + 2 WHERE rgt > @myRight;
UPDATE nested_category SET lft = lft + 2 WHERE lft > @myRight;

INSERT INTO nested_category(name, lft, rgt) VALUES(‘GAME CONSOLES‘, @myRight + 1, @myRight + 2);

UNLOCK TABLES;
Query OK, 0 rows affected

+-----------------+
| @myRight := rgt |
+-----------------+
|               9 |
+-----------------+
1 row in set

Query OK, 6 rows affected
Rows matched: 6  Changed: 6  Warnings: 0

Query OK, 5 rows affected
Rows matched: 5  Changed: 5  Warnings: 0

Query OK, 1 row affected

Query OK, 0 rows affected

mysql> SELECT CONCAT( REPEAT(‘|--‘, COUNT(parent.name) - 1), node.name) AS name
FROM nested_category AS node,
        nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;
+-------------------------+
| name                    |
+-------------------------+
| ELECTRONICS             |
| |--TELEVISIONS          |
| |--|--TUBE              |
| |--|--LCD               |
| |--|--PLASMA            |
| |--GAME CONSOLES        |
| |--PORTABLE ELECTRONICS |
| |--|--MP3 PLAYERS       |
| |--|--|--FLASH          |
| |--|--CD PLAYERS        |
| |--|--2 WAY RADIOS      |
+-------------------------+
11 rows in set

mysql> LOCK TABLE nested_category WRITE;

SELECT @myLeft := lft FROM nested_category

WHERE name = ‘2 WAY RADIOS‘;

UPDATE nested_category SET rgt = rgt + 2 WHERE rgt > @myLeft;
UPDATE nested_category SET lft = lft + 2 WHERE lft > @myLeft;

INSERT INTO nested_category(name, lft, rgt) VALUES(‘FRS‘, @myLeft + 1, @myLeft + 2);

UNLOCK TABLES;
Query OK, 0 rows affected

+----------------+
| @myLeft := lft |
+----------------+
|             19 |
+----------------+
1 row in set

Query OK, 3 rows affected
Rows matched: 3  Changed: 3  Warnings: 0

Query OK, 0 rows affected
Rows matched: 0  Changed: 0  Warnings: 0

Query OK, 1 row affected

Query OK, 0 rows affected

mysql> SELECT CONCAT( REPEAT(‘|--‘, COUNT(parent.name) - 1), node.name) AS name
FROM nested_category AS node,
        nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;
+-------------------------+
| name                    |
+-------------------------+
| ELECTRONICS             |
| |--TELEVISIONS          |
| |--|--TUBE              |
| |--|--LCD               |
| |--|--PLASMA            |
| |--GAME CONSOLES        |
| |--PORTABLE ELECTRONICS |
| |--|--MP3 PLAYERS       |
| |--|--|--FLASH          |
| |--|--CD PLAYERS        |
| |--|--2 WAY RADIOS      |
| |--|--|--FRS            |
+-------------------------+
12 rows in set

mysql> LOCK TABLE nested_category WRITE;

SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
FROM nested_category
WHERE name = ‘GAME CONSOLES‘;

DELETE FROM nested_category WHERE lft BETWEEN @myLeft AND @myRight;

UPDATE nested_category SET rgt = rgt - @myWidth WHERE rgt > @myRight;
UPDATE nested_category SET lft = lft - @myWidth WHERE lft > @myRight;

UNLOCK TABLES;
Query OK, 0 rows affected

+----------------+-----------------+---------------------------+
| @myLeft := lft | @myRight := rgt | @myWidth := rgt - lft + 1 |
+----------------+-----------------+---------------------------+
|             10 |              11 |                         2 |
+----------------+-----------------+---------------------------+
1 row in set

Query OK, 1 row affected

Query OK, 7 rows affected
Rows matched: 7  Changed: 7  Warnings: 0

Query OK, 6 rows affected
Rows matched: 6  Changed: 6  Warnings: 0

Query OK, 0 rows affected

mysql> SELECT CONCAT( REPEAT(‘|--‘, COUNT(parent.name) - 1), node.name) AS name
FROM nested_category AS node,
        nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;
+-------------------------+
| name                    |
+-------------------------+
| ELECTRONICS             |
| |--TELEVISIONS          |
| |--|--TUBE              |
| |--|--LCD               |
| |--|--PLASMA            |
| |--PORTABLE ELECTRONICS |
| |--|--MP3 PLAYERS       |
| |--|--|--FLASH          |
| |--|--CD PLAYERS        |
| |--|--2 WAY RADIOS      |
| |--|--|--FRS            |
+-------------------------+
11 rows in set

mysql> LOCK TABLE nested_category WRITE;

SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
FROM nested_category
WHERE name = ‘MP3 PLAYERS‘;

DELETE FROM nested_category WHERE lft BETWEEN @myLeft AND @myRight;

UPDATE nested_category SET rgt = rgt - @myWidth WHERE rgt > @myRight;
UPDATE nested_category SET lft = lft - @myWidth WHERE lft > @myRight;

UNLOCK TABLES;
Query OK, 0 rows affected

+----------------+-----------------+---------------------------+
| @myLeft := lft | @myRight := rgt | @myWidth := rgt - lft + 1 |
+----------------+-----------------+---------------------------+
|             11 |              14 |                         4 |
+----------------+-----------------+---------------------------+
1 row in set

Query OK, 2 rows affected

Query OK, 5 rows affected
Rows matched: 5  Changed: 5  Warnings: 0

Query OK, 3 rows affected
Rows matched: 3  Changed: 3  Warnings: 0

Query OK, 0 rows affected

mysql> SELECT CONCAT( REPEAT(‘|--‘, COUNT(parent.name) - 1), node.name) AS name
FROM nested_category AS node,
        nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;
+-------------------------+
| name                    |
+-------------------------+
| ELECTRONICS             |
| |--TELEVISIONS          |
| |--|--TUBE              |
| |--|--LCD               |
| |--|--PLASMA            |
| |--PORTABLE ELECTRONICS |
| |--|--CD PLAYERS        |
| |--|--2 WAY RADIOS      |
| |--|--|--FRS            |
+-------------------------+
9 rows in set

mysql> LOCK TABLE nested_category WRITE;

SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
FROM nested_category
WHERE name = ‘PORTABLE ELECTRONICS‘;

DELETE FROM nested_category WHERE lft = @myLeft;

UPDATE nested_category SET rgt = rgt - 1, lft = lft - 1 WHERE lft BETWEEN @myLeft AND @myRight;
UPDATE nested_category SET rgt = rgt - 2 WHERE rgt > @myRight;
UPDATE nested_category SET lft = lft - 2 WHERE lft > @myRight;

UNLOCK TABLES;
Query OK, 0 rows affected

+----------------+-----------------+---------------------------+
| @myLeft := lft | @myRight := rgt | @myWidth := rgt - lft + 1 |
+----------------+-----------------+---------------------------+
|             10 |              17 |                         8 |
+----------------+-----------------+---------------------------+
1 row in set

Query OK, 1 row affected

Query OK, 3 rows affected
Rows matched: 3  Changed: 3  Warnings: 0

Query OK, 1 row affected
Rows matched: 1  Changed: 1  Warnings: 0

Query OK, 0 rows affected
Rows matched: 0  Changed: 0  Warnings: 0

Query OK, 0 rows affected

mysql> SELECT CONCAT( REPEAT(‘|--‘, COUNT(parent.name) - 1), node.name) AS name
FROM nested_category AS node,
        nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;
+-----------------+
| name            |
+-----------------+
| ELECTRONICS     |
| |--TELEVISIONS  |
| |--|--TUBE      |
| |--|--LCD       |
| |--|--PLASMA    |
| |--CD PLAYERS   |
| |--2 WAY RADIOS |
| |--|--FRS       |
+-----------------+
8 rows in set

mysql> SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
FROM nested_category
WHERE name = ‘LCD‘;
+----------------+-----------------+---------------------------+
| @myLeft := lft | @myRight := rgt | @myWidth := rgt - lft + 1 |
+----------------+-----------------+---------------------------+
|              5 |               6 |                         2 |
+----------------+-----------------+---------------------------+
1 row in set

mysql>
时间: 2024-11-05 00:23:14

基于左右值无限分类数据库操作的相关文章

左右值无限分类实现算法

一.引言产品分类,多级的树状结构的论坛,邮件列表等许多地方我们都会遇到这样的问题:如何存储多级结构的数据?在PHP的应用中,提供后台数据存储的通常是关系型数据库,它能够保存大量的数据,提供高效的数据检索和更新服务.然而关系型数据的基本形式是纵横交错的表,是一个平面的结构,如果要将多级树状结构存储在关系型数据库里就需要进行合理的翻译工作.接下来我会将自己的所见所闻和一些实用的经验和大家探讨一下:层级结构的数据保存在平面的数据库中基本上有两种常用设计方法: 毗邻目录模式(adjacency list

无限分类树操作

获取相应分类id的分类树: public static function getCategoryTree($id){ //$model=M('category'); if($id>0){ $obj=self::selectTable('category',array('id'=>$id),true);//$model->where(array('id'=>$id))->find(); if(!is_null($obj)){ $childList=self::selectTab

android菜鸟学习笔记20----Android数据存储(四))Android数据库操作

Android内置了一个名为SQLite的关系型数据库,这是一款轻量型的数据库,操作十分简便.SQLite与别的数据库不同的是,它没有数据类型.可以保存任何类型的数据到你所想要保存的任何表的任何列中.但它又支持常见的类型比如: NULL, VARCHAR, TEXT, INTEGER, BLOB, CLOB...等. 唯一的例外是:integer primary key 此字段只能存储64位整数. 在JAVA项目中,要使用JDBC操作数据库需要加载数据库驱动,连接数据库等操作.Android简化

数据库结果为 基于左右值排序的无限分类算法

<?php /**     * 基于左右值排序的无限分类算法     * 数据库结果为 CREATE TABLE om_catagory (      CatagoryID int(10) unsigned NOT NULL auto_increment,     Name varchar(50) default '',      Lft int(10) unsigned NOT NULL default '0',      Rgt int(10) unsigned NOT NULL defau

php基于左右值排序的无限分类算法

PHP无限分类[左右值]算法 <?php /** * 基于左右值排序的无限分类算法 * 数据库结果为 CREATE TABLE om_catagory ( CatagoryID int(10) unsigned NOT NULL auto_increment, Name varchar(50) default '', Lft int(10) unsigned NOT NULL default '0', Rgt int(10) unsigned NOT NULL default '0', PRIM

树形结构的数据库表Schema设计-基于左右值编码

树形结构的数据库表Schema设计 程序设计过程中,我们常常用树形结构来表征某些数据的关联关系,如企业上下级部门.栏目结构.商品分类等等,通常而言,这些树状结构需要借助于数据库完 成持久化.然而目前的各种基于关系的数据库,都是以二维表的形式记录存储数据信息,因此是不能直接将Tree存入DBMS,设计合适的Schema及其对 应的CRUD算法是实现关系型数据库中存储树形结构的关键. 理想中树形结构应该具备如下特征:数据存储冗余度小.直观性强:检索遍历过程简单高效:节点增删改查CRUD操作高效.无意

基于OCILIB的oracle数据库操作总结及自动生成Model和Dao的工具

基于OCILIB的oracle数据库操作总结 1.       类图 2.       基类BaseOCIDao的设计与实现 BaseOCIDao.h头文件 #pragma once /* --------------------------------------------------------------------------------------------- * * INCLUDES * ----------------------------------------------

【转】ThinkPHP中数据库操作返回值总结

Thinkphp中的Think\Model类提供了数据库的基本CURD(Create.Update.Read及Delete),通过该类可以很便捷的进行操作.Model类及扩展类主要的方法有: Create操作:create()(非链式) .add().addAll()支持的链式操作有:table .data.field .relation .validate.auto .filter.scope .bind .token .comment Update操作save().setField().se

ThinkPHP中数据库操作返回值总结

转自:http://www.baiwar.com/post/thinkphp-database-operations-in-the-return-value.html Thinkphp中的Think\Model类提供了数据库的基本CURD(Create.Update.Read及Delete),通过该类可以很便捷的进行操作.Model类及扩展类主要的方法有: Create操作:create()(非链式) .add().addAll()支持的链式操作有:table .data.field .rela