Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Наследование в базах данных 
:(
    Опции темы
taral
Дата 23.3.2009, 02:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 230
Регистрация: 17.1.2008

Репутация: нет
Всего: нет



Доброго времени суток. Возникла у меня такая задачка.
Есть каталоги (допустим) такой структуры.
Биология
   Медицина
   Экология
   Ботаника
      Деревья
      Кусты
Математика
   Теория вероятности
   Математический анализ
...

Вложенность неограниченная. Эту структуру я храню в базе по методу Nested Sets (статья http://www.internet-technologies.ru/articl...ticle_635.html)
Теперь главное. В другой таблице я задаю title к каталогу Биология - 'супер сайт раздел - Биология'.
Теперь когда мы находимся в каталоге Биология, Медицина, Экология, Ботаника, Деревья или Кусты title должен быть 'супер сайт раздел - Биология'
Если я задам title для каталога Ботаника то у каталогов Ботаника Деревья Кусты title изменится соответствующим образом.
Что то подобное наблюдается в css стилях. Более "глобокий" стиль перекрывает другие. Надеюсь мне удалось объяснить задачу.
Задача. Нету излишних данных. Для любого каталога можно получить title одним запросом.
Идеальное решение если можно одним (это не принципиально но..) запросом получить все title для всех каталогов.
Я придумал 2 решения. Но оба мне не нравятся. Возможно кто то знает как это реализовать лучше всего? Спасибо за внимание.
PM MAIL   Вверх
ksnk
Дата 23.3.2009, 08:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 96
Всего: 386



taral, вообще-то есть еще стандартная для NS задача - получить всех предков узла... Оно?





--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
taral
Дата 23.3.2009, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 230
Регистрация: 17.1.2008

Репутация: нет
Всего: нет



Цитата

taral, вообще-то есть еще стандартная для NS задача - получить всех предков узла... Оно?

Спасибо за ответ. Но нет. Это не то. Как получить предком и всех родителей я знаю. Тут задача другая.
Видно тут моя вина что я не точно описал что я хочу. Сейчас попробую.
Сперва.
Структура таблицы catalogs.
Думаю понятно где и какие поля. Заполним таблицу для примера.
Код
 id title        cleft cright clevel.
1  билогия       2     13     1
2  медицина      3      4     2
3  экология      5      6     2
4  Ботаника      7     12     2
5  Деревья       8      9     3
6  Кусты        10     11     3
7  Математ.     14     19     1
8  Теория в.    15     16     2
9  М. анализ    17     18     2

Хух.
И есть таблица titles
Код
id    catalog_id    title
1        1          супер биология
2        4          супер ботаника
3        7          математика

И задача. Максимально просто получить какой title будет у категории с id 3.
Главное тут вот что. У меня уже есть 2 решения. Я позже их напишу. Потому тут главное не решение, а каким образом все это красиво реализовать. Веди известно если структура базы не правильная, то ту же задачу можно реализовать огромным количеством кода. Хотя в ином случае это можно сделать одним запросом в базу. Еще нюанс. Структура таблицы titles не окончательная. Предлагайте лучшие варианты и я с радостью их приму.
Что то типа справки если кто не захочет переходить по ссылке и изучать метод Nested Sets, а сам его не знает.
У текущей структуры таблицы catalogs мы можем лиш одним запросом получить всех детишек любой категории. И сех ее родителей.
Вот эти запросы.
Получить всех детишек каталога билогия (id 1, cleft 2 , cright 13)
Код
SELECT FROM catalogs WHERE cleft BETWEEN 2 AND 13 ORDER BY cleft

Получить всех родителей каталога Кусты  ( id  6, cleft   10, cright  11)
Код
SELECT FROM catalogs WHERE cleft < 10 AND cright  > 11


Один из вариантов решений что я обещал написать позже (поскольку тогда не успевал)
А именно вот он.
К примеру получение title для каталога Деревья.
Сперва. Узнаем cleft и cright этого каталога. (первый запрос в базу).
В нашем примере это 8   и  9.
Получаем id всех родителей этого каталога через cleft и cright что мы нашли в первом запросе. (второй запрос в базу)
Мы получили id 5, 4, 1 (пусть сам каталог будет для себя тоже родителем)
И третим запросом получаем title.
Код
SELECT t.title, c.id
FROM catalogs as c 
JOIN titles as t ON t.catalog_id=c.id // связываем 2 таблицы.
WHERE c.cleft<8 AND c.cright>9 ORDER BY c.cleft DESC LIMIT 1. // в данном случае мы сортируем все полученные результаты в порядке от ближнего родителя к дальнему и берем первый попавшийся. Таким образом получаем что нужно.
Кажется правильно написал.
Способ неплохой как на меня. Но. Если мне нужно получить title для 10 каталогов (в случае с title конечно такое не понадобится. Но в моем случае такая задача есть.) То будет 20 запросов в базу. Что мне не нравится. Это конечно не смертельно. Поскольку такая задача будет происходить из админки и достаточно редко. Но всеже.
Второй вариант. Мне нравится меньше. Из за излишка хранимой информации.
В таблице titles будет столько же записей как и в таблице catalogs. В отличие от
Код
id    catalog_id    title
1        1          супер биология
2        4          супер ботаника
3        7          математика

Будет 
Код
id    catalog_id    title
1        1          супер биология
2        2          супер биология
3        3          супер биология
4        4          супер   ботаника
5        5         супер    ботаника
6        6         супер    ботаника
....

Если мы изменяем title у каталога билогия то автоматом изменяется title у всех детишек если он был равен старому значению title.
Ну вот собсно и все.

Это сообщение отредактировал(а) taral - 23.3.2009, 15:43
PM MAIL   Вверх
ksnk
Дата 23.3.2009, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 96
Всего: 386



Легко! Получим title для 5 элементов. (1,3,5,7,9)
Код

select 
  t.title, x.id, 
  x.name from (select * from catalogs where id in (1,3,5,7,9)) as x, 
  catalogs as c left join titles as t on c.id=t.catalog_id
where
  c.cleft<=x.cleft and 
  c.cright>=x.cright 
group by x.id;

Правда мне почему-то этот sql напоминает бред  smile Хотя работает! 
Как оно будет работать на больших объемах данных мне пока сложно представить... Скорее всего медленно и печально, впрочем - не проверял...


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
taral
Дата 23.3.2009, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 230
Регистрация: 17.1.2008

Репутация: нет
Всего: нет



Цитата

Правда мне почему-то этот sql напоминает бред  smile Хотя работает! 
Как оно будет работать на больших объемах данных мне пока сложно представить... Скорее всего медленно и печально, впрочем - не проверял...

Вот это уже ближе к делу. Огромное спасибо за старания. Правда как вы сказали 
Цитата

Как оно будет работать на больших объемах данных мне пока сложно представить... Скорее всего медленно и печально

Но в любом случае это получше будет моих вариантов.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0518 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.