Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Bagaimana cara mengubah hierarki relasional menjadi tabel penutupan di MySQL?

Ini adalah skrip kuno yang saya selesaikan 6-7 tahun yang lalu untuk menyelesaikan tugas ini di PHP/Propel. Semoga bermanfaat untuk orang lain:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Menggunakan TIMESTAMP MySQL vs menyimpan stempel waktu secara langsung

  2. Desain Basis Data - Model Push, atau Fan-out-on-write

  3. Mengapa kueri dieksekusi dari meja kerja mysql membutuhkan waktu lebih lama daripada mengeksekusinya langsung dari cli mysql?

  4. Laravel 4 tidak dapat menjalankan seluruh kueri RAW

  5. Bagaimana cara menghasilkan interval waktu acak dan menambahkannya ke datetime mysql menggunakan php?