Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: EAV или Create table для фиксированнных наборов значений атрибутов?

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (3): [1] 2 3 »   

> Без описания
Anchor
Отправлено: 22 Апреля, 2015 - 14:06:26
Post Id


Новичок


Покинул форум
Сообщений всего: 57
Дата рег-ции: Май 2014  


Помог: 0 раз(а)




Всех приветствую.

Для БД универсального скрипта интернет-магазина был выбран паттерн Flate table. Т.е. значения товаров будут храниться не в одной таблице EAV, а для каждого типа товара будет создаваться таблица.

В таблицах типов будет много значений которые лучше куда-то отделить в "фиксированные наборы значений". Т.е. например "цвет", "текстура", "материал". Писать миллион раз в каждой записи "красный","желтый",... "пластмасса"... - вот от этого нужно избавиться. Вместо этого, естественно, будут id значений. И здесь, опять приходим к EAV vs Create table =)))
Итак, нужно определиться где хранить "фиксированные наборы значений", наподобие значений цветов, значений материалов. В одной таблице? Или для каждого атрибута создавать по таблице?

1.EAV. По идеи он так и просится сюда. Действительно, нам советуют EAV, тогда когда кол-во атрибутов велико, а количество записей не велико. Если делать таблицами - то они будут содержать мало записей. Недостатки EAV я думаю итак известны - это скорость, и сложность 3-хэтажных запросов. Но... Для меня как для человека учившегося на мат.факе, EAV, в первую очередь, не симпатичен тем, что коверкает самую основную идеологию РБД - relation, "отношения". Все последующее строение будет "оторвано" от математики. Не я не фанат) и тоже за практичные решения) Просто мое сугубо индивидуальное мнение, EAV целесообразен: Если 1)Атрибуты очень динамичны (каждые неск-ко часов и даже каждые 10мин, они изменяются/добавляются/удаляются) И ПРИ ЭТОМ 2)Кол-во записей таблиц(у которых меняется структура) очень велико (>1млн. записей). При одновременном выполнении этих условий - без EAV просто никак. Каждое изменение (ALTER TABLE) будет блокировать базу, и будет выполнятся очень долго.

2.Flate table. Насколько я понимаю, непосредственно кол-во таблиц в БД не значительно влияют на скорость. Встает лишь вопрос удобства. Но ведь ничего не мешает таблицам прилепить префикс "z_"/"zz_" и все они будут отображаться в конце БД. Хоть их там тыща - растут себе вниз БД да и все. А имена их заданы по строгому формату "zz_"."type_value_"."{atribute_name}"

Вообщем хочу услышать ваши мнения, приветствуются ЛЮБЫЕ рассуждения=)))

(Отредактировано автором: 22 Апреля, 2015 - 14:23:55)

 
 Top
Panoptik
Отправлено: 22 Апреля, 2015 - 15:31:32
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2493
Дата рег-ции: Нояб. 2011  
Откуда: Одесса, Украина


Помог: 131 раз(а)




как известно серебрянной пули нет, а то или инное решение принимается в зависимости от ситуации

помнится не так давно тут был холивар на тему ЕАВ и почему это плохо
вот ссылки для раздумий
http://www[dot]dbforums[dot]com/showthre[dot][dot][dot]o-people-hate-it
http://stackoverflow[dot]com/questio[dot][dot][dot]se-design-choice

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

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

Если же речь идет о неопределенном количестве атрибутов лично я бы использовал ЕАВ. И что касательно того что оно плохо работает то в ссылке СО выше есть примеры когда еав работает хорошо с миллионами данных и отлично справляется с задачами в известной системе Магенто. Так что смотрите сами

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


-----
Just do it
 
 Top
DeepVarvar Супермодератор
Отправлено: 22 Апреля, 2015 - 15:59:15
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Последнее что я похожее реализовал: составляемые пользователем формы для заполнения, которые, потом, нужно еще и статистически выводить.

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

Так вот.
Я обошелся тремя таблицами:

CODE (SQL):
скопировать код в буфер обмена
  1. CREATE TABLE IF NOT EXISTS `templates` (
  2.   `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  3.   `project_id` bigint(20) UNSIGNED NOT NULL,
  4.   `in_archive` tinyint(1) NOT NULL,
  5.   `type` tinyint(1) UNSIGNED NOT NULL DEFAULT '0',
  6.   `title` varchar(255) NOT NULL,
  7.   PRIMARY KEY (`id`),
  8.   KEY `project_id` (`project_id`),
  9.   KEY `in_archive` (`in_archive`),
  10.   KEY `type` (`type`)
  11. ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;


CODE (SQL):
скопировать код в буфер обмена
  1. CREATE TABLE IF NOT EXISTS `templates_fields` (
  2.   `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  3.   `template_id` bigint(20) UNSIGNED NOT NULL,
  4.   `title` varchar(255) NOT NULL,
  5.   `field_type` enum('text','textarea','select','radio','checkbox','caption','separator') CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
  6.   `data_type` enum('none','varchar','text','bigint','decimal') CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
  7.   `required` tinyint(1) NOT NULL,
  8.   `extra` text,
  9.   `sort` tinyint(3) DEFAULT '0',
  10.   PRIMARY KEY (`id`),
  11.   KEY `template_id` (`template_id`),
  12.   KEY `sort` (`sort`)
  13. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CODE (SQL):
скопировать код в буфер обмена
  1. CREATE TABLE IF NOT EXISTS `templates_values` (
  2.   `field_id` bigint(20) UNSIGNED NOT NULL,
  3.   `value_varchar` varchar(255) DEFAULT NULL,
  4.   `value_text` text,
  5.   `value_bigint` bigint(20) DEFAULT NULL,
  6.   `value_decimal` decimal(20,2) UNSIGNED DEFAULT NULL,
  7.   KEY `field_id` (`field_id`)
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


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

CODE (SQL):
скопировать код в буфер обмена
  1.                 IF(
  2.                     cctf.data_type = 'varchar',
  3.                     cctv.value_varchar,
  4.                     IF(
  5.                         cctf.data_type = 'text',
  6.                         cctv.value_text,
  7.                         IF(
  8.                             cctf.data_type = 'bigint',
  9.                             cctv.value_bigint,
  10.                             IF(
  11.                                 cctf.data_type = 'decimal',
  12.                                 cctv.value_decimal,
  13.                                 ''
  14.                             )
  15.                         )
  16.                     )
  17.                 )

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

Не вникал, насколько мой выверт может помочь, но, хотябы натолкнет на мысли.
(Добавление)
А вообще это же у меня в велосипеде реализовано (правда там ГК, да, некогда разгребсти) - там две таблицы: название и значение, ессно там привязка к конкретному "товару" и ты не можешь создать два одинаковых свойства у одного. А еще там автокомплит по уже созданным свойствам.
 
 Top
MiksIr
Отправлено: 22 Апреля, 2015 - 16:46:46
Post Id


Забанен


Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014  


Помог: 10 раз(а)

[+]


Для универсального магазина "коробки", наверно нормально.

Т.е. написан то у вас бред во многом, в том числе и про "когда нужно использовать eav", и про "идеологию" (это eav то, который по сути - классическое многое-ко-многим - не реляционный?). А если взять нормальную СУБД, то и alert таблицы транзакционен и ничего не блокирует.

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

А вопрос производительности магазинов со сложными выборками по куче атрибутов лучше решать специализированными средствами - sphinx, lucent. Хороший повод, кстати, зарабатывать на этом, как разработчику.


-----
self-banned
 
 Top
esterio
Отправлено: 22 Апреля, 2015 - 16:52:43
Post Id



Активный участник


Покинул форум
Сообщений всего: 5025
Дата рег-ции: Нояб. 2012  
Откуда: Украина, Львов


Помог: 127 раз(а)




в мпдженто вроде как сделали EAV. и Flat как cache для EAV.
оно у них там норм работает.
 
 Top
DeepVarvar Супермодератор
Отправлено: 22 Апреля, 2015 - 16:59:23
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




В магенте то? Да там тупит все по страшному. Но да, лучше чем в виртуемарте ))
 
 Top
esterio
Отправлено: 22 Апреля, 2015 - 17:06:45
Post Id



Активный участник


Покинул форум
Сообщений всего: 5025
Дата рег-ции: Нояб. 2012  
Откуда: Украина, Львов


Помог: 127 раз(а)




DeepVarvar
я описал только EAV часть которую видел. сам не любитель. Но как коробочное решение очень даже неплохое. Но тупит там в основному Zend первый и очень тупые xml конфигы

(Отредактировано автором: 22 Апреля, 2015 - 17:07:43)

 
 Top
Anchor
Отправлено: 22 Апреля, 2015 - 17:49:39
Post Id


Новичок


Покинул форум
Сообщений всего: 57
Дата рег-ции: Май 2014  


Помог: 0 раз(а)




esterio пишет:
в мпдженто вроде как сделали EAV. и Flat как cache для EAV.
оно у них там норм работает.

Видимо не имели дело с Магенто (перекреститесь, слава Богу Улыбка ) =))) Нифига не норм у них=)))
Во-первых все тормозит крамешно. У меня на локале простая операция добавления товара занимает порой до 1,5минуты. Ну это ладно тормоза, даже не в этом суть то. Разрабы Магенто наплевались столько с этим EAV что сами хотели переделывать все на flate table. К примеру попробуйте в Магенто поделать сложные выборки по 10-15 атрибутам.

esterio пишет:
Flat как cache для EAV.
оно у них там норм работает.

Да, совершенно верно, он у них трансформируется в flat

MiksIr пишет:
А если взять нормальную СУБД, то и alert таблицы транзакционен и ничего не блокирует.

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

(Отредактировано автором: 22 Апреля, 2015 - 18:16:48)

 
 Top
DeepVarvar Супермодератор
Отправлено: 22 Апреля, 2015 - 18:09:10
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Anchor пишет:
Почему он считается антипаттерном?
Потому же, что goto и long_jmp.
 
 Top
MiksIr
Отправлено: 22 Апреля, 2015 - 18:13:43
Post Id


Забанен


Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014  


Помог: 10 раз(а)

[+]


Цитата:
Ок. Почему он считается антипаттерном?

Он им не считается. Рабочий механизм с известными плюсами и минусами. Минусы вполне себе весомые, но в некоторых случаях простота и компактность решения перевешивает их. Все зависит от характера магазина.

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

Или выборка снипетов товаров с базовыми характеристиками и вывод разных товаров "в перемешку": Есть у нас на странице 50 товаров из 50 разных категорий - получили запрос с 50-ю джойнами на разные таблицы.
(Добавление)
Anchor пишет:
Ну там видите как, допустим не заблокирует, но изменение структуры таблицы, помойму все равно будет оч. долго выполняться. Или я ошибаюсь?

Не, не будет долго. Да и пофиг, если честно, главное, что бы другие операции не тормозили. Другое дело, что большинство такие "скрипты" будет юзать на хостингах, где только MySQL и есть, а там не знаю как с этим обстоит ;) Вероятно плохо ;)


-----
self-banned
 
 Top
Anchor
Отправлено: 22 Апреля, 2015 - 18:20:22
Post Id


Новичок


Покинул форум
Сообщений всего: 57
Дата рег-ции: Май 2014  


Помог: 0 раз(а)




MiksIr пишет:
Не, не будет долго. Да и пофиг, если честно, главное, что бы другие операции не тормозили. Другое дело, что большинство такие "скрипты" будет юзать на хостингах, где только MySQL и есть, а там не знаю как с этим обстоит ;) Вероятно плохо ;)

А для какого кол-ва записей приемлемо? Просто я читал, (да и сам немного тестил), что alter для большого кол-ва записей долго выполняется. http://habrahabr[dot]ru/post/121129/ А то может эта проблема была актуальна 4 года назад=))
UPD: Ну да, MySQL=)

(Отредактировано автором: 22 Апреля, 2015 - 18:22:00)

 
 Top
MiksIr
Отправлено: 22 Апреля, 2015 - 18:34:28
Post Id


Забанен


Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014  


Помог: 10 раз(а)

[+]


Без понятия ;) Обычно когда говорят о проблемах подобного рода - подразумевают миллионы записей. Но в общем вопрос не корректен - зависит от ресурсов СУБД ;) На ноутбуке одно значение, на своем топовом сервере - другое ;)
Важно даже не время - в конце концов администратор может подождать. Важно - как блокируются таблицы при этом и насколько код к этому готов (например, к режиму "только чтение").
Это нужно уже поизучать и самому потестировать.


-----
self-banned
 
 Top
esterio
Отправлено: 22 Апреля, 2015 - 18:34:31
Post Id



Активный участник


Покинул форум
Сообщений всего: 5025
Дата рег-ции: Нояб. 2012  
Откуда: Украина, Львов


Помог: 127 раз(а)




Я рад что обошлось тем что работал с ней только две недели. Потом на другой проект перебросили. Но если так, то нужна брать NoSQL решение здесь. Конешно если у вас не коробочное решение
 
 Top
Panoptik
Отправлено: 22 Апреля, 2015 - 18:36:35
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2493
Дата рег-ции: Нояб. 2011  
Откуда: Одесса, Украина


Помог: 131 раз(а)




alter для 0,5кк+ будет уже чувствоваться в контексте минут, если данных не дай бог накапает на 2, 10кк то альтеры могут и в часах длиться. зависит от структуры, данных, индексов итд


-----
Just do it
 
 Top
Anchor
Отправлено: 23 Апреля, 2015 - 10:56:52
Post Id


Новичок


Покинул форум
Сообщений всего: 57
Дата рег-ции: Май 2014  


Помог: 0 раз(а)




Panoptik пишет:
помнится не так давно тут был холивар на тему ЕАВ и почему это плохо
вот ссылки для раздумий

Как я понимаю "недавно" речь шла не об этих ссылках, а о чем то свежем на форуме

Panoptik пишет:
http://www[dot]dbforums[dot]com/showthre[dot][dot][dot]o-people-hate-it
http://stackoverflow[dot]com/questio[dot][dot][dot]se-design-choice

Там темы 2010-го и 2007-го года, + к сожалению не силен в инглише. Буду благорен за ссылку на тему которую имели ввиду "недавно"

(Отредактировано автором: 23 Апреля, 2015 - 10:57:21)

 
 Top
Страниц (3): [1] 2 3 »
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


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



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB