7

여러 테이블에서 동적 검색을 수행하기위한 패턴을 찾고 있습니다.여러 SQL 테이블의 동적 검색 패턴 필요

레거시 데이터베이스 (또는 잘 설계되지 않은 데이터베이스 테이블 구조)를 제어 할 권한이 없습니다.

사용자가 이력서의 데이터에 대해 검색을 수행하고 검색 기준과 일치하는 이력서 목록을 되찾기를 원하는 이력서 검색과 유사한 시나리오를 생각해보십시오. 모든 필드는 언제든지 하나 이상의 다른 필드와 함께 검색 할 수 있습니다.

실제 SQL 쿼리는 검색되는 필드에 따라 동적으로 생성됩니다. 내가 발견 한 대부분의 솔루션은 복잡한 if 블록을 포함하지만, 지금까지는 해결 된 문제 여야하기 때문에 좀 더 세련된 솔루션이 있어야한다고 생각합니다.


그래, 그래서 코드에서 SQL을 동적으로 빌드하는 경로를 시작했습니다. 사악 해 보입니다. 어떤 테이블에서 어떤 필드의 조합을 쿼리 할 수있는 요청 된 기능을 실제로 지원하려고 시도하면 이것은 하나의 대량의 if 문 집합이 될 것입니다. 전율


은 내가 데이터가 널 (null)을 포함하지 않는 경우 COALESCE 만 작동하는지 읽을 생각합니다. 그 맞습니까? 그렇다면 NULL 값을 가지고 있기 때문에 아무 것도하지 않습니다.

답변

5

내가 아는 한 (그리고 나는 끔찍한 레거시 데이터베이스에 대해 작성한 사람이기도하다) 동적 WHERE 절은 없다. 그것은 해결되지 않았습니다.

저는 개인적으로 코드에서 동적 검색을 생성하는 것을 선호합니다. 테스트를 편리하게 해줍니다. 코드에서 SQL 쿼리를 만들 때 사용자 입력을 연결하지 마십시오. @ 변수를 사용하십시오!

유일한 대안은 COALESCE 연산자를 사용하는 것입니다. 다음 표가 있다고 가정 해 보겠습니다.

Users 
----------- 
Name nvarchar(20) 
Nickname nvarchar(10) 

및 이름 또는 닉네임을 선택적으로 검색하려고합니다. 다음 쿼리는이를 수행합니다.

SELECT Name, Nickname 
FROM Users 
WHERE 
    Name = COALESCE(@name, Name) AND 
    Nickname = COALESCE(@nick, Nickname) 

무언가를 검색하지 않으려면 null을 전달하십시오. 예를 들어, 다음 쿼리에서 @nick 결과에 대한 @name 및 널 (null)은 "브라이언"전달 평가되고 :

SELECT Name, Nickname 
FROM Users 
WHERE 
    Name = 'brian' AND 
    Nickname = Nickname 

병합 연산자는 항상 사실과하지 않는 신원 평가에 널 (null)을 회전 where 절에 영향을줍니다.

1

검색과 정규화가 서로 다를 수 있습니다. 그래서 아마 첫 번째 일은 당신에게 이력서를 얻는 하나의 키로 단일 행으로 검색 할 수있는 모든 필드를 보여주는 일종의 "뷰"를 얻는 것입니다. 그런 다음에 그 앞에 Lucene과 같은 것을 던져서 해당 행의 전체 텍스트 색인을 제공 할 수 있습니다. 작동 방식은이보기에서 "x"를 요구하고 키를 반환합니다. 그것의 위대한 솔루션과 처음 2 개월 IIRC 이내에 포드 캐스트에 조엘 자신이 추천 온.

1

SphinxSearch (MySQL의 경우) 또는 Apache Lucene과 같은 것이 필요합니다.

당신이 당신의 예에서 말했듯이 여러 개의 필드로 구성됩니다 이력서 상상할 수 :

  • 목록 항목
  • 이름,
  • Adreess,
  • 교육 (이것은 테이블에 수 자체) 또는
  • 실무 경험 (각 행이 이전 작업을 나타내는 자체 테이블로 확장 될 수 있음)

그래서 모든 필드에서 단어를 검색하면 WHERE가 여러 개의 JOINS가있는 매우 긴 쿼리가됩니다.

대신 참조 프레임 워크를 변경하고 전체 이력서가 단일 문서인지 생각하고 해당 문서를 검색하기 만하면됩니다.

여기가 스핑크스 검색과 같은 도구입니다. 그들은 '문서'의 전체 텍스트 색인을 작성한 다음 sphinx를 조회 할 수 있으며 데이터베이스에서 해당 레코드가 발견 된 곳으로 다시 돌아갑니다.

정말 좋은 검색 결과입니다.

이 도구가 RDBMS의 일부가 아니어도 걱정할 필요가 없습니다. 적절한 모델 "Documents"와이 응용 프로그램의 잘못된 "TABLES"를 사용하는 데 많은 골칫거리가 될 것입니다.