Как лучше спроектировать БД?

Lord Maverik
На сайте с 15.04.2003
Offline
471
818

Есть основная запись, таблица. Допустим люди A.

У них есть набор опций B.

1. Есть такой вариант:

Таблица A

Таблица B

Таблица связей AB (a_id, b_id,value)

2. Есть такой вариант

Таблица A

Таблица B (особой роли не играет)

Текстовое поле в таблице A:

===========

b_id(1) = value

b_id(2) = value

b_id(3) = value

===========

В чем у меня проблема.Поиск может осуществляться сразу по нескольким полям и в результатах нужно показать значения всех полей.

В итог в первом варианте получается

LEFT JOIN AB as b1 ON (b1.id=a.id)

LEFT JOIN AB as b2 ON (b2.id=a.id)

LEFT JOIN AB as b3 ON (b3.id=a.id)

WHERE `b1.value`='value' OR `b2.value`='value' OR `b3.value`='value'

При большом количестве записей меня вся эта конструкция с кучей LEFT JOIN смущает совей производительностью

Во втором случае это просто

WHERE `option` LIKE 'pole1_value1%' OR `option` OR LIKE 'pole1_value1%' `option` OR LIKE 'pole1_value1%'

С одной стороны никаких join, с другой стороны LIKE c % тоже не лучший вариант.

Как все таки лучше поступить?

RedMall.Ru (https://redmall.ru) - Товары из Китая (Таобао, Tmall) с проверкой качества, скидка для форумчан 7% Партнерская программа 2 уровня: 5% + 5%. Подробнее. (https://redmall.ru/about/partner/)
C
На сайте с 26.10.2013
Offline
54
#1

Индексы по a_id и b_id проставить и нормально будут джоины по производительности

Уж точно лучше лайков

Услуги по парсингу данных (/ru/forum/939826), единоразовый и регулярный сбор данных. Любые объемы. Скрипты на PHP, создание и доработка, решение проблем с сайтами Пишите в личные сообщения или скайп
Lord Maverik
На сайте с 15.04.2003
Offline
471
#2
colorito:
Индексы по a_id и b_id проставить и нормально будут джоины по производительности

даже если таких join будет штук 10, а в основной таблице A под 200 000 записей и в таблице AB под миллион записей?

C
На сайте с 26.10.2013
Offline
54
#3

Ну, во первых, вам никто не мешает забить таблицу данными (рандом) и проверить

Во вторых, вот запрос, скажем, отрабатывает практически моментально на нормально настроенной базе. По количеству записей - category около 1000, products 25 000, product_catnum около 10 000, partsCategories 1 500 000, coordinates около двух миллионов

		SELECT DISTINCT `i`.`id` as image_id,
(select
cats2.`title`
from
category as cats1
inner join
category as cats2 on cats1.modelid = cats2.id
where
cats1.`id` = `i`.CategoryID
limit 1) as model_title,
(select `text` from textinfo where id =`i`.`nameID` limit 1) AS title
FROM (`products` p)
JOIN `product_catnum` pc ON `pc`.`product_id` = `p`.`id`
JOIN `partsCategories` pct ON `pct`.`catalog_num` = `pc`.`part_id`
JOIN `coordinates` c ON `c`.`partid` = `pct`.`id`
JOIN `images` i ON `i`.`id` = `c`.`imageID`
WHERE `p`.`id` = ' . $id
Lord Maverik:
даже если таких join будет штук 10, а в основной таблице A под 200 000 записей и в таблице AB под миллион записей?
dma84
На сайте с 21.04.2009
Offline
168
#4

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

doctorpc
На сайте с 12.07.2009
Offline
112
#5
Lord Maverik:

В чем у меня проблема.Поиск может осуществляться сразу по нескольким полям и в результатах нужно показать значения всех полей.
В итог в первом варианте получается
LEFT JOIN AB as b1 ON (b1.id=a.id)
LEFT JOIN AB as b2 ON (b2.id=a.id)
LEFT JOIN AB as b3 ON (b3.id=a.id)
WHERE `b1.value`='value' OR `b2.value`='value' OR `b3.value`='value'

При большом количестве записей меня вся эта конструкция с кучей LEFT JOIN смущает совей производительностью

Не совсем понятно, почему одного JOIN не достаточно?



LEFT JOIN AB ON (b1.id=a.id)
WHERE `AB.value`in ('value1', 'value2', 'value3')

bay_ebook
На сайте с 28.05.2010
Offline
111
#6
Lord Maverik:


При большом количестве записей меня вся эта конструкция с кучей LEFT JOIN смущает совей производительностью

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

Нужен прогер на php+mysql+понимание чужего кода? (/ru/forum/540660) Вам сюда PHP-шаман (http://php-shaman.pw/)
TA
На сайте с 12.06.2009
Offline
116
TiA
#7

Самым лучшим будет вариант:

Lord Maverik:

Таблица A
Таблица B
Таблица связей AB (a_id, b_id,value)

JOIN-ы по many-to-many таблицам работают гораздо быстрее чем запросы с LIKE. Для еще большего ускорения можно разбить один сложный запрос c JOIN-ами на несколько более простых. Грубо говоря, сначала вы получаете список ID пользователей, которые содержат нужные опции, а потом производите по ним выборку. Подобный подход применяется в Yii2.

Профессиональная верстка и разработка сайтов на WordPress (http://www.maultalk.com/topic139110s0.html)
dma84
На сайте с 21.04.2009
Offline
168
#8
TiA:
Самым лучшим будет вариант:

JOIN-ы по many-to-many таблицам работают гораздо быстрее чем запросы с LIKE. Для еще большего ускорения можно разбить один сложный запрос c JOIN-ами на несколько более простых. Грубо говоря, сначала вы получаете список ID пользователей, которые содержат нужные опции, а потом производите по ним выборку. Подобный подход применяется в Yii2.

Подобный подход применяется при выборках с LIMIT OFFSET

D
На сайте с 14.01.2007
Offline
153
#9

dma84, будьте поаккуратней с limit offset. на больших значениях там начинается полный П. я однажды полдня потратил на поиски бага. http://stackoverflow.com/questions/4481388/why-does-mysql-higher-limit-offset-slow-the-query-down

dma84
На сайте с 21.04.2009
Offline
168
#10
Dinozavr:
dma84, будьте поаккуратней с limit offset. на больших значениях там начинается полный П. я однажды полдня потратил на поиски бага. http://stackoverflow.com/questions/4481388/why-does-mysql-higher-limit-offset-slow-the-query-down

Я использую JOIN или переменную-счётчик записей, но во втором случае обязательным условием является наличие всех столбцов в WHERE в составном индексе.

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий