sql >> データベース >  >> RDS >> Mysql

MySQLでリレーショナル階層をクロージャテーブルに変換するにはどうすればよいですか?

    これは、PHP / Propelでこのタスクを実行するために6〜7年前に完成させた古代のスクリプトです。うまくいけば、それは他の誰かに役立つでしょう:

    require_once 'common/Autoloader.php';
    require_once 'propel/Propel.php';
    \Propel::init('db/runtime-conf.php');
    
    function truncateHierarchy(\PropelPDO $propel) {
        /* @var $state \PropelStatement */
        $state = $propel->prepare('TRUNCATE database.person_hierarchy');
        $state->execute();
    }
    
    function insertHierarchy(\PropelPDO $propel, $length) {
        if ($length == 0) {
            $state = $propel->prepare('INSERT INTO database.person_hierarchy SELECT id, id, 0 FROM person;');
            $state->execute();
            return $state->rowCount();
        } else if ($length == 1) {
            $state = $propel->prepare('INSERT INTO database.person_hierarchy SELECT parent_person_id, id, 1 FROM person WHERE id != parent_person_id;');
            $state->execute();
            return $state->rowCount();
        } else {
            $sql = "INSERT INTO database.person_hierarchy \n";
            $sql .= "SELECT p.parent_person_id, c" . ($length - 1) . ".id, " . $length . " FROM database.person AS p \n";
            for ($i = 1; $i <= $length - 1; $i++) {
                $sql .= "LEFT JOIN person AS c" . $i . " ON " . ($i == 1 ? 'p.id' : 'c' . ($i - 1) . '.id') . " = c" . $i . ".parent_person_id \n";
            }
            $sql .= "WHERE p.parent_person_id != p.id \n";
            for ($i = 1; $i <= $length - 1; $i++) {
                $sql .= "AND c" . $i . ".parent_person_id != c" . $i . ".id \n";
            }
            echo $sql;
            $state = $propel->prepare($sql);
            $state->execute();
            return $state->rowCount();
        }
    }
    
    /* @var $connect \PropelConnection */
    $propel = \Propel::getConnection();
    $propel->beginTransaction();
    
    try {
        truncateHierarchy($propel);
        $propel->commit();
    } catch (\Exception $e) {
        error_log_exc($e);
        echo "Failed to truncate person hierarchy!\n";
        $propel->rollBack();
        exit();
    }
    
    $length = 0;
    $inserts = -1;
    while ($inserts !== 0 || $length != 10) {
        $propel->beginTransaction();
        try {
            $inserts = insertHierarchy($propel, $length);
            if ($inserts == 0) { 
                echo "No persons exist at length " . $length . ".\n";
            } else {
                echo $inserts . " rows inserted for length " . $length . ".\n";
            }
            $length++;
            $propel->commit();
        } catch (\Exception $e) {
            error_log_exc($e);
            echo "Failed to regenerate person hierarchy!\n";
            $propel->rollBack();
            exit();
        }
    }
    
    echo "Regenerated person hierarchy!\n";
    exit();
    



    1. 疑わしいモードの問題でスタックしているSQLServerデータベースを効率的に解決する

    2. Androidルームデータベースはすべてのデータをエクスポートしません

    3. djangoの複合主キー

    4. MariaDBでのサウンドの仕組み