Один простой вопрос – preg_match
в PHP и like
в mysql-запросе такие же?
Главный вопрос:
Рассмотрим следующие две таблицы: table1 и table2
Таблица 1 Таблица 2
+ ------- + ------------------------- + + ------- + ------ ------------------------ + | ID | Модель | | ID | Модель | + ------- + ------------------------- + + ------- + ------ ------------------------ + | 1 | iPad 2 WiFi 16GB | | 1 | iPad2 WiFi 16GB | | 2 | iPhone 4S 16GB | | 2 | iPhone4S 16GB | | 3 | iPod Touch (4-го поколения) 8 ГБ | | 3 | iPod Touch 4-го поколения 8GB | + ------- + ------------------------- + + ------- + ------ ------------------------ +
Теперь, что я хочу сделать, это сравнить эти две таблицы, так как вы можете видеть iPad 2 WiFi 16GB
и iPad2 WiFi 16GB
или iPod Touch(4th Gen)8GB
и iPod Touch 4th Generation 8GB
оба одинаковы, но он не показывает, запрос where Table1.model = Table2.model
потому что они не являются точным совпадением. Я хочу сделать это, чтобы сравнить эти строки с запросом mysql, используя like
или любой другой способ, чтобы сравнить обе строки таблицы, которые одинаковы. Пожалуйста, дайте мне знать, как написать такой SQL-запрос.
Я попробовал следующий sql-запрос, но он не возвращал все строки, как будто он не возвращал те типы строк, которые указаны в приведенном выше примере.
SELECT table1.model as model1, table2.model as model2 FROM table1,table2 WHERE table1.model REGEXP table2.model
Два вопроса – стандартные ли описания (описания не меняются) или они введены пользователем? Если они стандартные, добавьте столбец, который является целым числом, и выполните сравнение в этом столбце.
Если его вводит пользователь, ваша работа сложнее, потому что вы ищете что-то более нечеткое. Я использовал алгоритм поиска по двум граммам для ранжирования сходства между двумя строками, но это невозможно сделать непосредственно в mySQL.
Вместо нечеткого поиска вы можете использовать LIKE, но эффективность ограничивается выполнением сканирования таблицы, если вы в конечном итоге ставите «%» в начале поискового запроса. Кроме того, это означает, что вы можете получить соответствие по выбранной части подстроки, то есть вам нужно будет знать подстроку раньше времени.
Я с удовольствием расскажу больше, когда узнаю, что вы пытаетесь сделать.
EDIT1: Хорошо, учитывая вашу разработку, вам нужно будет выполнить поиск по нечеткому стилю, как я уже упоминал. Я использую метод bi-gram, который включает в себя взятие каждой записи, сделанной пользователем, и разделение ее на фрагменты из 2 или 3 символов. Затем я сохраняю каждый из этих фрагментов в другой таблице, каждая запись возвращается к фактическому описанию.
Пример:
Описание1: «Быстрый запуск вперед» Описание2: «Короткий пробег вперед»
Если вы разбиваете каждый на 2 куска char – «A», «f», «fa», «as», «st» …..
Затем вы можете сравнить количество 2 кусков чар, которые соответствуют обеим строкам, и получить «оценку», которая будет означать точность или сходство между ними.
Учитывая, что я не знаю, какой язык разработки вы используете, я оставлю реализацию, но это то, что нужно сделать явно не в mySQL.
Или ленивой альтернативой было бы использовать службу облачного поиска, такую как Amazon, которая обеспечит поиск на основе терминов, которые вы им даете … не уверен, что они позволяют вам постоянно добавлять новые описания, которые следует учитывать, и в зависимости от вашего приложения может быть немного дорогостоящим (IMHO).
р
Для другого сообщения SO о реализации биграмм – см. Этот SO bigram / нечеткий поиск
— Обновление для каждого вопросника —
Во-первых, я предполагаю, что вы читаете теорию о ссылках, которые я предоставил … во-вторых, я постараюсь сохранить ее как агностик как можно более полезной, поскольку она не нуждается в mySQL (хотя я ее использую, и она работает больше, чем отлично)
Хорошо, поэтому метод bigram работает нормально в создании / сравнении массивов в памяти только в том случае, если возможные совпадения относительно малы, в противном случае он довольно быстро выполняет производительность таблицы-сканирования, такую как таблица mysql, без индексов. Таким образом, вы будете использовать сильные стороны базы данных, чтобы помочь вам индексировать.
Вам нужна одна таблица, в которой пользователь вводит «термины» или текст, который вы хотите сравнить. Простейшей формой является таблица с двумя столбцами, одна из которых представляет собой уникальное целое число с автоматическим инкрементом, которое будет проиндексировано, мы будем называть hd_id ниже, второе – varchar (255), если строки довольно короткие или TEXT, если они могут получить долго – вы можете назвать это, как хотите.
Затем вам нужно будет создать еще одну таблицу с по крайней мере тремя столбцами – одну для столбца ссылки обратно в столбец с автоинкрементами другой таблицы (мы будем называть этот hd_id ниже), второй – varchar () скажем, не более 5 символов (это будет содержать ваши куски bigram), которые мы будем называть «bigram» ниже, а третий – автоинкрементный столбец b_id ниже. В этой таблице будут сохранены все биграммы для входа каждого пользователя и привязаны к общей записи. Вам нужно индексировать столбец varchar самостоятельно (или сначала по порядку в составном индексе).
Теперь, каждый раз, когда пользователь вводит термин, который вы хотите искать, вам нужно ввести термин в первой таблице, а затем проанализировать его в битрамах и ввести каждый кусок во вторую таблицу, используя ссылку на общий термин в первая таблица для завершения отношений. Таким образом, вы делаете вскрытие на PHP, но позволяете mySQL или любой другой базе данных оптимизировать индексы для вас. Это может помочь в фазе bigram сохранить количество биграмм, сделанных в таблице 1 для фазы расчета. Ниже приведен некоторый код в PHP, чтобы дать вам представление о том, как создавать биграммы:
// split the string into len-character segments and store seperately in array slots function get_bigrams($theString,$len) { $s=strtolower($theString); $v=array(); $slength=strlen($s)-($len-1); // we stop short of $len-1 so we don't make short chunks as we run out of characters for($m=0;$m<$slength;$m++) { $v[]=substr($s,$m,$len); } return $v; }
Не беспокойтесь о пространствах в строках – они действительно очень полезны, если вы думаете о нечетком поиске.
Таким образом, вы получаете bigrams, вводите их в таблицу, связанную с общим текстом в таблице 1 через и индексированный столбец … теперь что?
Теперь, когда вы ищете такой термин, как «Мой любимый термин для поиска», вы можете использовать функцию php, чтобы превратить ее в массив битрамов. Затем вы используете это для создания IN (..) части инструкции SQL в вашей таблице bigram (2). Ниже приведен пример:
select count(b_id) as matches,a.hd_id,description, from table2 a inner join table1 b on (a.hd_id=b.hd_id) where bigram in (" . $sqlstr . ") group by hd_id order by matches desc limit X
Я оставил $ sqlstr в качестве ссылки на строку PHP – вы могли бы построить это самостоятельно как список, разделенный запятыми, из функции bigram с использованием implode или что-либо в массиве, возвращаемом из get_bigrams, или параметризовать, если хотите.
Если все сделано правильно, запрос, приведенный выше, возвращает наиболее близко согласованные условия нечеткого поиска в зависимости от длины выбранного вами биграмма. Выбранная длина имеет относительную эффективность, основанную на ожидаемой длине всех строк поиска.
Наконец – запрос выше, просто дает нечеткое соответствие. Вы можете играть и улучшать, сравнивая не только совпадения, но и совпадающие с общим числом биграмм, что поможет сократить длинные строки поиска по сравнению с короткими строками. Я остановился здесь, потому что на этом этапе он становится гораздо более специфичным для приложения.
Надеюсь это поможет!
р