Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Модель EAV (сущность - характеристики) / 25 сообщений из 53, страница 1 из 3
15.01.2014, 18:07:58
    #38527387
folder-pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
Доброго времени суток уважаемые форумчане.

Прошу помощи в доработке EAV.


Имеем упрощенную таблицу основных записей.



упрощенная схема хранения



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT
	jos_md_catalog_message_criterions.id,
	jos_md_catalog_message_criterions.message_id,
	jos_md_catalog_criterions_name.`name` AS param_name,
	jos_md_catalog_criterions_type.`name` AS type_name,
	jos_md_catalog_criterions_values.`values`
FROM
	jos_md_catalog_message_criterions
LEFT JOIN jos_md_catalog_criterions_name ON jos_md_catalog_message_criterions.id_criterions_name = jos_md_catalog_criterions_name.id
LEFT JOIN jos_md_catalog_criterions_type ON jos_md_catalog_criterions_name.id_type = jos_md_catalog_criterions_type.id
LEFT JOIN jos_md_catalog_criterions_values ON jos_md_catalog_message_criterions.id_criterions_values = jos_md_catalog_criterions_values.id



В чистом виде данные характеристик

[img] http://clip2net.com/clip/m0/1389792562-clip-7kb.png?nocache=1 [/img]

Теперь собственно проблема, необходимо выбрать нужные ID при поиске по этой таблице.
Делаем запрос

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT
	message_id
FROM
	jos_md_catalog_message_criterions
WHERE
	(
		(
			jos_md_catalog_message_criterions.`id_criterions_name` = '4'
			AND jos_md_catalog_message_criterions.`id_criterions_values` = '13'
		)
		OR (
			jos_md_catalog_message_criterions.`id_criterions_name` = '25'
			AND jos_md_catalog_message_criterions.`id_criterions_values` = '95'
		)
	)





пытаясь найти записи у которых есть характеристика 4 с ID значения 13
и 25 с ID значения 95

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


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT
	message_id
FROM
	jos_md_catalog_message_criterions
WHERE
	(
		(
			jos_md_catalog_message_criterions.`id_criterions_name` = '4'
			AND jos_md_catalog_message_criterions.`id_criterions_values` = '13'
		)
		AND (
			jos_md_catalog_message_criterions.`id_criterions_name` = '25'
			AND jos_md_catalog_message_criterions.`id_criterions_values` = '95'
		)
	)




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

Заранее благодарен за любую помощь.
...
Рейтинг: 0 / 0
15.01.2014, 18:09:40
    #38527391
folder-pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
Забыл дамп прикрепить
...
Рейтинг: 0 / 0
15.01.2014, 18:19:14
    #38527401
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
folder-proпытаясь найти записи у которых есть характеристика 4 с ID значения 13 и 25 с ID значения 95
Да щазз!

Шаблон:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT entity
FROM eav_table
GROUP BY entity
HAVING av_pairs_count = SUM(
( (attribute, value) = (att_1, val_1) )
OR
( (attribute, value) = (att_2, val_2) )
OR
....
)
...
Рейтинг: 0 / 0
15.01.2014, 18:24:50
    #38527409
folder-pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
Akina,

Возможно это хорошо ) но я вообще ничего не понял из того что вы написали, если не сложно, используйте названия таблиц из дампа.
Вообще ничего не понял...
...
Рейтинг: 0 / 0
15.01.2014, 18:26:48
    #38527412
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
AkinaШаблон:Да уж больно медленный шаблон-то...
...
Рейтинг: 0 / 0
15.01.2014, 18:44:26
    #38527431
folder-pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
SELECT
	jos_md_catalog_message_criterions.message_id
FROM
	jos_md_catalog_message_criterions
GROUP BY
	jos_md_catalog_message_criterions.message_id
HAVING
	2 = SUM(
		(
			(
				jos_md_catalog_message_criterions.id_criterions_name,
				jos_md_catalog_message_criterions.id_criterions_values
			) = (4, 13)
		)
		OR (
			(
				jos_md_catalog_message_criterions.id_criterions_name,
				jos_md_catalog_message_criterions.id_criterions_values
			) = (25, 95)
		)
	)
...
Рейтинг: 0 / 0
15.01.2014, 18:45:22
    #38527434
folder-pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
Akinafolder-proпытаясь найти записи у которых есть характеристика 4 с ID значения 13 и 25 с ID значения 95
Да щазз!

Шаблон:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT entity
FROM eav_table
GROUP BY entity
HAVING av_pairs_count = SUM(
( (attribute, value) = (att_1, val_1) )
OR
( (attribute, value) = (att_2, val_2) )
OR
....
)



непонятно что за поле av_pairs_count и что выдаст запрос...
...
Рейтинг: 0 / 0
15.01.2014, 18:48:29
    #38527436
folder-pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
folder-pro
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
SELECT
	jos_md_catalog_message_criterions.message_id
FROM
	jos_md_catalog_message_criterions
GROUP BY
	jos_md_catalog_message_criterions.message_id
HAVING
	2 = SUM(
		(
			(
				jos_md_catalog_message_criterions.id_criterions_name,
				jos_md_catalog_message_criterions.id_criterions_values
			) = (4, 13)
		)
		OR (
			(
				jos_md_catalog_message_criterions.id_criterions_name,
				jos_md_catalog_message_criterions.id_criterions_values
			) = (25, 95)
		)
	)



как доработать его, чтобы заработало, сейчас выдает null

вместо av_pairs_count подставлено 2
...
Рейтинг: 0 / 0
15.01.2014, 18:49:43
    #38527437
folder-pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
miksoft,

Вы предлагаете на каждый тип товара отдельную таблицу?

скажем 500 типов товаров, и 500+ таблиц где будут храниться характеристики?
...
Рейтинг: 0 / 0
15.01.2014, 18:57:48
    #38527445
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
folder-promiksoft,

Вы предлагаете на каждый тип товара отдельную таблицу?

скажем 500 типов товаров, и 500+ таблиц где будут храниться характеристики?В данный момент не предлагаю. Чтобы предлагать такие вещи, нужно очень хорошо знать задачу, что малореально в формате форума. Хотя, теоретически, и в 500 таблицах ничего страшного не вижу.

Я говорил и именно о самом запросе в рамках текущей ситуации. Уж хотя бы WHERE можно было бы добавить.
...
Рейтинг: 0 / 0
15.01.2014, 19:04:26
    #38527452
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
miksoftAkinaШаблон:Да уж больно медленный шаблон-то...
Конечно, это же идея, а не реализация.
...
Рейтинг: 0 / 0
15.01.2014, 20:51:34
    #38527521
folder-pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
Akinamiksoftпропущено...
Да уж больно медленный шаблон-то...
Конечно, это же идея, а не реализация.

Если предложили этот вариант, может объясните его суть? ибо вопрос не решен пока что...
...
Рейтинг: 0 / 0
15.01.2014, 20:59:42
    #38527527
folder-pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
miksoft,

Суть проекта.
есть доска объявлений - каталог товаров, у объявлений есть характеристики, у каждого раздела свои, "по типу яндекс маркета".
фильтров будет не мало, думаю до 500 шт.

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

записей основной таблицы будет в районе 500 000 шт.
если предположить что у каждого товара будет по 16 характеристик, то таблица jos_md_catalog_message_criterions будет содержать порядка 8 000 000 записей.

что в такой ситуации вы могли бы предложить?
...
Рейтинг: 0 / 0
15.01.2014, 21:10:29
    #38527531
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
Так Вы же суть поймали и составили в общем верный запрос...

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
mysql> create table eav(entity int, attrib int, val int);
Query OK, 0 rows affected (0.08 sec)

mysql> insert into eav (entity, attrib, val)
    -> select 1, 1, 1 union
    -> select 1, 2, 2 union
    -> select 2, 1, 1 union
    -> select 2, 2, 1 union
    -> select 3, 1, 2 union
    -> select 3, 2, 2 ;
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> select * from eav;
+--------+--------+------+
| entity | attrib | val  |
+--------+--------+------+
|      1 |      1 |    1 |
|      1 |      2 |    2 |
|      2 |      1 |    1 |
|      2 |      2 |    1 |
|      3 |      1 |    2 |
|      3 |      2 |    2 |
+--------+--------+------+
6 rows in set (0.00 sec)

mysql> select entity
    -> from eav
    -> group by entity
    -> having sum( (attrib, val) in ( (1,1), (2,2) ) );
+--------+
| entity |
+--------+
|      1 |
|      2 |
|      3 |
+--------+
3 rows in set (0.03 sec)

mysql> select entity
    -> from eav
    -> group by entity
    -> having 2 = sum( (attrib, val) in ( (1,1), (2,2) ) );
+--------+
| entity |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)

mysql> select entity
    -> from eav
    -> group by entity
    -> having 1 = sum( (attrib, val) in ( (1,1) ) );
+--------+
| entity |
+--------+
|      1 |
|      2 |
+--------+
2 rows in set (0.00 sec)

mysql>



Если запрос даёт NULL - либо нет запрошенных данных, либо есть дубликаты, либо ты в запросе таки накосячил.
...
Рейтинг: 0 / 0
15.01.2014, 21:20:47
    #38527539
folder-pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
Akina,

нет не накосячил, я просто не мог его суть понять и что там делает av_pairs_count
теперь суть понятна, спасибо.

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

из того что нагуглил, особо разобраться не смог (
...
Рейтинг: 0 / 0
15.01.2014, 21:22:59
    #38527541
folder-pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
Akina,

да и IN откуда взялось, в первом ответе было другое )
...
Рейтинг: 0 / 0
15.01.2014, 21:58:26
    #38527569
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
Akinafolder-proпытаясь найти записи у которых есть характеристика 4 с ID значения 13 и 25 с ID значения 95
Да щазз!

Шаблон:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT entity
FROM eav_table
GROUP BY entity
HAVING av_pairs_count = SUM(
( (attribute, value) = (att_1, val_1) )
OR
( (attribute, value) = (att_2, val_2) )
OR
....
)



Лучше всё же

Код: sql
1.
2.
3.
4.
5.
SELECT entity
FROM eav_table e
where exists ( select * from attribure a where e.entity_id = a.entity_id and a.attribute = 'att1' and a.value = @val_1 )
   and exists ( select * from attribure a where e.entity_id = a.entity_id and a.attribute = 'att2' and a.value = @val_2 )
-- ...
...
Рейтинг: 0 / 0
15.01.2014, 23:47:18
    #38527635
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
folder-proУ вас под рукой нет случайно статей на манипуляцию с этим шаблоном?Да я его прямо тут от руки набросал... какие нахрен статьи ещё. Потому, кстати, и дорабатываю, в частности
folder-proда и IN откуда взялось, в первом ответе было другое )
это по сути абсолютно то же самое, просто запись более читабельная.

MasterZivЛучше всё же
Тогда уж
Код: sql
1.
... exists ( select 1 from ...


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

К слову, для моего шаблона, если в таблице есть подходящий индекс (в коем поля идут в правильном порядке) - он будет использоваться.
...
Рейтинг: 0 / 0
16.01.2014, 12:12:40
    #38527984
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
MasterZivЛучше всё же
Тогда уж
Код: sql
1.
... exists ( select 1 from ...




разницы 0.


Но мой шаблон гораздо удобнее при неопределённом количестве пар... а если


не думаю.
...
Рейтинг: 0 / 0
16.01.2014, 12:33:07
    #38528034
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
MasterZiv , мне во всяком случае было бы удобнее, буде у меня возникла бы задачиа динамического построения текста запроса. В коде - и удобнее, и проще, отдельно условие, отдельно критерий, отдельно литералы сравнения, ничего не перемешано.
...
Рейтинг: 0 / 0
16.01.2014, 13:22:25
    #38528140
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
Akina MasterZiv , мне во всяком случае было бы удобнее,

Согласись, это далеко не самый важный критерий оценки текста запроса.
...
Рейтинг: 0 / 0
16.01.2014, 13:47:49
    #38528197
folder-pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
Akinafolder-proУ вас под рукой нет случайно статей на манипуляцию с этим шаблоном?Да я его прямо тут от руки набросал... какие нахрен статьи ещё. Потому, кстати, и дорабатываю, в частности
folder-proда и IN откуда взялось, в первом ответе было другое )
это по сути абсолютно то же самое, просто запись более читабельная.

MasterZivЛучше всё же
Тогда уж
Код: sql
1.
... exists ( select 1 from ...


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

К слову, для моего шаблона, если в таблице есть подходящий индекс (в коем поля идут в правильном порядке) - он будет использоваться.

сгенерил таблицу на 11000 характеристик для 2000 товаров, ваш запрос не желает индексы использовать...



подскажите как их правильно создать тогда, индексы
...
Рейтинг: 0 / 0
16.01.2014, 14:07:37
    #38528236
folder-pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
Akina,

...
Рейтинг: 0 / 0
16.01.2014, 14:28:40
    #38528278
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
folder-proсгенерил таблицу на 11000 характеристик для 2000 товаров, ваш запрос не желает индексы использовать...
Ага... possible keys IS NULL - а где подходящий индекс-то? трудно использовать то, чего нет.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
mysql> create index idx1 on eav(entity, attrib, val);
Query OK, 0 rows affected (0.35 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> explain
    -> select entity
    -> from eav
    -> group by entity
    -> having 2 = sum( (attrib, val) in ( (1,1), (2,2) ) );
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | eav   | index | idx1          | idx1 | 15      | NULL |    1 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

mysql>
...
Рейтинг: 0 / 0
16.01.2014, 14:44:39
    #38528319
Cygapb-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модель EAV (сущность - характеристики)
http://sqlfiddle.com/#!2/5e97c/1
Код: sql
1.
KEY id_nm_val (`message_id`,`id_criterions_name`,`id_criterions_values`)



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT
	message_id
FROM
	jos_md_catalog_message_criterions
WHERE 
  (`id_criterions_name`,`id_criterions_values`) in (
    (4,13),(25,93)
  )
group by message_id
having sum(
  (`id_criterions_name`,`id_criterions_values`) in (
    (4,13),(25,93)
  )
  )=2;


ID SELECT_TYPE TABLE TYPE POSSIBLE_KEYS KEY KEY_LEN REF ROWS FILTERED EXTRA1SIMPLEjos_md_catalog_message_criterionsindexid_nm_val154100Using where; Using index
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Модель EAV (сущность - характеристики) / 25 сообщений из 53, страница 1 из 3
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]