【问题标题】:MySQL operating hierarchical dataMySQL操作分层数据
【发布时间】:2011-07-05 13:55:56
【问题描述】:

我有 MySQL 表结构:

CREATE TABLE IF NOT EXISTS `categories` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `parent_id` int(10) unsigned NOT NULL DEFAULT '0',
  `name` varchar(255) NOT NULL DEFAULT '',
  `is_working` tinyint(1) unsigned NOT NULL DEFAULT '1',
);

它保存具有idparent_id关系的分层数据

我有 5 级深度树,例如:

CATEGORY LEVEL 1
  SUBCAT LEVEL 2
    SUBCAT LEVEL 3
      SUBCAT LEVEL 4
        SUBCAT LEVEL 5

我需要(问题):如果我为某个类别或子类别设置is_working = 0,则所有子类别的is_working 都设置为0

【问题讨论】:

标签: mysql hierarchical-data sql-update


【解决方案1】:

我用的是另一种设计,虽然有局限性,但如果你能承受的话,它很简单,也很高效。

这是鸟类分类树的示例,因此层次结构是类/顺序/科/属/物种 - 物种是最低级别,1 行 = 1 个物种:

CREATE TABLE `taxons` (
  `TaxonId` smallint(6) NOT NULL default '0',
  `ClassId` smallint(6) default NULL,
  `OrderId` smallint(6) default NULL,
  `FamilyId` smallint(6) default NULL,
  `GenusId` smallint(6) default NULL,
  `Name` varchar(150) NOT NULL default ''
);

以及数据示例:

+---------+---------+---------+----------+---------+-------------------------------+
| TaxonId | ClassId | OrderId | FamilyId | GenusId | Name                          |
+---------+---------+---------+----------+---------+-------------------------------+
|     254 |       0 |       0 |        0 |       0 | Aves                          |
|     255 |     254 |       0 |        0 |       0 | Gaviiformes                   |
|     256 |     254 |     255 |        0 |       0 | Gaviidae                      |
|     257 |     254 |     255 |      256 |       0 | Gavia                         |
|     258 |     254 |     255 |      256 |     257 | Gavia stellata                |
|     259 |     254 |     255 |      256 |     257 | Gavia arctica                 |
|     260 |     254 |     255 |      256 |     257 | Gavia immer                   |
|     261 |     254 |     255 |      256 |     257 | Gavia adamsii                 |
|     262 |     254 |       0 |        0 |       0 | Podicipediformes              |
|     263 |     254 |     262 |        0 |       0 | Podicipedidae                 |
|     264 |     254 |     262 |      263 |       0 | Tachybaptus                   |

这很好,因为这样您就可以非常轻松地完成所有需要的操作,只要类别不改变它们在树中的级别即可。

【讨论】:

  • 您有任何文献支持这种解决方案吗?我个人喜欢它(对于我正在构建的简单层次结构)并且希望有一些支持和反对它的论据。
【解决方案2】:

您可以使用触发器来执行递归更新。

看看这个:http://dev.mysql.com/doc/refman/5.0/en/triggers.html

这只是一个想法,我不尝试这段代码。

delimiter //
CREATE TRIGGER categoriesUpdateTrg BEFORE UPDATE ON categories
    FOR EACH ROW BEGIN
    IF (NEW.is_working<>OLD.is_working) THEN
        UPDATE categories SET is_working=NEW.id_working WHERE parent_id=NEW.id;
        END IF;
    END;
//
delimiter ;

每次更新表“类别”时都会执行触发器。对于每个更新的行,都在询问 is_working 列是否已更改。如果条件为真,则更新所有子类别(递归)。

【讨论】:

  • 查看新的示例代码。 “For Each Row”语句为每个更新的行执行包含代码。
  • 我试过你的例子,但得到一个错误:#1442 - Can't update table 'categories' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
  • 哦,我没试过这段代码,但是如果这被限制的话是全面的,因为可以创建一个无限循环,抱歉我没有其他想法。
猜你喜欢
  • 1970-01-01
  • 2015-01-24
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
  • 2012-01-31
相关资源
最近更新 更多