![]() |
|
Модераторы: skyboy, MoLeX, Aliance, ksnk |
![]()
|
|
| Aliance |
|
|||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
Такая проблема, в структуре БД у меня есть 30 полей с названиями mater1, mater2, ..., mater30.
Я делаю выборку 1 строчки по primary key - `id`. В этих полях по умолчанию содержатся нули, но могут быть и положительные цифры. Как бы пробежаться по всем этим 30 полям, чтобы это было как можно более эффективно и не грузило сервер и страницу соответственно. Гробо говоря:
Возможно стоить перестроить структуру БД, потому как выборка производится по этим 30 полям, а они не являются индексами (их 30, а индексов можно сделать 16) Это сообщение отредактировал(а) Aliance - 10.1.2007, 16:21 |
|||
|
||||
| GZep |
|
|||
![]() участник Винграда ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1528 Регистрация: 7.7.2006 Где: Москва Репутация: -1 Всего: 32 |
Надо LIMIT поставить, чтобы 30 записей вытаскивал.
Это сообщение отредактировал(а) GZep - 10.1.2007, 16:22 -------------------- ![]() ![]() |
|||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 11 Всего: 261 |
А никак сделать одно поле, но множеством?
|
|||
|
||||
| Aliance |
|
|||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
Это как? Боюсь если я тебя правильно понял, то тогда моя БД не будет удоволетворять 1НФ. |
|||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 11 Всего: 261 |
1 НФ тут не при чем.
Скажи для чего эти поля, какие у них значения и как могут изменяться |
|||
|
||||
| Aliance |
|
|||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
У меня есть грубо говоря каталог предметов для игры, некоторые предметы характеризируются не только ценой, но и опр. количеством опр. предметов mater1-mater30. Например, предмет нож характеризируется только ценой, а предмет меч характеризируется еще наличием 2 mater10 и 8 mater21. Описание этих mater1-30 содержится в другой таблице. Вот.
|
|||
|
||||
| GZep |
|
|||
![]() участник Винграда ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1528 Регистрация: 7.7.2006 Где: Москва Репутация: -1 Всего: 32 |
Тут, вроде только если один очень длинный запрос составить можно или выбрать все записи и отсеять лишние уже с помощью PHP.
-------------------- ![]() ![]() |
|||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 11 Всего: 261 |
Aliance, грубо говоря тебе надо отразить как бы для I'той записи принадлежность к ней цифры (предмета) 1, 2 ... 30.
Делаешь поле множеством, впихиваешь туда значения от 1 до 30. И все. Запрос упрощается и работа в сто раз. http://dev.mysql.com/doc/refman/4.1/en/set.html |
|||
|
||||
| Dremlin |
|
|||
|
Quo vadis? ![]() Профиль Группа: Участник Сообщений: 157 Регистрация: 21.9.2006 Где: Киев Репутация: 2 Всего: 4 |
При такой постановке задачи, мне кажется, что косяк в структуре БД. ИМХО, надо бы так: predmet -id -opisanie_i_drugie_polya mater -id -opisanie_i_drugie_polya predmet_mater -id_predmet -id_mater -kolichestvo Тогда и запросы упростятся и структура прозрачней и понятней будет --------------------
Каждый дурак знает, что до звезд не достать, а умные, не обращая внимания на дураков, пытаются... |
|||
|
||||
| Bikutoru |
|
|||
|
Увлекающийся ![]() ![]() Профиль Группа: Участник Сообщений: 522 Регистрация: 24.5.2005 Где: Москва Репутация: 2 Всего: 22 |
Если я все правильно понял, то такая структура базы не очень хороша. Получается, что у тебя большое количество полей в каждой отдельно взятой записи просто не нужны (например, в записи, соответствующей предмету "нож" все 30 полей пустуют). В этом случае мне видится два пути: Вариант 1. Разбить одну таблицу на несколько по сущностям (т.е. отдельно ножи, характеризующиеся только ценой, отдельно мечи, характеризующиеся чем-то еще и т.д.). Это довольно утомительное занятие, если у тебя достаточно большое количество таких сущностей (предметов), т.к. потребует ручной переделки. Данное решение совершенно не годится, если ты хочешь добавлять эти сущности динамически (через админку). Вариант 2. Сделать две таблицы: "предметы", в которой предметы просто перечисляются (без характеризующих их параметров), и "параметры", в которой хранится список параметров. После чего сделать третью таблицу, которая содержит значение параметра с заданным id для предмета с заданным (но другим, конечно же) id. Плюс данного решения: возможность написания скриптика, который автоматически перельет значения в новую структуру. Минусы: оно более медленное по сравнению с предыдущим... В качестве примера приведу кусок из одного своего проекта:
Добавлено @ 16:57 Dremlin, опередил, а я столько писал :-) Это сообщение отредактировал(а) Bikutoru - 10.1.2007, 17:05 -------------------- Человек, словно в зеркале мир — многолик, Он ничтожен — и он же безмерно велик! Омар Хайям |
|||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 11 Всего: 261 |
Я не понимаю, чем множество не устраивает? :_
|
|||
|
||||
| Aliance |
|
|||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
Dremlin, над этим думал, но сомневался. Спасибо. Вопрос такой: в третьей таблице predmet_mater что сделать индексом?
Mal Hack, может быть я туплю, но не вижу вообще как оно тут может пригодится. У каждого предмета либо вообще нет mater, либо их больше 1. Поэтому полей все равно 30 должно быть, а уж какие они будут сильно не влияет на общую логику. В общем решил сделать так, как предложил дремлин. |
|||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 11 Всего: 261 |
очень просто... Смотри есть таблица соответствий mater1 - 1 mater2 - 2 ... mater3 - 3 Есть таблица с предметами (нож, копье). Есть поле maters в нем, для ножа - пустое множество, для копья множество {1,2}, для другого предмета - свое, т.е. указывается только то, что есть. |
|||
|
||||
| Aliance |
|
|||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
Mal Hack, в твоец таблице соответсвий второй столбец - это id?
Проблема в том, что каждого mater может быть по несколько штук. Например в копье 3 - mater1, 2 - mater5, 1 - mater16 и 15 - mater24. Кстати, сделал как предложил Dremlin, но не понятно, как выброрку сделать. Поясняю: у меня 4 таблицы: encyclopedia, items, member_items и encyclopedia_items. Первая - список всех вещей, структура такова: ид вещи, название, характеристики. Вторая - список всех ингридиентов, структура такова: ид ингридиента, характеристики. Третья - список вещей у каждого пользователя, структура такова: ид пользователя, ид вещи (связано со второй таблицей), количество. Четвертая - список вещей требующихся для предмета, структура такова: ид предмета (связано с первой таблицей), ид вещи (связано со второй таблицей), количество. Как мне узнать, какой пользователь сможет купить вещь определенную? Я знаю ид вещи и хочу проверить, у кого есть необходимые для нее ингридиенты. Тоесть мне нужно в третьей таблице найти всех пользователей, у который есть нужные мне ингридиенты в нужной кол-ве. Но тут загвоздка, делаю так: выбираю из 3 таблицы всех пользователей, у которых есть нужное количество первого ингридиента UNION тоже самое со вторым UNION и так далее. Но сдесь есть пользователи, у которых есть первый ингридиент, но нет второго, скажем. Если обойтись без объединения запросов, то как?
Работает, но это при условии, что для вещи с ид "известное ид" требуется только 1 ингридиент. В общем, тупик. Надеюсь более менее понятно написал, если нет - придется выкладывать дамп БД упрощенный. Буду признателен за помощь. |
|||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 11 Всего: 261 |
Первый - индекс предмета. Второй - множество mater'ов.
Тебе это информация нужна для показа инфы, так? А не для поиска. Тогда организуй свое множество через строку. 1-5|2-4|30-1 первое число - meter, второе - кол-во. |
|||
|
||||
| Aliance |
|
|||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
И для показа и для поиска, в том-то и дело.
|
|||
|
||||
| Aliance |
|
||||||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
Делаю такой запрос:
Он мне возвращает 2 ряда: "654";"3";"8";"3";"Кора Змеиного Дерева";"mater10";"1.00";"1";"0/1" "654";"18";"1";"18";"Эссенция Глубины";"mater21";"1.00";"1";"0/1" Из них я могу увидеть, какие ингридиенты и в каком количетсве нужны для покупки вещи с id 654 (в данном случае это 3 предметов с id 3 и 1 предмет с id 18). Гуд. Как дальше построить запрос поиска тех людей, у кого оба этих предмета присуствуют в количестве равном или большем, чем необходимо - не знаю. Если б с 1 предметом - легко, таким запросом:
Он выведет всех, у кого предмет с id 3 есть в количестве больше или равно 8. Но проблема в том, что для покупки предмета с id 654 мне нужно 2 предмета (id 3 и 18), а этим запросом я узнаю только про 1 предмет. Тоесть нужно убьединить запросы
И выбрать все уникальные member_id. Как? Дамп нужной части таблиц кинуть? Помогите пожалуйса, сам не справляюсь. |
||||||
|
|||||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 11 Всего: 261 |
||||
|
||||
| Aliance |
|
|||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
||||
|
||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 11 Всего: 261 |
Делаешь так. Одно поле, как я сказал - сам через строку:
Делаешь еще одно поле, SET'ом, и закидываешь туда те mater'ы, что есть у предмета. Поиск ведешь по второму полю. Очень быстро и удобно. Работаешь с первым полем, не забывая обновлять второе (если какой-ть mater добавляется или удаляется). Запрос совсем не сложный. |
|||
|
||||
| Aliance |
|
|||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
Mal Hack, не, мне не нравится. Я, во-первых, плохо понимаю такую структуру, а соотв. это считай все равно что пользоваться готовым скриптом. Чужое, не понятное. Ну а во-вторых, мне кажется слишком много гемора будет нести такое хранение (редактирование например).
Был бы признателен, если б вы мне помогли с тем, что уже у меня есть, потому как я это все сделал сам и понимаю. Просто знаних не хватает составить запросы и логику правильно. |
|||
|
||||
| Sardar |
|
||||
![]() Бегун ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: нет Всего: 317 |
В простейшем решении собрать все ингридиенты в UNION. Но тогда придёться строить такой запрос самому в момент исполнения скрипта, что не есть гуд по определению.
Вроде можно и так:
Возвращает народ имеющих нужные компоненты в достаточном количестве. Если в ответе будут null, значит есть компоненты (добавь eitems.ditem_id что бы знать какие), которых ни у кого нет. DISTINCT нужен т.к. один member.id может иметь кучу ингридиентов из рецепта (если в рецепте используеться куча). Или так если инфа из dungeon_items (окромя id) нужна:
Возможно мускул будет ругаться на AS, также возможно 5ый может ругаться на второй запрос (там JOIN'ы вроде стали жёще, нельзя просто eitems.required_quantity <= member.quantity, попробуй). -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
||||
|
|||||
| Aliance |
|
||||||||||||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
Sardar, опа, спасибо, уже ближе как мне кажется к истине.
Немного подправил запрос:
Он мне вернул:
Вот структура таблиц:
|
||||||||||||
|
|||||||||||||
| Sardar |
|
|||
![]() Бегун ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: нет Всего: 317 |
Видать хорошую дурь принимает автор названий ингридиентов (похоже рандмно скрипт генерит по словарю)
Вроде всё правильно вывел, Вбей в селект: "member.id, eitems.*", да на quantity проверке поставь <=, это я опечатался, поправил, а ты уже успел использовать (реально пару минут стояло -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
|||
|
||||
| Aliance |
|
||||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
такого быть не может, такое наверное member.member_id Нет не то, смотри, он мне выдает что у 5 пользователей есть все ингридиенты, пользовательские id - 9, 151, 34, 63, 12
А на самом деле нужно чтобы были только 2 юзера - 9 и 151 ведь только у них есть оба предмета в нужном кол-ве!
|
||||
|
|||||
| Sardar |
|
||||
![]() Бегун ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6986 Регистрация: 19.4.2002 Где: Нидерланды, Groni ngen Репутация: нет Всего: 317 |
Угу, мой первый запрос будет возвращать id всех людей, имеющих хотя бы один из компонентов в достаточном количестве.
Можно группировать и выфильтровывать народ не имеющих всех id с ингридиентами, правда их нужно в начале из рецепта выцепить. Т.е. два запроса:
В первом запросе INNER JOIN не нужен если у тебя битых ссылок нет (т.е. энциклопедия всегда ссылаеться на существующие компоненты). Если БД поддерживает вложенные запросы, то можно так:
Это сообщение отредактировал(а) Sardar - 11.1.2007, 04:30 -------------------- Опыт - сын ошибок трудных © А. С. Пушкин Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik Оценить мои качества можно тут. |
||||
|
|||||
| Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 11 Всего: 261 |
Ну и зря... |
|||
|
||||
| Aliance |
|
|||
![]() I ♥ <script> ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 6418 Регистрация: 2.8.2004 Где: spb Репутация: 3 Всего: 137 |
Sardar, первый запрос возвращает 2, как и должен. Второй - работает отлично! Спасибо огромное!
Кстати, третий вопрос возвращает:
Хотя вроде мускул поддерживает вложенные запросы... У меня он 4ка. |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | PHP: Базы Данных | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |