"Многие ко многим" либо альтернативная структура

Frenk

Guest
"Многие ко многим" либо альтернативная структура

Давненько сюда не заглядывал. Привет всем!
Итак:
Имеется таблица товаров:
id | товар
товаров порядка 40 тыс.
Имеется таблица пользователей
id | имя
Каждый пользователь имеет отношение к каким-либо товаром. Может к одному, но может и к 100-1000.
Каким образом осуществить эту связь. На ум приходит самое очевидное решение:
Создать таблицу типа многие ко многим:
id пользователя | id товара.
Но тут есть маленькая загвоздочка - дело в том, что каталог товаров трех-уровневый.
Т.е. каждый товар в своей подкатегории, а каждая подкатегория, в свою очередь, в своей категории.
Таким образом, имея приведенную выше таблицу, будет довольно трудоемко вычислить сумму пользователей, имеющих отношение к категории/подкатегории.
Можно, конечно, сделать три таблицы отношений, но ...
Может, есть более красивое решение?
 

HEm

Сетевой бобер
id пользователя / id товара / уровень категории / тип (если на одном уровне могут быть и товары и категории)

-~{}~ 26.05.04 13:59:

тип = товар|категория
 

Demiurg

Guest
>Таким образом, имея приведенную выше таблицу, будет довольно трудоемко вычислить сумму пользователей, имеющих отношение к категории/подкатегории.
Почему трудоемко ? с правильно настроеными индексами никаких проблем быть не должно.

-~{}~ 26.05.04 14:01:

HEm
предлагаешь денормализовать базу ?
 

Frenk

Guest
Что значит: "вычислить сумму пользователей"?
Хмм. Есть товар. К нему имеют отношение, к примеру, три пользователя.
К другому товару в этой-же ПОДкатегории имеют отношение еще 3 пользователя. В следующей подкатегории нашей КАТЕГОРИИ есть еще куча товаров и куча пользователей, имеющих отношение к товару.
Задача - быстро вычислить сумму пользователей, имеющих отношение к каким-либо товаром в заданной категории.
если на одном уровне могут быть и товары и категории
Нет. Структура жесткая.
У каждой категории свой код. Свой код также имеют подкатегории и товары.
 

HEm

Сетевой бобер
Demiurg
теоретически это неправильно, да
но на практике бывает, что удобно, особенно если количество уровней неизвестно

впрочем, в случае Frenk, похоже напряга не будет, достаточно только правильно сформулировать запрос и сделать индексы

-~{}~ 26.05.04 14:30:

Автор оригинала: Frenk
Нет. Структура жесткая.
У каждой категории свой код. Свой код также имеют подкатегории и товары.
а почему тогда категории в одной таблице с товарами?
 

Frenk

Guest
а почему тогда категории в одной таблице с товарами?
Мдя. Структура такова:

id | shifr | kat_id | pap_id | kod | name
Поле shifr - ... не важно, в общем.
Итак Kod =0 - категория, kod=1 - подкатегория, kod=2 - товар.
Далее объяснять, надеюсь, нет смысла?
 

Falc

Новичок
Я так и не понял какую "сумму пользователей" ты хочешь считать и почему у тебя это вызывает проблему?
 

Demiurg

Guest
Frenk
а зачем мешать ? почеу не сделать 3 таблицы ?
 

Frenk

Guest
а зачем мешать ? почеу не сделать 3 таблицы ?
Такая структура мне показалось оптимальной. Все в одном, так сказать. Однако, в свете предыдущих вопросов, действительно было бы удобней сделать три, но...
Исходим из существующего варианта.
Задача прежняя. Вычислить сумму пользователей, имеющих отношение к каким-либо товаром в заданной категории.
Имеем таблицу отношений
id пользователя | id товара.
Это будет несколько запросов. Потребуется вытащить id товаров, имеющих отношение к ПОДкатегории/категории.
Затем аппелировать к таблице отношений. Как-то кривенько...
 

Demiurg

Guest
запро будет один
select count(desctinct users_goods.users_id) from
category , subcategory , goods, users_goods
where [ тут соеденяем все таблицы ] and category.category_id = $id
 

chira

Новичок
ты наверно примерно так уже пробовал?
Код:
SELECT t0.id, count(distinct tu.user_id) user_count
FROM tovar t0, tovar t1, tovar t2, tovar_user tu
WHERE t0.kod = 0 AND t0.id=t1.kod_id
  AND t1.kod = 1 AND t1.id=t2.kod_id
  AND t2.kod = 2 AND t2.id=tu.tovar_id
GROUP BY t0.id
 

Falc

Новичок
Demiurg, chira

Зачем соединять таблицы в WHERE если для этого предусмотрен специальный синтаксис?
 

Falc

Новичок
Demiurg
Зато подом дольше понимать, что с чем у тебя вяжется. Особено когда связываешь много таблиц и используешь алиасы.
 

Frenk

Guest
Ок. Сообразил.
Как в плане быстродействия?
 

Demiurg

Guest
Falc
согласен

Frenk
посмотри explain. 40 тыс - это не так много для mysql.
 

Demiurg

Guest
>ты про INNER JOIN .... USING(id)?
скорее про inner join ... on ...
 
Сверху