programing

MySQL과 Postgres 모두에 대해 대소문자를 구분하지 않는 쿼리를 작성하려면 어떻게 해야 합니까?

sourcejob 2022. 9. 20. 23:54
반응형

MySQL과 Postgres 모두에 대해 대소문자를 구분하지 않는 쿼리를 작성하려면 어떻게 해야 합니까?

개발을 위해 MySQL 데이터베이스를 로컬로 실행하고 있지만 Postgres를 사용하는 Heroku에 배포하고 있습니다.Heroku가 거의 모든 것을 처리하지만 대소문자를 구분하지 않는 Like 문장은 대소문자를 구분하지 않습니다.iLike 문을 사용할 수 있지만 로컬 MySQL 데이터베이스에서는 처리할 수 없습니다.

MySQL과 Postgres 모두와 호환되는 대소문자를 구분하지 않는 쿼리를 작성하는 가장 좋은 방법은 무엇입니까?아니면 앱이 말하는 DB에 따라 Like와 iLike 문장을 따로 작성해야 하나요?

이 이야기의 교훈은 다음과 같습니다.개발 및 생산에 다른 소프트웨어 스택을 사용하지 마십시오.절대.

개발에서는 재현할 수 없는 버그만 남게 됩니다.테스트는 무의미해집니다.그냥 하지 마.

다른 데이터베이스 엔진을 사용하는 것은 문제가 되지 않습니다.LIKE와는 다른 동작을 하는 경우가 훨씬 더 많습니다(또, 데이터베이스에서 사용되고 있는 대조도 확인해 보셨습니까?).모든 케이스가 동일합니까?그렇지 않은 경우 동일한 기능을 하는 varchar 열에서 ORDER BY를 잊어버릴 수 있습니다.)

select * from foo where upper(bar) = upper(?);

발신측에서 파라미터를 대문자로 설정하면 두 번째 함수 호출을 회피할 수 있습니다.

아렐 사용:

Author.where(Author.arel_table[:name].matches("%foo%"))

matches하겠습니다.ILIKE 및 Postgres LIKE른른 츠키

포스트그레스에서는 다음 작업을 수행할 수 있습니다.

SELECT whatever FROM mytable WHERE something ILIKE 'match this';

MySQL과 동등한 기능이 있는지 모르겠지만, 이 기능은 항상 사용할 수 있습니다.이것은 조금 못생겼지만 MySQL과 postgres 모두에서 동작할 것입니다.

SELECT whatever FROM mytable WHERE UPPER(something) = UPPER('match this');

몇 가지 답변이 있지만, 어느 것도 매우 만족스럽지 않습니다.

  • LOWER(bar) = LOWER(?)는 MySQL 및 Postgres에서 작동하지만 MySQL에서는 LOWER 함수 때문에 인덱스를 사용하지 않습니다.Postgres에서 기능 색인을 추가할 수 있지만(줄) MySQL은 이를 지원하지 않습니다.
  • MySQL은 대소문자를 구분하지 않는 한 대소문자를 구분하지 않고 자동으로 일치시키고 인덱스를 사용합니다(bar = ?).
  • 데이터베이스 외부의 코드에서 bar 및 bar_lower 필드를 유지합니다.여기서 bar_lower에는 lower(bar)의 결과가 포함됩니다.(데이터베이스 트리거를 사용하는 경우도 있습니다).(Drupal에서 이 솔루션에 대한 설명을 참조하십시오).이것은 서툴지만 적어도 거의 모든 데이터베이스에서 동일한 방식으로 실행됩니다.

REGEXP는 대소문자를 구분하지 않으며(BINARY와 함께 사용하지 않는 한), 다음과 같이 사용할 수 있습니다.

    SELECT id FROM person WHERE name REGEXP 'john';

'JOHN', 'JOHN', 'JOHN', 'JOHN' 등과 일치합니다.

Postgre를 사용하는 경우SQL 8.4에서는 citext 모듈을 사용하여 대소문자를 구분하지 않는 텍스트필드를 생성할 수 있습니다.

COLATE를 사용합니다.

http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html

LIKE/ILIKE 스위치를 대신 해주는 검색 로직 플러그인을 확인하는 것도 고려할 수 있습니다.

블록 내의 서브스트링을 일치시키려면 포스트그레스에서 ~*를 사용할 수도 있습니다.~는 대소문자를 구분하는 하위 문자열, ~* 대소문자를 구분하지 않는 하위 문자열과 일치합니다.느린 작업이지만 검색에 유용할 수 있습니다.

Select * from table where column ~* 'UnEvEn TeXt';
Select * from table where column ~ 'Uneven text';

둘 다 "Some Equality Text here"를 누릅니다. 전자만 "Some Equality Text here"를 누릅니다.

가장 많이 사용되는 3개의 Rails 데이터베이스 백엔드에 대해 호환되는 구문을 포함하므로 상위로 변환하는 것이 가장 좋습니다.포스트그레SQL, MySQL 및 SQLite는 모두 이 구문을 지원합니다.어플리케이션이나 조건 문자열에 검색 문자열을 대문자로 표시해야 하는 (작은) 단점이 있기 때문에 조금 더 보기 흉하지만 호환성이 있기 때문에 가치가 있다고 생각합니다.

MySQL과 SQLite3에는 대소문자를 구분하지 않는LIKE 연산자가 있습니다.포스트그레만SQL에는 대소문자를 구분하는 LIKE 연산자와 Postgre가 있습니다.대소문자를 구분하지 않는 검색을 위한 SQL별(수동 기준) ILIKE 연산자.Rails 응용 프로그램의 조건에서 ILIKE inseed를 LIKE로 지정할 수 있지만 MySQL 또는 SQLite에서는 응용 프로그램이 작동하지 않습니다.

세 번째 옵션은 사용 중인 데이터베이스 엔진을 확인하고 그에 따라 검색 문자열을 수정하는 것입니다.이것은 Active Record의 접속 어댑터를 해킹/매칭하여 Postgre를 사용하는 것이 좋습니다.SQL 어댑터는 쿼리를 실행하기 전에 쿼리 문자열을 수정하여 "ILIKE" 대신 "LIKE"로 대체합니다.그러나 이 솔루션은 가장 복잡하며 두 용어를 모두 대문자로 바꾸는 등 쉬운 방법에 비추어 볼 때, 저는 이것이 노력을 필요로 하지 않는다고 생각합니다(이렇게 하면 많은 브라우니 포인트를 얻을 수 있습니다).

언급URL : https://stackoverflow.com/questions/203399/how-do-you-write-a-case-insensitive-query-for-both-mysql-and-postgres

반응형