sql >> Databasteknik >  >> RDS >> Mysql

Hur implementerar man hierarkiska cms-webbplatser?

Här är tabellstrukturen som jag använde för att testa detta -

CREATE TABLE  `test`.`pages` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `slug` varchar(45) NOT NULL,
    `title` varchar(45) NOT NULL,
    `content` text NOT NULL,
    `parent_id` int(10) unsigned DEFAULT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `UQ_page_parent_id_slug` (`parent_id`,`slug`),
    CONSTRAINT `FK_page_parent_id` FOREIGN KEY (`parent_id`) REFERENCES `pages` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Notera den unika nyckeln på (parent_id, slug). Detta är nyckeln till att få bästa resultat från följande fråga. Jag testade detta med 50 000 rader och det returnerade fortfarande på mindre än 1 ms för en sökväg med fem sniglar - /cms/slug-1/slug-2/slug-3/slug-4/slug-5/

Här är PHP-koden som jag har kommit fram till för att skapa en lämplig fråga -

<?php

// I will assume the rest of the url has already been stripped away
$url = '/fruits/tropical/bananas/';

// lets just make sure we don't have any leading or trailing /
$url = trim($url, '/');

// now let's split the remaining string based on the /
$aUrl = explode('/', $url);

/**
* Now let's build the query to retrieve this
*/

// this array stores the values to be bound to the query at the end
$aParams = array();

$field_list = 'SELECT p1.* ';
$tables = 'FROM pages p1 ';
$where = "WHERE p1.parent_id IS NULL AND p1.slug = ? ";

// this array stores the values to be bound to the query at the end
$aParams[] = $aUrl[0];

// if we have more than one element in our array we need to add to the query
$count = count($aUrl);

for ($i = 1; $i < $count; $i++) {

    // add another table to our query
    $table_alias = 'p' . ($i + 1);
    $prev_table_alias = 'p' . $i;
    $tables .= "INNER JOIN pages $table_alias ON {$prev_table_alias}.id = {$table_alias}.parent_id ";

    // add to where clause
    $where .= "AND {$table_alias}.slug = ? ";
    $aParams[] = $aUrl[$i];

    // overwrite the content of $field_list each time so we
    // only retrieve the data for the actual page requested
    $field_list = "SELECT {$table_alias}.* ";

}

$sql = $field_list . $tables . $where;

$result = $this->db->query($sql, $aParams);


  1. Skapa en SQL Server-databas med SQLOPS

  2. mysql-transaktion - blanda infoga och välj för att uppnå last_insert_id?

  3. PDO-anslutning utan databasnamn?

  4. ORA-06502:PL/SQL:numeriskt eller värdefel:teckensträngsbuffert för liten