Alkeeper
Новичок
Нестандартный тип хранения данных и генерация запросов
Суть проблемы такова:
Есть каталог услуг произвольной структуры, грубо говоря, одна услуга имеет в детализации 5 полей, другая 10, третья еще сколько-то.
Типы данных почти не повторяются, поэтому при добавлении новой услуги делать каждый раз alter table не хочется.
Пришел к такой структуре БД
Табл. 1 - Типы услуг (общее описание, название типа, отношение к вышестоящим уровням дерева).
serv_id|serv_en|serv_ru|serv_description
Табл. 2 Типы Полей (по serv_id относятся к типам услуг)
var_id|serv_id|var_name|var_name_ru|possible_values|position
Табл. 3. Частные случаи услуг. (Общая информация для любой услуги)
id|serv_id|owner_id|s_name|s_description
Табл. 4 Значения переменных, характерных для конкретных типов услуг
value_id|var_id|s_id|value
Задача - вывести список услуг конкретного типа.
тип передается либо через GET, либо вытаскивается из request_uri при включенном mod_rewrite
Додумался до двух способов извлечения данных:
1. Заключается в следующем.
а) Первым запросом получаем названия переменных и формируем шапку для табличного представления.
б) Вторым запросом получаем общие данные по услугам из таблицы 3.
в) В цикле обращаемся к таблице значений, выдергиваем для каждой строки нужные данные в том же порядке, что и при формировании шапки
г) вложенным циклом добиваем эти значения в массивы к результату из таблицы 3.
Обновленные строки отдаем в шаблонизатор (смарти).
Недостатоки - высокая сложность при сортировке и наложении условий при выборке, большое количество запросов.
2. Состоит в идее 2х запросов.
а) Первый запрос - получение шапки (и латинских псевдонимов переменных)
б) Вторым шагом идет не запрос, а генерация второго запроса на основе результатов первого. т.е.
В цикле формируем составляющие Select, from и where (возмозжно и order by) след образом. при формировании селекта мы несколько раз просим вернуть value из табл. 4 каждый раз присваивая значению и запрашиваемой таблице разные псевдонимы (для этого нужны латинские псевдонимы из первого запроса)
т.е примерно так
select serv.*,var1_t.value as var1, var2_t.value as var2
from servises as serv, values as var1_t, values as var2_t
where var1_t.serv_id = serv.id and var1_t.var_id = '{$var[1]}' and var2_t.serv_id = serv.id and var2_t.var_id = '{$var[2]}' and serv.serv_type_id = '$sid'
массив $var приходит из первого запроса, $sid = определение типа выводимой услуге. через GET
вот пример реально сгенерированного запроса
SELECT
`serv`.*,
`valyuta_t`.`value` AS `valyuta`,
`min_srok_t`.`value` AS `min_srok`,
`maks_srok_t`.`value` AS `maks_srok`,
`min_stavka_t`.`value` AS `min_stavka`,
`maks_stavka_t`.`value` AS `maks_stavka`
FROM
`cat_services` AS `serv`,
`cat_service_values` AS `valyuta_t`,
`cat_service_values` AS `min_srok_t`,
`cat_service_values` AS `maks_srok_t`,
`cat_service_values` AS `min_stavka_t`,
`cat_service_values` AS `maks_stavka_t`
WHERE
`valyuta_t`.`serv_id` = `serv`.`s_id` AND `valyuta_t`.`var_id` = '118' AND
`min_srok_t`.`serv_id` = `serv`.`s_id` AND `min_srok_t`.`var_id` = '119' AND
`maks_srok_t`.`serv_id` = `serv`.`s_id` AND `maks_srok_t`.`var_id` = '120' AND
`min_stavka_t`.`serv_id` = `serv`.`s_id` AND `min_stavka_t`.`var_id` = '121' AND
`maks_stavka_t`.`serv_id` = `serv`.`s_id` AND `maks_stavka_t`.`var_id` = '122' AND
`serv`.`cid` = '3';
По идее если к результату этому запросу правильно сформировать доп. условия where и order by должен бы получиться еще и недурственный простор для экспериментов с поиском.
НО!!! при попытке выполнить один такой запрос локальная машина просто умирает. т.е. речь не идет даже о двух посетителях - первый нифига не увидит. На сервере даже побаиваюсь испытывать, ато ведь и от админа по шапке можно получить.
Есть ли какая-то альтернатива? хотя бы направление задайте???
Спасибо, что хватило терпения прочесть.
-~{}~ 28.02.06 11:51:
Странно, что никакой реакции, даже фраз "РТФМ" или "Выражайся яснее" не наблюдается.....
Суть проблемы такова:
Есть каталог услуг произвольной структуры, грубо говоря, одна услуга имеет в детализации 5 полей, другая 10, третья еще сколько-то.
Типы данных почти не повторяются, поэтому при добавлении новой услуги делать каждый раз alter table не хочется.
Пришел к такой структуре БД
Табл. 1 - Типы услуг (общее описание, название типа, отношение к вышестоящим уровням дерева).
serv_id|serv_en|serv_ru|serv_description
Табл. 2 Типы Полей (по serv_id относятся к типам услуг)
var_id|serv_id|var_name|var_name_ru|possible_values|position
Табл. 3. Частные случаи услуг. (Общая информация для любой услуги)
id|serv_id|owner_id|s_name|s_description
Табл. 4 Значения переменных, характерных для конкретных типов услуг
value_id|var_id|s_id|value
Задача - вывести список услуг конкретного типа.
тип передается либо через GET, либо вытаскивается из request_uri при включенном mod_rewrite
Додумался до двух способов извлечения данных:
1. Заключается в следующем.
а) Первым запросом получаем названия переменных и формируем шапку для табличного представления.
б) Вторым запросом получаем общие данные по услугам из таблицы 3.
в) В цикле обращаемся к таблице значений, выдергиваем для каждой строки нужные данные в том же порядке, что и при формировании шапки
г) вложенным циклом добиваем эти значения в массивы к результату из таблицы 3.
Обновленные строки отдаем в шаблонизатор (смарти).
Недостатоки - высокая сложность при сортировке и наложении условий при выборке, большое количество запросов.
2. Состоит в идее 2х запросов.
а) Первый запрос - получение шапки (и латинских псевдонимов переменных)
б) Вторым шагом идет не запрос, а генерация второго запроса на основе результатов первого. т.е.
В цикле формируем составляющие Select, from и where (возмозжно и order by) след образом. при формировании селекта мы несколько раз просим вернуть value из табл. 4 каждый раз присваивая значению и запрашиваемой таблице разные псевдонимы (для этого нужны латинские псевдонимы из первого запроса)
т.е примерно так
select serv.*,var1_t.value as var1, var2_t.value as var2
from servises as serv, values as var1_t, values as var2_t
where var1_t.serv_id = serv.id and var1_t.var_id = '{$var[1]}' and var2_t.serv_id = serv.id and var2_t.var_id = '{$var[2]}' and serv.serv_type_id = '$sid'
массив $var приходит из первого запроса, $sid = определение типа выводимой услуге. через GET
вот пример реально сгенерированного запроса
SELECT
`serv`.*,
`valyuta_t`.`value` AS `valyuta`,
`min_srok_t`.`value` AS `min_srok`,
`maks_srok_t`.`value` AS `maks_srok`,
`min_stavka_t`.`value` AS `min_stavka`,
`maks_stavka_t`.`value` AS `maks_stavka`
FROM
`cat_services` AS `serv`,
`cat_service_values` AS `valyuta_t`,
`cat_service_values` AS `min_srok_t`,
`cat_service_values` AS `maks_srok_t`,
`cat_service_values` AS `min_stavka_t`,
`cat_service_values` AS `maks_stavka_t`
WHERE
`valyuta_t`.`serv_id` = `serv`.`s_id` AND `valyuta_t`.`var_id` = '118' AND
`min_srok_t`.`serv_id` = `serv`.`s_id` AND `min_srok_t`.`var_id` = '119' AND
`maks_srok_t`.`serv_id` = `serv`.`s_id` AND `maks_srok_t`.`var_id` = '120' AND
`min_stavka_t`.`serv_id` = `serv`.`s_id` AND `min_stavka_t`.`var_id` = '121' AND
`maks_stavka_t`.`serv_id` = `serv`.`s_id` AND `maks_stavka_t`.`var_id` = '122' AND
`serv`.`cid` = '3';
По идее если к результату этому запросу правильно сформировать доп. условия where и order by должен бы получиться еще и недурственный простор для экспериментов с поиском.
НО!!! при попытке выполнить один такой запрос локальная машина просто умирает. т.е. речь не идет даже о двух посетителях - первый нифига не увидит. На сервере даже побаиваюсь испытывать, ато ведь и от админа по шапке можно получить.
Есть ли какая-то альтернатива? хотя бы направление задайте???
Спасибо, что хватило терпения прочесть.
-~{}~ 28.02.06 11:51:
Странно, что никакой реакции, даже фраз "РТФМ" или "Выражайся яснее" не наблюдается.....