Ru-Board.club
← Вернуться в раздел «Web-программирование»

» Поиск в базе MySQL

Автор: SparcoCF
Дата сообщения: 25.06.2009 19:47
И все таки Cheery вы бли правы, это пробелы, нашел гадов Все дело в том что у некоторых деталей есть пробел перед номером. И вот постает вопрос, как их удалять ? Во время заполнения базы или во время запроса на вывод? И удалять их с помощью функции str_replace или есть метод получше ?
Автор: Cheery
Дата сообщения: 25.06.2009 19:51
SparcoCF

Цитата:
Во время заполнения базы или во время запроса на вывод?

лучше до и удалить в самой базе (UPDATE database SET columnname=TRIM(columnname);), чтобы не было ничего лишнего.
Автор: SparcoCF
Дата сообщения: 26.06.2009 20:16
Все тот же поиск только для ввода номера запчасти вместо <input type='text' name='number'> нужно использовать <textarea name='number' cols=30 rows=5> </textarea>
использовать его нужно для того что бы можно было реализовать "многопоточный запрос"
Например нужно вывести на экран результат поиска трех запчастей в textarea с новой строчки вводим их:
00000041950070
00000041951946
00000041951955

Как сделать что бы каждый номер запчасти введенный с новой строчки в textarea воспринимался как отдельный запрос ?

Что бы наглядно увидеть как работает данный метод можно посмотреть на сайте www.autopartner.kiev.ua Если выбрать Mercedes и в поле ввести следующие номера:
00000041950070
00000041951946
00000041951955

Увидите какого результата я хочу добиться.
Автор: Cheery
Дата сообщения: 26.06.2009 20:19
SparcoCF

Цитата:
Как сделать что бы каждый номер запчасти введенный с новой строчки в textarea воспринимался как отдельный запрос ?

формировать строку запроса в базу динамически.

WHERE Nomer LIKE 'значение1%' OR Nomer LIKE 'значение2%' и так далее по числу строк в textarea
Автор: SparcoCF
Дата сообщения: 26.06.2009 20:47
делаю запрос таким:
WHERE Nomer LIKE '".mysql_real_escape_string($_REQUEST['number'])."%' OR Nomer LIKE '".mysql_real_escape_string($_REQUEST['number'])."%'

Но это видимо не правильно поскольку $_REQUEST['number'] будет принимать полностью значение которое было вписано в textarea. Значит нужно использовать массив для разделения данных которых получаются с textarea ? Или как указывать что значение введенное с новой строки предназначено для LIKE 'значение2%' и т.д. ?
Автор: Cheery
Дата сообщения: 26.06.2009 20:50
SparcoCF

Цитата:
Значит нужно использовать массив для разделения данных которых получаются с textarea ?

разве не очевидно? разбиваете по строчно - каждая строка и есть значениеN
ну думайте перед тем, как задать вопрос
не забываем делать trim данным из формы
Автор: SparcoCF
Дата сообщения: 27.06.2009 00:24
Вот как я сделал:

<textarea name='number' cols=30 rows=5 class='textarea_search'></textarea>

Код:
$nums = explode(" ", trim($_POST['number']));
$result = mysql_query("SELECT * FROM `".mysql_real_escape_string($_REQUEST['manufacturer'])."` WHERE Nomer LIKE '".$nums[0]."%' OR Nomer LIKE '".$nums[1]."%'");
Автор: Cheery
Дата сообщения: 27.06.2009 00:31
SparcoCF
ну когда вы думать начнете?


Цитата:
$nums = explode(" ", trim($_POST['number']));

трим для каждого элемента после explode
это раз.. второе - проверяйте, что у вас не появится пустой строки, так как тогда будет вместо
Цитата:
Nomer LIKE '".$nums[0]."%'

этого просто
Nomer LIKE '%'
что и дает вывод всего.
опять же - сделайте вывод для query и посмотрите какой.
Автор: SparcoCF
Дата сообщения: 27.06.2009 01:02
Я уже просто в недоумении:
1.

Код:
$nums = explode(" ", $_POST['number']);
         echo $nums[0];
         echo $nums[1];
$query = "SELECT * FROM `".mysql_real_escape_string($_REQUEST['manufacturer'])."` WHERE Nomer LIKE '".trim($nums[0])."%' OR Nomer LIKE '".trim($nums[1])."%'";
$result=mysql_query($query);
echo $query;
Автор: Cheery
Дата сообщения: 27.06.2009 01:06
Cheery

Цитата:
Где же теперь моя ошибка ?

что такое разбиение "построчно" знаете? нет, это не пробелом.
символ переноса строки какой??
вы даже не пытаетесь..
explode по \n
затем trim для каждого элемента
Автор: SparcoCF
Дата сообщения: 27.06.2009 01:21
Спасибо, работает .. я так и думал что пробел не подойдет но после того как увидел что переменные $nums[0] $nums[1] отвечают соответствующим данным то решил что подходит и пробел.

Теперь последнее что осталось с этим поиском
Это то что вы заметили насчет пустой строки.
Ведь дело в том что кто то может ввести для поиска только одну запчасть а кто то и три, значит нужно делать проверку пустая строка или нет.
Как мне кажеться будет правильно делать это так, после разбиения данных делать условие
if (empty($nums[1]) { и что указать здесь если все таки строка пустая ? Нужно что бы вообще по ней ничего не искало тоесть в запрос OR Nomer LIKE '".trim($nums[0])."%' ничего и ничего не искалось.
Автор: Cheery
Дата сообщения: 27.06.2009 01:38
SparcoCF

Цитата:
Как мне кажеться будет правильно делать это так, после разбиения данных делать условие
if (empty($nums[1]) { и что указать здесь если все таки строка пустая ? Нужно что бы вообще по ней ничего не искало тоесть в запрос OR Nomer LIKE '".trim($nums[0])."%' ничего и ничего не искалось.

эх..

Код: $num=explode("\n",$_REQUEST['поле']);
$num=array_map("trim",$num);
$num=sort(array_unique($num));
if (empty($num[0])) unset($num[0]);
if (!empty($num))
{
$query="SELECT * FROM tablename WHERE";
for($i=0;$i<count($num);$i++)
{
$query.=" Nomer LIKE '".mysql_real_escape_string($num[$i])."%'";
if ($i!=count($num)-1) $query.=" OR";
}
$result=mysql_query($query);
}
Автор: SparcoCF
Дата сообщения: 27.06.2009 16:43
Вот это круто Cheery большое СПАСИБО !
Автор: SparcoCF
Дата сообщения: 03.07.2009 17:15
Встретился с одной проблемой.
Если ввести в textarea один номер, потом нажать ентер и не ввести следующего номера и сделать сабмит формы, находит первый номер и делает вывод всего содержимого базы. И это понятно поскольку LIKE получает % и выводит все.
Каким образом можно сделать так что бы проверялось если последующие строки пусты запрос не делать для них ?
Сделал так:

Код:
$num=explode("\n",$_REQUEST['number']);
$num=array_map("trim",$num);

if (empty($num[0])) unset($num[0]);
if (!empty($num))
{
$query="SELECT * FROM `".mysql_real_escape_string($_REQUEST['manufacturer'])."` WHERE";
for($i=0;$i<count($num);$i++)
{
$query.=" Nomer LIKE '$num[$i]%'";
if (empty($num[1])) { unset($num[1]); }
if ($i!=count($num)-1) $query.=" OR";
}
$result=mysql_query($query);
}
Автор: Cheery
Дата сообщения: 03.07.2009 18:00
SparcoCF

Цитата:
Сделал так:

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

зачем вот это?

Цитата:
if (empty($num[1])) { unset($num[1]); }

вы не пытаетесь думать, а программы методом тыка не пишутся.


ps: совет - перечитайте пару книжек по алгоритмам выполнения кода.. рисуйте диаграммы, раз не можете в голове "прокрутить" работу скрипта.
Автор: SparcoCF
Дата сообщения: 03.07.2009 18:18
Cheery
Конечно что я вижу разницу, думаете что я вырезал строку просто так ? Дело в том что когда я вставляю в ваш код:

$num=sort(array_unique($num));

ничего не ищет, а выводиться весь контент базы. Поскольку LIKE в этом случае получает только %
Автор: Cheery
Дата сообщения: 03.07.2009 18:21
SparcoCF

Цитата:
ничего не ищет, а выводиться весь контент базы. Поскольку LIKE в этом случае получает только %

не верю. сделайте после этого
print_r($num); и посмотрите результат
пустая строка должна быть на нулевом индексе, который удаляется в этом случае

Цитата:
if (empty($num[0])) unset($num[0]);

Автор: SparcoCF
Дата сообщения: 03.07.2009 18:34
Вот код:

Код:
$num=explode("\n",$_REQUEST['number']);
         $num=array_map("trim",$num);
         $num=sort(array_unique($num));
         print_r($num);
         if (empty($num[0])) unset($num[0]);
         if (!empty($num))
Автор: Cheery
Дата сообщения: 03.07.2009 18:38
SparcoCF

Цитата:
$num=sort(array_unique($num));

заменить на
$num=array_unique($num);
sort($num);

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

ps: как и говорю - советую еще прослэшить символы _ и % - они используются в выражениях LIKE
Автор: SparcoCF
Дата сообщения: 03.07.2009 19:09

Цитата:
заменить на
$num=array_unique($num);
sort($num);


Так и сделал, но проблема так и осталась если ввести один номер нажать ентер и потом сделать сабмит формы выводиться весь контент базы:

теперь код выглядит так:

Код: $num=explode("\n",$_REQUEST['number']);
         $num=array_map("trim",$num);
         $num=array_unique($num);
            sort($num);
         print_r($num);
         if (empty($num[0])) unset($num[0]);
         if (!empty($num))
{
$query="SELECT * FROM tablename WHERE";
for($i=0;$i<count($num);$i++)
{
$query.=" Nomer LIKE '".mysql_real_escape_string($num[$i])."%'";
if ($i!=count($num)-1) $query.=" OR";
}
$result=mysql_query($query);

}
echo $query;
Автор: Cheery
Дата сообщения: 03.07.2009 19:23
SparcoCF
причина в том, что unset не сдвигает индексы..
я почти весь код тут пишу не запуская
замените
Цитата:
if (empty($num[0])) unset($num[0]);

на
if (empty($num[0])) array_shift($num);

ну и для экранировки символов _ и % замените
array_map("trim",$num)
на
array_map("mytrim",$num);


function mytrim($el)
{
$el=trim($el);
$el=str_replace("%","\%",$el);
$el=str_replace("_","\_",$el);
return $el;
}
правда тут может быть ньюанс.. из за дальнейшего mysql_real_escape_string \ преобразуется в \\
надо попробовать и посмотреть.

опять же - пишу подробно, не через регулярку, чтобы было понятнее
Автор: SparcoCF
Дата сообщения: 03.07.2009 19:58
Cheery
Спасибо, теперь все просто отлично !

Еще хотел бы у вас спросить совета, дело в том что к этому поиску я прикрутил еще логику поиска, тоесть: искать по номеру что "начинаться", "заканчиваться", "содержит" номер который введется в textarea и для всех этих параметров я использую следующие запросы:
"Nomer REGEXP '^".mysql_real_escape_string($num[$i])."'" ----начинаться
"Nomer REGEXP '".mysql_real_escape_string($num[$i])."$'" ----заканчиваться
"Nomer REGEXP '".mysql_real_escape_string($num[$i]).".'" ----содержит

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

И еще одно в самой базе для поля Nomer в таблице задавать оба параметра "Уникальное" и "Индекс" ? Опять же для быстроты.
Автор: Cheery
Дата сообщения: 03.07.2009 20:03
SparcoCF

Цитата:
Мне главное скорость выполнения поскольку база большая

медленно сейчас запрос выполняется? добавляйте алгоритм кэширования типичных запросов.


Цитата:
Опять же для быстроты.

сначала разберитесь, что эти параметры означают.
первое - не совсем относится к скорости.. вот второе как раз
http://dev.mysql.com/doc/refman/5.1/en/indexes.html

Автор: SparcoCF
Дата сообщения: 03.07.2009 20:16

Цитата:
медленно сейчас запрос выполняется?


В принципе быстро если выводиться только 1-10 строк, но если больше 100 то очень даже долго думает, кстати добавил "Индекс" честно говоря сильного прироста в скорости не увидел и это на хостинге, сервак там с такими параметрами:
Processor Name Intel(R) Celeron(R) D CPU 3.06GHz
Vendor ID GenuineIntel
Processor Speed (MHz) 3071.749
Total Memory 1020024 kB
Free Memory 283920 kB
Total Swap Memory 2650684 kB
Free Swap Memory 2603288 kB
Автор: Cheery
Дата сообщения: 03.07.2009 20:19
SparcoCF

Цитата:
сервак там с такими параметрами:

все зависит от того, сколько еще хостов на нем находятся.
+
http://dev.mysql.com/tech-resources/presentations/presentation-oscon2000-20000719/index.html


Цитата:
но если больше 100 то очень даже долго думает

сколько? покажите время выполнения запроса
Автор: SparcoCF
Дата сообщения: 03.07.2009 20:40
Cheery

837 строк выводит 38 секунд !!! что очень и очень много.
Автор: Cheery
Дата сообщения: 03.07.2009 20:42
SparcoCF

Цитата:
837 строк выводит 38 секунд !!! что очень и очень много

выводит что?? скрипт или столько времени занимает запрос к базе?
сколько еще хостов на сервере?
Автор: SparcoCF
Дата сообщения: 03.07.2009 20:53
Выводит скрипт 38 секунд, хостов на сервере ~300 в день прямо сейчас вообще 1.

Засекал я время с помощью скрипта который для этого разработан и он мне выдал такие результаты.
время mysql: 0.000367, всего затрачено: 0.002106 секунд !Процент времени на MySQL: 17.41%

Но в действительности прошло, 38 секунд.
Автор: Cheery
Дата сообщения: 03.07.2009 20:55
SparcoCF

Цитата:
Но в действительности прошло, 38 секунд.

ну так видите, что проблема не в базе.. а в том, как формируется ваша страница с результатами.
да и потом - если затрачено 0.002 (и правильно подсчитано), то это вообще проблема браузера с отрисовкой или коннекта.
Автор: SparcoCF
Дата сообщения: 03.07.2009 21:02
Cheery
Вы были правы ! Почему то тестировал сейчас все в Internet Explorer 8, зашел в FireFox, и Safari загрузило моментально !

Спасибо Cheery за всю оказанную вами помощь !

Страницы: 1234

Предыдущая тема: Вопросы по CSS


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.