2009-12-03 7 views
1

이 질문에 대한 다양한 구체화가 이전에 여기에서 제기되었지만, 나는 또 다른 시도를 할 것이라고 생각했다.여러 컬럼에 걸친 mysql 키워드 검색

나는 끔찍한 데이터베이스 레이아웃을 가졌습니다. 하나의 엔티티 (위젯) 두 테이블로 분할 :이 덜 그 이상이었다

CREATE TABLE widgets (widget_id int(10) NOT NULL auto_increment)

CREATE TABLE widget_data ( widget_id int(10), field ENUM('name','size','color','brand'), data TEXT)

. 특정 이름, 색상 및 브랜드의 위젯을 찾으려면 widget_data 테이블에서 3 방향 조인을 수행해야했습니다. 그래서 합리적인 테이블 형식으로 변환 : 이것은 대부분의 질의가 훨씬 더합니다

CREATE TABLE widgets (widget_id int(10) NOT NULL auto_increment, name VARCHAR(32),size INT(3),color VARCHAR(16), brand VARCHAR(32))

. 그러나 그것은 더 열심히 검색합니다. 예를 들어 '% black %'의 위젯을 검색하고 싶다면 SELECT * FROM widget_data WHERE data LIKE '%black%' 일 것입니다. 이렇게하면 색상이 검은 색이거나 블랙웰 산업에 의해 만들어진 위젯의 모든 사례를 볼 수 있습니다. 심지어 어떤 분야가 일치하는지 정확히 알 수 있었고,이를 내 사용자에게 보여줄 수있었습니다.

새 테이블 레이아웃을 사용하여 유사한 검색을 수행하려면 어떻게해야합니까? 나는 당연히 WHERE name LIKE '%black%' OR size LIKE '%black%'...을 할 수 있었다. 그러나 그것은 clunky하게 보인다. 그리고 나는 아직도 어느 분야가 필적하는지 모른다. 일치시키려는 각 열에 대해 별도의 쿼리를 실행할 수 있습니다.이 쿼리는 모든 일치 항목과 일치하는 항목을 제공하지만 실적이 좋을 것입니다. 어떤 아이디어?

답변

3

두 가지 상충되는 요구 사항이 있습니다. 마치 모든 데이터가 하나의 필드에있는 것처럼 검색하고 싶지만 특정 필드가 일치하는지 확인하고 싶을 수도 있습니다.

WHERE name LIKE '%black%' OR size LIKE '%black%'... 표현에 문제가 없습니다. 당신이 정의한대로 테이블에서 완벽하게 유효한 검색입니다. 코드에서 결과를 확인하여 일치하는 결과를 확인하는 것이 가장 좋은 이유는 무엇입니까? 최소한의 오버 헤드입니다. 그럼 당신은 추가해야 할 것

CREATE VIEW extra_widget_data AS 
    SELECT (name, size, color, brand, 
      CONCAT(name, size, color, brand) as all_fields) 
    FROM widget_data; 

:

당신은 다른 필드을 연결 구성 추가 필드를 추가, 당신은 테이블에 뷰를 만들 수 있습니다 당신의 SQL에 대한 청소기 구문을 원하는 경우 더 많은 공간, CPU 시간 등을 유지해야하는이 필드의 색인입니다. 그만한 가치가 있다고 생각하지 않습니다.

0

아마도 MySQL 전체 텍스트 검색 기능을 살펴보고 싶은데,이 기능을 사용하면 varchar 유형의 여러 열과 일치시킬 수 있습니다.

http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html

+1

해당 테이블이 innodb이므로 myisam으로 변경할 수 없습니다. 따라서 전체 텍스트 인덱스는 불행히도 옵션이 아닙니다. –

+0

전체 텍스트 인덱스는 InnoDB 또는 MyISAM 테이블과 함께 사용할 수 있으며 CHAR, VARCHAR , 또는 TEXT 열. –

2

당신은 선택 열에 WHERE 표현의 일부를 포함 할 수 있습니다. 예 :

SELECT 
    *, 
    (name LIKE '%black%') AS name_matched, 
    (size LIKE '%black%') AS size_matched 
FROM widget_data 
WHERE name LIKE '%black%' OR size LIKE '%black%'... 

그런 다음 스크립트 측면에서 name_matched의 값을 확인하십시오.

성능에 어떤 영향을 미치는지 확실하지 않습니다. 생산에 들어가기 전에 자유롭게 테스트하십시오.