![]() |
|
![]() ![]() ![]() |
|
Hinikato |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 18.2.2007 Репутация: нет Всего: нет |
Здравствуйте!
Суть задачи такая: есть около 10 000 (10 тысяч) продуктов в прайсе в формате XML. Нужно импортировать все продукты в базу данных. У каждого продукта есть собственный код по которому можно искать в базе. Задача сводится к тому, что по коду продукта нужно смотреть в базе, есть там уже продукт с таким кодом и если есть, просто обновлять информацию, если нет, то добавлять. Но есть ограничение: нельзя делать много запросов в базу для выборки, т.е. 10000 запросов SELECT неприемлимо. Выбирать все в массив, тоже не выход, т.к. в базе может быть около 1000 000 продуктов. Если выбрать все 1000000 записей получим для худшего случая такой расход памяти:
UTF-8 может занимать 2 байта, поэтому 2, умножаем на макс. кол-во символов в коде и умножаем на общее кол-во продуктов в базе, после чего получаем кол-во мегабайт. Поэтому нужен какой-то алгоритм, который позволит искать продукты по коду с меньшим количеством запросов. Пример кода продукта: "abcd" - это просто строка длиной до 255 символов. Можете ли вы посоветовать такой алгоритм или просто подсказать/показать как тут можно поступить? |
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 20 Всего: 454 |
Грузим файл на сайт, средствами SQL импортируем его в таблицу и одним запросом получаем необходимые данные.
-------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
Lipetsk |
|
|||
![]() в форме ;) ![]() Профиль Группа: Участник Сообщений: 180 Регистрация: 28.1.2009 Где: Липецк Репутация: 2 Всего: 5 |
||||
|
||||
Hinikato |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 18.2.2007 Репутация: нет Всего: нет |
Akina, можно подробнее, насколько я понял, вы описали кратко саму суть задачи, а не ее решение. Добавлено через 2 минуты и 21 секунду В цикле мы идем по продуктам, для каждого продукта мы ищем в базе его код, если продукт с таким кодом найден в базе, мы делаем UPDATE, иначе, делаем INSERT. Прояснило ли это для вас суть задачи? |
|||
|
||||
Akina |
|
|||
Советчик ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 20581 Регистрация: 8.4.2004 Где: Зеленоград Репутация: 20 Всего: 454 |
Это - решение. Или, если желаете, алгоритм решения. А если нужна реализация - Вам в другой раздел. В раздел по работе из конкретного ЯП с конкретной СУБД. -------------------- О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума. |
|||
|
||||
ksnk |
|
|||
![]() прохожий ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 6855 Регистрация: 13.4.2007 Где: СПб Репутация: 7 Всего: 386 |
Вряд ли получится одним запросом для 100000 строк ![]() А так - все просто. Строим такую-же временную таблицу, как и таблица товаров, строим запросы "insert ... values" с максимальными количествами товаров и исполняем. После заполнения временной таблицы - запрос на изменения - один и запрос на вставку - другой. Разумнее, все-таки, на компьютер клиента, на котором строится XML таблица, поставить скрипт преобразования всего этого добра в SQL, и грузить на сервер именно sql запрос. -------------------- Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! ![]() |
|||
|
||||
Hinikato |
|
||||||
![]() Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 18.2.2007 Репутация: нет Всего: нет |
Похоже немного непонятен мой вопрос. Вот краткий псевдокод, чтобы стала понятна суть:
Каждый вызов FindProductByCodeInDB() это один SELECT:
Если у нас 10000 продуктов, то получаем 10000 селектов. Как преобразовать это дело можно, чтобы не выбирать все коды в память, а потом в памяти искать. Объясню почему не получится выбрать все 1000 000 кодов из базы одним запросом. Потому что это получится:
а такой расход памяти недопустим. Поэтому вопрос, как можно это оптимизировать? Я надеюсь может вы подскажете какой алгоритм есть особый который позволяет как-то умно уменьшить кол-во селектов и искать продукт по коду в базе/памяти. Это сообщение отредактировал(а) Hinikato - 29.4.2011, 15:57 |
||||||
|
|||||||
ksnk |
|
|||
![]() прохожий ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 6855 Регистрация: 13.4.2007 Где: СПб Репутация: 7 Всего: 386 |
--Не нужно искать товары отдельными запросами.
--Нужно импортировать маловразумительную xml таблицу в базу данных, в отдельную таблицу, специально для этого дела создаваемую. --Для этого импорта лучше всего подходят длинные и быстрые "insert...values..." запросы. Именно ими оперируют все процедуры импорта-экспорта менеждеров баз данных. --Кто и где будет делать sql дамп не суть важно, хотя я предпочел бы, чтобы клиент, так как сервер и так занят. Для этого нужно поставить несложный конвертер (можно на php ;) ) на клиентскую машину. Для такого очень удобны фреймворки, которые умеют делать консольные приложения. После успешного импорта таблицы товаров в новую таблицу на сервере, операция импорта товаров становится достаточно тривиальной. Это сообщение отредактировал(а) ksnk - 29.4.2011, 16:22 -------------------- Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! ![]() |
|||
|
||||
Hinikato |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 18.2.2007 Репутация: нет Всего: нет |
ksnk, наконец-то, надеюсь, я понял вашу идею, спасибо, умное решение
![]() У меня остались некоторые вопросы по той части, о которой вы говорите как о тривиальной. В результате мы получим две похожих таблицы: - в первой таблице будут храниться товары для импорта, загруженные из XML, - во вторую нам нужно будет их перенести. Это как я понял можно сделать SQL запросом, но тут вопрос каким. Ведь он должен решать по-сути ту же саму задачу: обновить те товары, код которых совпадает и вставка тех товаров, код которых не совпадает. Мои вопросы такие: 1. Можно привести хотя бы набросок SQL запроса, чтобы я понял общий смысл? 2. Можно ли это сделать без хранимой процедуры, при этом не забыв, что делать 1000 000 запросов неприемлимо? Или все-таки здесь не обойтись без хранимой процедуры? Это сообщение отредактировал(а) Hinikato - 30.4.2011, 05:58 |
|||
|
||||
almagnit |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 283 Регистрация: 3.4.2008 Репутация: нет Всего: 7 |
Если productCode является уникальным или первичным ключом то можно пользоваться такими запросами
В случае совпадения какого-нибудь ключа, СУБД самостоятельно обработает исключение и выполнит UPDATE для указанных столбцов. |
|||
|
||||
Hinikato |
|
||||||||
![]() Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 18.2.2007 Репутация: нет Всего: нет |
almagnit, изящно, спасибо, взял себе как способ одним запросом обновить строку или вставить ее. Я кажется понял, как можно это сделать: выбираем коды всех продуктов у которых product_code совпал:
В худшем случае их кол-во будет равно кол-ву импортируемых товаров, таким образом массив не будет превышать 10000 кодов продуктов, а это равно:
Размер такого массива допустимо выбирать в память и искать продукты по коду в нем. Спасибо ребята за помощь ;) Тема закрыта, если кто-то еще не хочет ее чем-то дополнить. |
||||||||
|
|||||||||
![]() ![]() ![]() |
Правила форума "Алгоритмы" | |
|
Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Алгоритмы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |