Предметы из нескольких категорий: лучшие практики

Я составляю список элементов по категориям, проблема в том, что элемент может быть в нескольких категориях. Как лучше всего хранить элементы в категориях и как перечислить все элементы в категории и ее дочерних категориях? Я использую Zend Framework и MySQL для решения этой проблемы.

Спасибо за ответы.

Извините за мой английский :)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
3
0
2 257
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Итак, у вас есть иерархия категорий, да? Это один уровень (категория и дочерняя категория) или любое количество (дети могут иметь детей и т. д.)? Это повлияет на решение.

Как правило, вы бы смоделировали что-то подобное с помощью отношения «многие ко многим», например:

CREATE TABLE Item(
  item_id INT NOT NULL, 
  item_name VARCHAR(255) NOT NULL
)
CREATE TABLE Category(
  category_id INT NOT NULL, 
  category_name VARCHAR(255) NOT NULL
)
CREATE TABLE Item_Category(
  item_id INT NOT NULL REFERENCES Item(item_id), 
  category_id INT NOT NULL REFERENCES Category(category_id)
 )

Запись в «Item_Category» означает, что указанный элемент находится в указанной категории. Затем вы можете объединить 2 (или 3) из этих таблиц, чтобы перечислить, какие элементы относятся к каким категориям:

SELECT I.* 
  FROM Item I 
    INNER JOIN Item_Category IC ON I.item_id = IC.item_id 
    INNER JOIN Category C on IC.category_id = C.category_id 
  WHERE 
    C.category_name = 'MyCategory'

Или какие категории есть у предмета:

SELECT C.*
  FROM Category C
    INNER JOIN Item_Category IC.category_id = C.category_id 
    INNER JOIN Item I on IC.item_id = I.item_id
  WHERE 
    I.item_name = 'MyItem'

Если в категориях есть иерархия, это можно выразить с помощью рекурсивной связи в таблице категорий, например:

CREATE TABLE Category(
  category_id INT NOT NULL, 
  category_name VARCHAR(255) NOT NULL,
  parent_category_id INT NOT NULL REFERENCES Category(category_id)
)

Это усложняет ситуацию, потому что вам нужно использовать рекурсивные запросы, чтобы получить все записи для категории и ее дочерних элементов. Более простой способ, если у вас есть только два уровня категорий, это просто сделать его вторым полем в таблице категорий, например:

CREATE TABLE Category(
  category_id INT NOT NULL, 
  category_name VARCHAR(255) NOT NULL,
  subcategory_name VARCHAR(255) NULL
)

И чтобы было ясно, в этой последней версии таблицы категорий есть одна запись на подкатегорию. Так что на самом деле ее следует называть таблицей подкатегорий с PK "subcategory_id".

Ian Varley 17.12.2008 20:14

если элемент может быть в нескольких категориях, то это не «категории». они больше похожи на теги.

используйте отношения "многие ко многим" между вашими элементами и вашими тегами. если вам нужна иерархия тегов, дерзайте; но это обычно излишне и очень редко добавляет ценности.

Как правило, лучшее решение, которое я нашел, которое работает в большинстве ситуаций, - это просто использовать поле parent_id в таблице категорий. Таким образом, вам понадобится только одна таблица категорий. Это будет поддерживать любое количество уровней или только один, если хотите (в этом случае в вашем коде необходимо предотвратить возможность создания третьего уровня категории).

Например:
CREATE TABLE category ( id INT NOT NULL AUTO_INCREMENT, parent_id INT NOT NULL DEFAULT '0' name VARCHAR(255) NOT NULL ) Так проще. Любая категория с parent_id, равным 0, будет вашим самым верхним уровнем. Если у вас есть категория, идентификатор которой равен 1, и вы создаете подкатегорию, ее parent_id будет равен 1 и т. д.

Другие вопросы по теме