Подтвердить что ты не робот

Необходимая информация о структуре базы данных

Im в настоящее время работает на сайте, который будет содержать каталог продуктов. Я немного новичок в дизайне базы данных, поэтому я ищу советы о том, как это сделать лучше всего. Я знаком с дизайном реляционной базы данных, поэтому я понимаю "многие для многих" или "один для многих" и т.д. (Взял хороший класс db в колледже). Вот пример того, что элемент может быть классифицирован как:

Propeller -> aircraft -> wood -> brand -> product.

Вместо того, чтобы писать то, что у меня есть, просто взгляните на этот образ, который я создал из функции конструктора phpmyadmin.

alt text http://www.usfultimate.com/temp/db_design.jpg

Теперь все это выглядело прекрасно и денди, пока я не понял, что категория "древесина" также будет использоваться под гребным винтом → airboat → (дерево). Это означало бы, что "дерево" нужно будет воссоздавать каждый раз, когда я хочу использовать его под другим родителем. Это не конец света, но я хотел знать, есть ли более оптимальный способ этого.

Кроме того, я стараюсь, чтобы эта вещь была настолько динамичной, насколько это возможно, чтобы клиент мог организовать свой каталог по мере того, как его потребности менялись.

* Edit. Подумал только о создании таблицы "тегов". Поэтому я мог бы назначить тег "дерево" или "металл" или "50inch" на 1 для многих предметов. Я бы по-прежнему сохранял тип родительского типа для основных категорий, но таким образом, категории не должны были бы проходить настолько глубоко и не было бы повторения.

4b9b3361

Ответ 1

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

Что Кевин Пено предлагает хороший совет и известен как граненый просмотр. Как Марсия Бейтс написала в После Dot-Bomb: Получение информации в Интернете В настоящее время "Поиск прав" , "... классифицированная классификация относится к иерархической классификации, поскольку реляционные базы данных относятся к иерархическим базам данных...".

В сущности, фасетный поиск позволяет пользователям выполнять поиск в вашем каталоге, начиная с любого "фасета", который они предпочитают, и позволять им фильтровать информацию, выбирая другие грани вдоль поиска. Обратите внимание: вопреки тому, как обычно задумываются системы тегов, ничто не мешает вам организовать некоторые из этих граней иерархически.

Чтобы быстро понять, что такое грандиозный поиск, есть некоторые демо, чтобы исследовать Проект интерфейса поиска фламенко - интерфейсы поиска, которые передаются.

Во-вторых, логика приложения:, которую предлагает Manitra, также является хорошим советом (как я понимаю), т.е. разделяя nodes и links дерева/графика в разных отношениях. Однако он называет "таблицу предков" (которая является гораздо более понятным именем) транзитивное закрытие ориентированного ациклического графа (DAG) (отношение достижимости). Помимо производительности, он значительно упрощает запросы, как сказал Манитра.

Но Я предлагаю view для такой "таблицы предков" (транзитивное закрытие), так что обновления выполняются в режиме реального времени и инкрементно, а не периодические с помощью пакетного задания. Существует код SQL (но я думаю, что он должен немного адаптироваться к конкретным СУБД) в документах, которые я упомянул в ответе на язык запросов для наборов графиков: вопрос моделирования данных, В частности, посмотрите Поддержание транзитивного закрытия графиков в SQL (.ps - postscript).

Соотношения продуктов и категорий

Первой точкой Манитра также стоит подчеркнуть.

То, что он говорит, заключается в том, что между продуктами и категориями существует отношение "многие ко многим". I.e.: каждый продукт может быть в одной или нескольких категориях и в каждой категории может быть ноль или более продуктов.

Указанные переменные отношения (relvars) Продукты и категории, такие отношения могут быть представлены, например, как рекурр-ПК с, по меньшей мере, атрибутами P # и С#, то есть номера продуктов и категорий (идентификаторы) в отношениях внешнего ключа с соответствующими Номера продуктов и категорий.

Это дополняет управление иерархиями категорий. Конечно, это всего лишь эскиз дизайна.

На гранжевом просмотре в SQL

Полезной концепцией реализации "граненного просмотра" является реляционное разделение или даже реляционные сравнения (см. нижнюю часть связанной страницы). То есть разделяя ПК (Продукты-Категории) на (растущий) список категорий, выбранных пользователем (фасетная навигация), то получается только продукты в таких категориях (конечно, категории считаются не все взаимоисключающими, в противном случае выбирая две категории, получим нулевые произведения).

СУБД на базе SQL обычно не хватает этих операторов (разделение и сравнение), поэтому я приводил ниже некоторые интересные статьи, которые реализуют/обсуждают их:

и т.д.

Здесь я не буду вдаваться в подробности, но взаимодействие между иерархиями категорий и просмотром фасетов требует особого внимания.

Отклонение от "плоскостности"

Я кратко рассмотрел статью, связанную с Pras, Управление иерархическими данными в MySQL, но я прекратил читать после этих нескольких строк во введении:

Введение

Большинство пользователей в тот или иной момент имеют рассмотрены иерархические данные в SQL базы данных и, без сомнения, управление иерархическими данными не какая реляционная база данных для. Таблицы реляционной база данных не является иерархической (например, XML), но это просто плоский список. Иерархические данные имеют родительский-родительский отношений, которые не являются естественными представленный в реляционной базе данных Таблица....

Чтобы понять, почему эта настойчивость в отношении плоскостности отношений просто бессмыслица, представьте себе куб в трехмерной декартовой системе координат: он будет идентифицирован по 8 координатам (триплетам), например P1 (x1, y1, z1), P2 (x2, y2, z2),..., P8 (x8, y8, z8) [здесь мы не связанные с ограничениями на эти координаты, так что они действительно представляют собой куб].

Теперь мы поместим этот набор координат (точек) в переменную отношения и назовем эту переменную Points. Мы будем представлять значение отношения Points в виде таблицы ниже:

Points|  x |  y |  z |
=======+====+====+====+
       | x1 | y1 | z1 |
       +----+----+----+
       | x2 | y2 | z2 |
       +----+----+----+
       | .. | .. | .. |
       | .. | .. | .. |
       +----+----+----+
       | x8 | y8 | z8 |
       +----+----+----+

Этот куб "сплющивается" простым актом представления его в виде таблиц? Является ли отношение (значение) тем же, что и его табличное представление?

Переменная отношения принимает значения в виде наборов значений точек в n-мерном дискретном пространстве, где n - число атрибутов отношения ( "столбцы" ). Что означает, что для n-мерного дискретного пространства должно быть "плоским"? Просто абсурд, как я писал выше.

Не поймите меня неправильно. Конечно, SQL - это плохо спроектированный язык и что SQL-базирующиеся СУБД полны особенностей и недостатков (NULL, избыточность,...), особенно плохих, СУБД -s-dumb-store (без ссылочных ограничений, ограничений целостности,...). Но это не имеет ничего общего с реляционными данными, фантазированными ограничениями, наоборот: больше они отворачиваются от него и хуже - результат.

В частности, реляционная модель данных, как только вы ее понимаете, не представляет проблемы в представлении любой структуры, даже иерархии и графиков, как я подробно описал со ссылками на опубликованные работы, упомянутые выше. Даже SQL может, если вы замаскируете свои недостатки, пропадает что-то лучше.

В разделе "Вложенная модель набора"

Я просмотрел оставшуюся часть в этой статье, и я не особенно впечатлен таким логическим дизайном: он предлагает путать два разных объекта, узлы и ссылки, в одно отношение, и это, вероятно, вызовет неловкость. Но я не склонен анализировать этот дизайн более тщательно, извините.


EDIT: Стефан Эггермонт возразил в комментариях ниже: "Плоская модель списка - это проблема. Это абстракция реализации, которая затрудняет достижение производительности...".

Теперь я хочу сказать, что:

  • эта "модель плоского списка" - это фэнтези: только потому, что одно изложение (представляет) отношения как таблицы ( "плоские списки" ) не означает, что отношения являются "плоскими списками" ( "объект" и его представления не одно и то же);
  • логическое представление (отношение) и физические данные хранения (горизонтальные или вертикальные разложения, сжатие, индексы (хеши, b + дерево, r-дерево,...), кластеризация, разбиение на разделы и т.д.) различны; одна из точек реляционной модели данных (RDM) состоит в том, чтобы отделить логику от "физической" модели (с преимуществами как для пользователей, так и для разработчиков СУБД);
  • производительность является прямым следствием физических данных хранения (реализации) и не логического представления (комментарий Eggermont является классическим примером логико-физическая путаница).

Модель RDM не ограничивает реализацию каким-либо образом; один может свободно вводить кортежи и отношения, как можно видеть. Отношения не обязательно. Файлы и кортежи - это не обязательно записи файла. Такое соответствие является немой реализацией прямого изображения.

К сожалению, реализация СУБД на основе SQL , слишком часто, нечеткие реализации прямого образа и они страдают низкой производительностью во множестве сценариев - OLAP/Продукты ETL существуют для устранения этих недостатков.

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

Конечно, точка не, что должен существовать "оптимальный" физический дизайн хранилища, но что любой дизайн физической памяти может быть абстрагирован красивым декларативным языком, основанным на реляционной алгебре/исчислениях (а SQL - пример плохой) или более непосредственно на языке логического программирования (например, Prolog, см. мой ответ на пролог в SQL-конвертер "). Хорошей СУБД должно быть изменение дизайна физической памяти" на лету" на основе статистики доступа к данным (и/или подсказок пользователя).

Наконец, в Eggermont комментирует утверждение: "Реляционная модель сжимается между облаком и предиэлером". Это еще одна бессмыслица, но я не могу дать опровержения здесь, этот комментарий уже слишком длинный.

Ответ 2

Прежде чем создавать иерархическую модель категории в своей базе данных, посмотрите эту статью, которая объясняет проблемы и решение (используя вложенные наборы).

Подводя итог, использование простой parent_category_id не очень хорошо масштабируется, и вам будет сложно записывать исполняемые SQL-запросы. Ответ заключается в использовании вложенных наборов, которые заставляют вас визуализировать вашу модель категории "многие ко многим" как наборы, которые вложены внутри других наборов.

Ответ 3

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

Однако я сомневаюсь, что это то, что вы хотите. Если я смотрю в категории Aircraft > Wood, то я бы не хотел видеть предметы из Boating > Wood. Есть две категории Wood, потому что они содержат разные элементы.

Ответ 4

Мои предложения

  • установите отношение "многие ко многим" между Item и Category, чтобы продукт отображался во многих иерархиях node (используется в ebay, sourceforge...)
  • сохранить иерархию категорий

Производительность по иерархии категорий

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

  • ChildId (идентификатор категории)
  • AncestorId (идентификатор родителя, родителя... всех категорий предков)

Это означает, что если у вас есть 3 категории: 1-Propeller > 2-plane > 3-wood

Затем таблица Ancestor будет содержать:

ChildId  AncestorId
1        2
1        3
2        3

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

Благодаря этой таблице вам понадобится только 1 соединение для запроса к категории (с ее дочерними элементами).

Если вам нужна помощь в создании таблицы Ancestor, просто дайте мне знать.

Ответ 5

Перед созданием иерархического категории в вашей базе данных, посмотрите эту статью, которая объясняет проблемы и решение (используя вложенные наборы).

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

Следует отметить, что идея "нескольких категорий" в основном заключается в том, как работает "тегирование". За исключением того, что в разделе "tagging" мы позволяем любому продукту иметь много категорий. Позволяя любому продукту находиться во многих категориях, вы разрешаете клиенту фильтровать свой поиск с помощью start ing , где они что они должны начать. Он мог бы нажимать на "самолеты", затем "дерево", затем "турбореактивный двигатель" (или что-то еще). Или они могут начать поиск с Вуда и получить тот же результат.

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

В целом результат в основном тот же, категории будут иметь естественную иерархию, , но этот предоставит еще большую гибкость.

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

EDIT: Я просто понял, что вы смутно упомянули об этом в своем ответе. Я на самом деле этого не замечал, но я думаю, что это похоже на то, что вы хотели бы сделать. В противном случае вы смешаете две иерархические системы в свою программу без особых преимуществ.

Ответ 6

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

Например, у нас были специальные теги, такие как 2009-ноябрь-Special. Любой продукт, подобный этому, мог быть показан на специальной странице на этом месяце. Поэтому нам не нужно было создавать специальную систему для обработки вращающихся спецсредств на первой странице, которую мы использовали только существующую систему тегов. Позже это можно было бы улучшить, чтобы скрыть те теги от потребителей и т.д.

Аналогично, вы можете использовать префиксы тегов, такие как: style: wood mfg: Nike, позволяющий выполнять относительно сложную категоризацию и детализацию без трудностей сложной перестановки базы данных или кошмаров EAV, все в системе тегов, которая дает вам больше гибкость для удовлетворения ожиданий пользователей. Помните, что пользователи могут рассчитывать на перемещение продуктов различными способами, чем вы, как база данных, и бизнес-владелец может ожидать. Использование системы тегов может помочь вам включить интерфейс для покупок без ущерба для вашего инвентаря или отслеживания продаж или всего остального.

Ответ 7

Теперь все это выглядело прекрасно и денди, пока я не понял, что категория "древесина" также будет использоваться под гребным винтом → airboat → (дерево). Это означало бы, что "дерево" нужно будет воссоздавать каждый раз, когда я хочу использовать его под другим родителем. Это не конец света, но я хотел знать, есть ли более оптимальный способ этого.

Что делать, если у вас есть самолет, который является деревянной конструкцией, но пропеллером может быть углеродное волокно, стекловолокно, металл, графит?

Я бы определил таблицу материалов и использовал ссылку на внешний ключ в таблице элементов. Если вы хотите поддерживать более одного материала (IE: скажем, металлическая переинформация или винты...), вам понадобится таблица corrollary/lookup/xref.

MATERIALS_TYPE_CODE таблица

  • MATERIALS_TYPE_CODE pk
  • MATERIALS_TYPE_CODE_DESC

PRODUCTS таблица

  • PRODUCT_ID, pk
  • MATERIALS_TYPE_CODE fk IF только один материал когда-либо ассоциируется

PRODUCT_MATERIALS_XREF таблица

  • PRODUCT_ID, pk
  • MATERIALS_TYPE_CODE pk

Я бы также относил продукты друг к другу с помощью таблицы corrollary/lookup/xref. Продукт может быть связан с более чем одним проданным продуктом:

KITTED_PRODUCTS таблица

  • PARENT_PRODUCT_ID, fk
  • CHILD_PRODUCT_ID, fk

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

Ответ 8

Вы можете легко протестировать свои проекты БД на http://cakeapp.com