• Как хранить товары с различными опциями в БД?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    В стародавние времена это действительно было проблемой.

    И обычно использовался п.2, который называется EAV, и который в нормальном виде (таблица всех атрибутов, таблица всех значений, и таблица-связка товар-атрибут-значение), хотя и является истинно реляционным решением, служил причиной кровавых слез не одного поколения программистов.

    Эта ситуация послужила одной из причин появления хранилищ для неструктурированных данных, таких как Монго, которые входят в очень широкую категорию NoSQL.
    Но сами по себе "документо-ориентированные базы данных" в качестве основного хранилища - это ад и проклятие, хуже EAV. Если EAV делает адом только работу с атрибутами товаров, то Монга делает проклятием работу со всей БД целиком. Забудьте об этой идее.

    Тем более что в последние годы появилось вполне достойное решение: во всех классических СУБД появилась поддержка JSON полей.
    То есть таблица товаров будет самая обычная, в которой есть общие поля типа цены, названия и прочее. А свойства хранятся в JSON поле. Беря, таким образом, лучшее из двух миров.

    На начальном этапе вы даже сможете делать поиск по атрибутам, используя нативные JSON функции. Но в дальнейшем поиск товаров, а так же фильтрацию по атрибутам на странице категории (так называемый "фасетный поиск") надо будет возложить на специальный поисковый движок (который тоже входит в широкую категорию "NoSQL", хотя ничего общего с документными БД не имеет, и БД, собственно, не является), такой как Эластик или Мантикора.

    Главное при этом хранить (либо в коде, либо в таблице категорий) эталонные структуры таких json полей, которые, во-первых, использовать как справочники для заполнения товаров (тупо чтобы помнить, что частота процессора называется freq, а не frequency), и чтобы собственно делать фасетные фильтры.
    Ответ написан
    5 комментариев
  • Как хранить товары с различными опциями в БД?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Ответ на вопрос "как хранить" зависит от того, какие данные вы будете запрашивать. То есть - от представлений данных, с которыми работает ваша программа (программы). Именно на основе этих представлений синтезируется полная модель даннных, хранящаяся в БД.
    В свое время, лет 25 назад, был (может, и сейчас есть) стандартизированный подход, называвшийся IDEF1 (это имя из стандарта) или Entity-RelationShip (это название процедуры), позволявший формальным образом синтезировать из этих, частных, представлений полную модель данных. И были программы, которые позволяли это делать. Я одной такой пользовался, ERwin называлась (AFAIK она жива и сейчас), но, в принципе, нужные процедуры можно выполнять и вручную. Описание процедуры на русском есть, как минимум одно, которое я знаю - в старой книге "Мартин Дж. Организация баз данных в вычислительных..."
    Короче, синтез модели ваших данных - это ваша задача, связанная со специфическими вашими задачами.
    Судя по информации из вашего вопроса, я могу только сказать, что:
    1. этот вариант вам явно не походит: данные из представления "Товары в корзине" включают товары из всех категорий, так что отделные таблицы для каждой категории - это костыль: ходить можно, а бежать - уже нет.
    2. В ItemOptions можно хранить данные для всех категорий - достаточно указать в каждой записи дополнительно к идентификатору товара идентификатор категории и идентификатор свойства. Потребуются ещё таблица категорий (идентификатор категории как первичный ключ плюс дополнительная информаци) и таблица свойств для каждой из категорий (идентифкатор свойства как первичный ключ, идентификатор категории - внешний, плюс дополнительная информация). Схема получается не очень уклюжая, но для работы в рамках реляционной модели более-менее годная (я когда-то такую и делал и с ней работал, но это было жутко давно). Насколько для вас такая схема пригодна - зависит от ваших моделей предствалений: например, будете ли вы в Корзине указывать дополнительную информацию из ItemOptions.
    3. NoSQL - это название больше коммерческое, а не техничекое: оно включает много разных технологий хранения в БД, единственным общим признаком которых является, что они - не реляционные. Под эту задачу мне видится годным вариант навигационной БД (это где каждая запись содержит физические ссылки на связанные с ней записи): сетевая, например. В настоящее время такие БД иногда ещё проходят под псевдонимом "графовая". Но, опять же, смотрите на нужные вам представления, в данном случае - обращайте внимание на пути доступа к данным (эти самые ссылки): навигационные БД в этом плане не так гибки, как реляционные, и отсутствие нужных ссылок может заставить ходить по кривым путям и убить тем самым производительность.
    Но это все теория, а что там сейчас на практике творится - я с уверенностью сказать не могу. Насколько я понимаю, там надо смотреь возможности конкретной СУБД - тем более, что производители часто называют их словом "гибридная", и надо понимать, что в этот гибрид попадает.
    Ответ написан
    2 комментария