MySQL query - индентификация данных с использованием имен URL, где данные организованы в иерархию - PullRequest
1 голос
/ 09 октября 2011

У меня есть таблица MySQL под названием content, в которой хранятся данные контента для системы управления контентом.

ПРИМЕЧАНИЕ. Весь контент организован в иерархию с использованием столбца родительского идентификатора.

+----+------------+-----------------+--------+
| id | slug       | content_type_id | parent |
+----+------------+-----------------+--------+
|  1 | portfolio  |               5 |      0 |
|  2 | about-us   |               1 |      0 |
|  3 | find-us    |               1 |      0 |
|  4 | contact-us |               1 |      2 |
|  5 | find-us    |               1 |      4 |
+----+------------+-----------------+--------+

Мне нужен запрос, чтобы выбрать правильную строку в таблице в зависимости от того, как называется слаг.Проблема в том, что слизни имеют одинаковое имя.

У меня есть два возможных пути, которые пользователь может посетить:

/find-us/

и

/about-us/contact-us/find-us/

Я могу подуматьодного решения:

, который должен создать другой столбец с полными путями:

full_path
--------
/portfolio/
/about-us/
/find-us/
/about-us/contact-us/
/about-us/contact-us/find-us/

Но есть ли какие-нибудь умные методы, которые я могу использовать, чтобы выбрать правильную строку.Я не уверен, что создание другого столбца с полными путями - это отличная идея (потому что они могут измениться), лично я хотел бы использовать это только в качестве крайней меры.

Спасибо.

1 Ответ

0 голосов
/ 09 октября 2011

Это было бы возможно, если бы ваша СУБД поддерживала рекурсивные запросы:

DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;

CREATE TABLE tmp.webmeuk
    ( id INTEGER NOT NULL PRIMARY KEY
    , slug VARCHAR
    , content_type_id INTEGER NOT NULL
    , parent_id INTEGER REFERENCES tmp.webmeuk(id)
    );
INSERT INTO tmp.webmeuk( id , slug, content_type_id , parent_id )
VALUES(  0 , 'HTTP://pr0n.mysite.xx',    5 , NULL )
    , (  1 , 'portfolio',   5 , 0 )
    , (  2 , 'about-us',    1 , 0 )
    , (  3 , 'find-us',     1 , 0 )
    , (  4 , 'contact-us',  1 , 2 )
    , (  5 , 'find-us',     1 , 4 )
    ;

-- a room with a view
CREATE VIEW tmp.reteview AS (
    WITH RECURSIVE xx AS (
        SELECT w0.id AS id
        , w0.slug AS slug
        , w0.content_type_id AS content_type_id
        , w0.slug AS fullpath
        FROM tmp.webmeuk w0
        WHERE w0.parent_id IS NULL
      UNION 
        SELECT w1.id AS id
        , w1.slug AS slug
        , w1.content_type_id AS content_type_id
        , xx.fullpath || '/'::text || w1.slug AS fullpath
        FROM tmp.webmeuk w1, xx
        WHERE w1.parent_id = xx.id
        )
    SELECT * FROM xx
    );

SELECT * FROM tmp.reteview ;

-- Change one row of data
UPDATE tmp.webmeuk
SET slug = 'what-about-us'
WHERE id = 2;

SELECT * FROM tmp.reteview ;

Выход:

NOTICE:  drop cascades to 2 other objects
DETAIL:  drop cascades to table tmp.webmeuk
drop cascades to view tmp.closure
DROP SCHEMA
CREATE SCHEMA
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "webmeuk_pkey" for table "webmeuk"
CREATE TABLE
INSERT 0 6
CREATE VIEW
 id |         slug          | content_type_id |                     fullpath                  
----+-----------------------+-----------------+---------------------------------------------------
  0 | HTTP://pr0n.mysite.xx |               5 | HTTP://pr0n.mysite.xx
  1 | portfolio             |               5 | HTTP://pr0n.mysite.xx/portfolio
  2 | about-us              |               1 | HTTP://pr0n.mysite.xx/about-us
  3 | find-us               |               1 | HTTP://pr0n.mysite.xx/find-us
  4 | contact-us            |               1 | HTTP://pr0n.mysite.xx/about-us/contact-us
  5 | find-us               |               1 | HTTP://pr0n.mysite.xx/about-us/contact-us/find-us
(6 rows)

UPDATE 1
 id |         slug          | content_type_id |                        fullpath                    
----+-----------------------+-----------------+--------------------------------------------------------
  0 | HTTP://pr0n.mysite.xx |               5 | HTTP://pr0n.mysite.xx
  1 | portfolio             |               5 | HTTP://pr0n.mysite.xx/portfolio
  3 | find-us               |               1 | HTTP://pr0n.mysite.xx/find-us
  2 | what-about-us         |               1 | HTTP://pr0n.mysite.xx/what-about-us
  4 | contact-us            |               1 | HTTP://pr0n.mysite.xx/what-about-us/contact-us
  5 | find-us               |               1 | HTTP://pr0n.mysite.xx/what-about-us/contact-us/find-us
(6 rows)
...