1

構造を使用してツリーをマップするデータベース テーブル (ディレクトリ) がありますparent_id=>id

ファイルを最初のテーブルのアイテムにマップする別のテーブル (ファイル) がありますdirectory_id => directories.id

私ができるようにしたいのは、最初のテーブルのIDを指定して、同じツリーで選択したID以上の場所にある2番目のテーブルのすべての行を削除することです。

次に、同じツリー内で等しいか上にある最初のテーブルのすべての行を削除します。

それを説明する最良の方法は、ファイルシステムであり、ディレクトリを削除し、その下のすべてを削除します。

これを行うために私が考えることができる唯一の方法は(半分の疑似コードです!):

$id = :id
$files = array();
$directories = array($id);
delete_tree($query:results, $files, $directories);

function delete_tree($id, &$files, &$directories){
    $query = SELECT `id` FROM `directories` WHERE `parent_id` = $id;
    foreach($query:results as $directory){
        $directories[] = $directory:id;
        $query2 = SELECT `id` FROM `files` WHERE `directory_id` = $directory:id;
        foreach($query2:results as $file){
            $files[] = $file:id
        }
        delete_tree($directory:id, $files, $directories);
    }
}

$query = DELETE from `directories` WHERE `id` IN (explode(',', $directories));
$query = DELETE from `files` WHERE `id` IN (explode(',', $files));
4

2 に答える 2

1

再帰SQLの使用を試みることができます;-)

ここであなたは情報を見つけることができます:

http://wiki.yaslaw.info/wikka/MySQLTree

「4)..」の下に、必要なSQL条件のサンプルがあります。

ここにサンプルコードがあります:

SELECT
    nav.id,
    nav.title
FROM
    (
        SELECT
            @rownum := @rownum+1 AS rownum, 
            IF(@lastid <> mylist.id, @id := mylist.id, @id) AS pathid,
            @lastid := mylist.id AS id,
            @id := (SELECT parentID FROM nav  WHERE id = @id) AS parentID
        FROM
            (SELECT @id := 0, @lastid := 0, @rownum := 0) AS vars,
            (SELECT id FROM nav) AS myloop,
            (SELECT id FROM nav) AS mylist
    ) AS t
    INNER JOIN nav
        ON t.id = nav.id
WHERE
    pathid = 2  // all subitems from id=2
于 2013-01-27T22:28:00.677 に答える
1

データベースの制約を通じてそれを行います。

次のテーブルがあるとします

ここに画像の説明を入力

メイン レコードの削除によってレコードがカスケードで削除されるように、両方の関係を定義できます。

phpMyAdmin での例:

//ディレクトリ

ここに画像の説明を入力

//ファイル

ここに画像の説明を入力

ここで、id=10 のディレクトリ「03」を削除します

//ディレクトリ

ここに画像の説明を入力

//ファイル

ここに画像の説明を入力

ご覧のとおり、ノードの子であった両方のテーブルのすべてのレコードが削除されました。非常に迅速で、スクリプトは必要ありません。

ここに小さなダンプがあります:

CREATE TABLE IF NOT EXISTS `directories` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `parent_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `parent_id` (`parent_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=cp1250 AUTO_INCREMENT=13 ;

INSERT INTO `directories` (`id`, `name`, `parent_id`) VALUES (0, 'root', 0),(6, '02', 0), (10, '03', 0),(11, '031', 10),(12, '032', 10);

CREATE TABLE IF NOT EXISTS `files` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `directory_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `directory_id` (`directory_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=cp1250 AUTO_INCREMENT=7 ;


INSERT INTO `files` (`id`, `name`, `directory_id`) VALUES (2, '031_f01', 11),(3, '031_f02', 11),(4, '02_f01', 6),(6, '02_f02', 6);


ALTER TABLE `directories`
  ADD CONSTRAINT `directories_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `directories` (`id`) ON DELETE CASCADE;

ALTER TABLE `files`
  ADD CONSTRAINT `files_ibfk_1` FOREIGN KEY (`directory_id`) REFERENCES `directories` (`id`) ON DELETE CASCADE;
于 2013-01-27T22:43:30.030 に答える