Необходимый совет структуры базы данных

Это - действительно одна вещь, которую понял превратно Scott Meyers.

, Если существует фактический алгоритм, который соответствует тому, что необходимо сделать, тогда конечно, используйте алгоритм.

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

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

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

19
задан Roeland 4 November 2009 в 14:35
поделиться

8 ответов

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

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

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

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

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

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

Связь продуктов и категорий

Первый пункт Manitra также заслуживает внимания.

Он говорит о том, что между продуктами и категориями существует связь «многие-ко-многим». То есть: каждый продукт может относиться к одной или нескольким категориям, и в каждой категории может быть ноль или более продуктов.

Для заданных переменных отношения (relvars) продуктов и категорий такие отношения могут быть представлены, например, как relvar PC с at наименьшие атрибуты P # и C #, т.е. номера продуктов и категорий (идентификаторы) во взаимоотношениях внешнего ключа с соответствующими номерами продуктов и категорий.

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

О фасетном просмотре в SQL

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

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

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

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

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

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

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

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

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

По «Модели вложенных множеств»

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


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

Я имею в виду именно то, что:

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

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

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

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

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

27
ответ дан 30 November 2019 в 02:29
поделиться

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

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

10
ответ дан 30 November 2019 в 02:29
поделиться

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

Однако я сомневаюсь, что это то, что вам нужно. Если я ищу в категории Самолет> Дерево , то мне не нужны предметы из Катание на лодке> Дерево . Есть две категории Древесина , потому что они содержат разные предметы.

4
ответ дан 30 November 2019 в 02:29
поделиться

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

  • устанавливают связь «многие-ко-многим» между элементом и категорией, чтобы продукт мог отображаться во многих узлах иерархии (используется в ebay, sourceforge ...)
  • сохранить иерархию категорий

Эффективность иерархии категорий

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

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

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

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

ChildId  AncestorId
1        2
1        3
2        3

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

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

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

4
ответ дан 30 November 2019 в 02:29
поделиться

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

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

Следует отметить, что идея «нескольких категорий» в основном заключается в том, как работает «тегирование». За исключением того, что в «тегах» мы разрешаем любому продукту иметь много категорий. Разрешив любой продукт быть во многих категориях, вы даете клиенту полную возможность фильтровать свой поиск по запускать в там, где они считают нужным для запуска . Это может быть щелчок по «самолетам», затем по «дереву», затем по «турбореактивному двигателю» (или как-то еще). Или они могут начать поиск с Вуда и получить тот же результат.

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

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

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

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

3
ответ дан 30 November 2019 в 02:29
поделиться

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

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

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

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

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

2
ответ дан 30 November 2019 в 02:29
поделиться

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

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

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

MATERIALS_TYPE_CODE таблица

  • MATERIALS_TYPE_CODE pk
  • MATERIALS_TYPE_CODE_DESC

PRODUCTS table

  • PRODUCT_ID_116032] MATERIALSOD_ MATERIAL_ID_ , pk 116034] только один материал когда-либо был связан

PRODUCT_MATERIALS_XREF таблица

  • PRODUCT_ID , pk
  • MATERIALS_TYPE_CODE pk

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

KITTED_PRODUCTS таблица

  • PARENT_PRODUCT_ID , fk
  • CHILD_PRODUCT_ID , fk

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

pk
  • MATERIALS_TYPE_CODE fk IF только один материал когда-либо связан
  • PRODUCT_MATERIALS_XREF таблица

    • PRODUCT_ID , pk
    • MATERIALSODEk [11608] pk [11608] MATERIALSODE [11608] Я бы также связал продукты друг с другом, используя таблицу corrollary / lookup / xref. Продукт может быть связан с более чем одним продуктом в комплекте:

      KITTED_PRODUCTS таблица

      • PARENT_PRODUCT_ID , fk
      • CHILD_PRODUCT_ID , fk

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

      pk
    • MATERIALS_TYPE_CODE fk IF только один материал когда-либо был связан

    PRODUCT_MATERIALS_XREF таблица

    • PRODUCT_ID , pk
    • MATERIALSODEk [11608] MATERIALSODE [11608] Я бы также связал продукты друг с другом, используя таблицу corrollary / lookup / xref. Продукт может быть связан с более чем одним продуктом в комплекте:

      KITTED_PRODUCTS таблица

      • PARENT_PRODUCT_ID , fk
      • CHILD_PRODUCT_ID , fk

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

    2
    ответ дан 30 November 2019 в 02:29
    поделиться

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

    1
    ответ дан 30 November 2019 в 02:29
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: