2011-09-14 2 views
1
$SQL = "SELECT * FROM `user_posts` WHERE (`post` LIKE '%@".$user."%')"; 

예를 들어, 사용자 이름이 @Jake이면 @Jake가있는 모든 게시물이 표시됩니다. 그러나 그것은 또한 예를 들어, @ Jake11도 할 것입니다, 그것은 또한 표시됩니다. 이 문제를 어떻게 해결할 수 있습니까?MySQL과 비슷하지만 다른 쿼리와 유사하지는 않습니다.

+0

그래서 @Jake 만 정확하게 표시하고 싶습니까? –

+0

여기에이 작업을 수행하는 방법에 대한 몇 가지 예가 있지만 페이지로드시이 작업을 수행 할 것으로 예상되는 경우 모두 수행됩니다. 색인이없는 것은 성능이 떨어집니다. 포스트 타임에 게시물에서 "@Name"을 추출하고 인덱싱 된 테이블 ('post_mention.post_id' ='post.id' &&'post_mention.name' = "@Jake")에서 참조를 생성하는 것이 더 낫습니다. 배치 프로세스에서 "@Name"멘션을 찾고 색인을 작성하게하십시오. – six8

답변

3

LIKE '%...%' 대신 regular expression을 사용하는 것이 좋습니다.

예는 다음과 같을 수 있습니다 오른쪽 단어 경계에

... WHERE `post` REGEXP '@" . mysql_real_escape_string($user) . "[[:>:]]'" 

[[:>:]] 일치. Bill Karwin에 의해 지적 되었 듯이, @ 문자에는 암시 적 단어 경계가 있기 때문에 왼쪽 경계 패턴이 필요하지 않습니다. (사실, 당신은 비 단어 문자의 왼쪽에 왼쪽 경계를 가질 수 없습니다.)

(나는 다른 사람들이 너무 SQL injection 공격에 노출 가능성에 대해 언급 것이라 확신합니다.)

+1

+1 비슷한 답변을 작성했지만 가장 먼저 게시했습니다. :) 그런데 왼손 단어 경계 패턴이 필요하지 않을 수도 있습니다. '@'그 자체만으로도 원하는 문자열에만 일치를 제한 할 수 있습니다. 단어 경계 패턴의 균형을 유지할 필요는 없습니다. –

+0

이렇게하면 데이터가 반환되지 않는 것 같습니다. – Jake

+0

감사합니다. 나는 그림으로 왼쪽 경계선을 넣었지 만, 반성에서 나는 아마 표현을 어겼을 것이라고 생각한다. 그래서 나는 바로 잡았다. –

0

당신이 여기 LIKE 필요가없는 간단한 평등 검사가 작동 같습니다 : 당신이 여기에 SQL 주입 가능성을 가지고 mysql_real_escape_string를 사용한다

$SQL = "SELECT * FROM `user_posts` WHERE (`post` = '@".$user."')"; 

가주의 할 :

$SQL = sprintf("SELECT * FROM `user_posts` WHERE (`post` = %s)", mysql_real_escape_string('@' . $user)); 

당신은 당신이 당신의 같은 항목에 공백을 추가 할 수 있습니다 후 내 @Joe를 찾으려면,하지만 천천히 수행합니다

$SQL = sprintf("SELECT * FROM `user_posts` WHERE (`post` LIKE %s)", mysql_real_escape_string('% @' . $user . ' %')); 
$SQL = sprintf("SELECT * FROM `user_posts` WHERE MATCH (post) AGAINST (%s)", mysql_real_escape_string('@' . $user)); 
+0

그 글은 오직 포스트가'@ '을 포함하고있는 곳에서만 일치합니다. $ user' – Joe

+0

아, 이제 알겠습니다. 게시물은 반드시 텍스트 열이어야합니다. 편집 됨. – six8

0
$SQL = "SELECT * FROM `user_posts` WHERE (`post` LIKE '%@".$user."')"; 
+1

게시물이 '@'로 끝나는 부분에만 일치합니다. $ user' – Joe

0

http://devzone.zend.com/article/1304

를 사용하여 전체 텍스트 열 :

ALTER TABLE user_posts ADD FULLTEXT(post); 

$sql = ' SELECT * FROM user_posts WHERE MATCH (post) AGAINST ("' . $user . '") '; 
+0

FWIW, FULLTEXT 인덱스는 현재 버전의 MySQL에서는 MyISAM 테이블에서만 지원되지만 InnoDB 풀 텍스트 구현은 MySQL 5.6에서 향후 제공 될 것으로보고 있습니다. –

+0

MyISAM이 일반적으로 정의하는 기능이라고 생각합니다. 전체 텍스트 검색을 원한다면 MyISAM을 사용할 것이고, 외래 키를 원한다면 InnoDB를 사용할 것이다. 드물게 두 가지를 원합니다 : P – Joe

+0

전체 텍스트 인덱싱과 외래 키를 모두 처리하는 문제는 숨쉬기가 힘들면 MyISAM이 손상된다는 것입니다. InnoDB도 손상 될 수 있지만 자동 복구에서는 훨씬 더 좋습니다. –

0

'%'는 와일드 카드, 그것은 어떤 일치한다 : 은 성능을 위해 FULLTEXT 인덱스를 사용 그 자리에있는 문자의 양. 검색어에서 해당 단어를 삭제하면 설정됩니다. 어떻게 그 쿼리는 IS 말하고 "포스트 일치가있는 행을 찾을 [아무것도] @Jake [아무것도]"

방금 ​​수행처럼 사용할처럼 소리하지 않습니다

$SQL = "SELECT * FROM `user_posts` WHERE (`post` = '@".$user."')"; 
+0

이것은 단지 포스트가'@ '을 포함하고있는 곳에 만 일치 할 것입니다. $ user' – Joe

+0

예, 그것이 OP가 원하는 것입니다, 맞습니까? – Landon

+0

"@Jake가있는 모든 게시물" – Joe

0

이러한 종류의 쿼리는 인덱스를 사용하지 않으므로 전체 테이블 검색이 필요합니다. 데이터베이스가 합리적인 크기가되면이 작업은 매우 느릴 것입니다. 이상적으로, 게시물이 생성되면 텍스트를 구문 분석하고 일대 다 테이블 (적절히 색인 된)에 행을 적절히 삽입하여 관계를 식별 할 수 있습니다. 문자는 바로 "제이크"을 다음과 같이 및 z, A와 Z 나 사이 아닌,이 한 @jake 포함됩니다 귀하의 예제의 경우 ($user를)

$SQL = "SELECT * 
     FROM `user_posts1 
     WHERE (`post` LIKE '%@".$user."%) 
     AND (`post` NOT RLIKE '%@".$user."[a-zA-Z0-9]%')" 

:

0

정규식을 사용하여 0-a.

관련 문제