예를 들어 이 test라는 테이블을 잠깐 봅시다.
test 테이블 안에는 sentence라는 컬럼 하나가 있는데요.
각 row의 값들을 보면
위 그림의 빨간 박스 표시처럼
%
‘
_
“
와 같은 문자들이 있습니다. 그런데 이런 문자들은 일반적인 문자임과 동시에 ‘어떤 것이 문자열이라는 것을 나타내거나(‘ / “), 문자열의 특정 패턴을 나타내는’ 표현식(%, _)들인데요.
잠깐 이 테이블에서 sentence 컬럼에 퍼센트 기호(%)가 포함된 row를 찾아야한다고 해봅시다.
우리가 이전에 배운대로 먼저 %를 써주고 그 앞 뒤로 임의의 길이의 문자열을 나타내는 %를 또 써준 뒤, 실행했습니다. 하지만 위 결과를 보니 우리가 예상했던 ‘For 51%’만 나온 게 아니라 전체 row가 조회되어버렸습니다. 그 이유는 바로 정가운데 %가 우리가 원하는 ‘문자로서의 %’가 아니라 ‘LIKE에서 쓰이는 표현식’으로 간주되어, ‘임의의 길이를 가진 문자열’을 나타내는 것으로 해석되었기 때문입니다.
그렇다면 이런 표현식이 아니라 ‘문자로서의 %’를 나타내려면 어떻게 해야 할까요?
이렇게 써주면 됩니다.
위 그림을 보면 가운데 % 앞에 역슬래쉬(백슬래쉬, backslash) 기호를 붙여주니까, 우리가 원하는 대로 ‘For 51%’만 조회됐습니다. 가운데 %가 ‘문자로서의 %’로 해석이 잘 된 겁니다.
방금 한 것처럼 원래 특정 의미(‘임의의 길이를 가진 문자열’)를 나타내던 문자(%)를 그 특정 의미가 아니라, 일반적인 문자처럼 취급하는 행위를 이스케이핑(escaping)이라고 합니다. 이스케이핑은 IT 분야에서 자주 등장하는 단어인데요. 어떤 문자가 그것에 부여된 특정한 의미, 기능으로 해석되는 게 아니라 그냥 단순한 문자 하나로 해석되도록 하는 것을 이스케이핑이라고 하는 거죠.
MySQL에서 이스케이핑을 하는 방법은 해당 문자 앞에 역슬래쉬를 붙여주는 겁니다. 다른 것들로도 실험해보겠습니다.
자, 이제 이스케이핑이 뭔지 알겠죠? 이미 특수한 기능(의미)을 갖고 있는 문자를, 그 특수한 기능(의미)이 아닌, 문자 그대로 해석하고 싶을 때는 이렇게 이스케이핑을 해주면 됩니다.
자, 방금 전 사용한 테이블에서 이번에는 소문자 g가 포함된 값들을 찾아보겠습니다.
그런데 뭔가 이상합니다. 저는 분명히 조건식에 소문자 g를 썼는데 대문자 G가 포함되어 있는 row도 함께 조회가 되어버렸네요.
왜 그런 걸까요? 이것은 MySQL의 기본 설정 때문입니다.
잠깐 이 테이블에 적용된 기본 설정을 보는 방법을 알려드릴게요.
위 그림의 i 표시를 클릭하면 test 테이블에 적용된 설정들을 볼 수 있습니다.
여러 항목들 중에서 Table collation 항목을 봅시다. 이 항목은 문자열이 서로 동일한지를 비교할 때 적용되는 설정을 나타내는데요. 그 뒤에 utf8mb4_0900_ai_ci 라는 값이 써있습니다. 이 단어의 의미를 모두 당장 설명하기는 힘듭니다. 하지만 여기서 ci 부분의 의미는 알아야합니다. ci는 case-insensitive의 약자로 문자열이 동일한지 확인할 때, 대소문자를 구별하지 않겠다는 뜻입니다.
바로 이 설정 때문에 아까 대소문자가 달라도 알파벳만 같으면 같다고 판단이 되버린 겁니다. 만약 이 설정을 다른 걸로 변경하면 대소문자 구분을 하도록 바꿀 수도 있습니다. 하지만 실무에서는 여러분이 데이터베이스 관리자가 아니라면 MySQL 설정을 맘대로 바꿔서는 안 되고, 애초에 그럴 수 있는 권한도 없을 겁니다.
따라서 어떤 설정에서든 대소문자 구분을 할 수 있는 방법이 필요한데요. 사실 설정에 상관없이 늘 대소문자를 구분하도록 할 수 있습니다. 아래 SQL 문을 봅시다.
지금 ‘%g%’ 앞에 BINARY라는 단어를 붙였죠? 실행 결과를 보니 소문자 g가 포함된 문자열만 잘 조회되었네요. BINARY란 ‘이진의, 0과 1로 된’이라는 뜻을 가집니다. 혹시 ‘컴퓨터에서 숫자, 문자 등 모든 것들은 0 또는 1로 표현된다’라는 말은 들어보신 적 있나요? BINARY를 붙여준다는 것은 해당 0과 1이 정확히 일치하는 것을 찾으라는 뜻입니다. 소문자 g와 대문자 G는 같은 알파벳이긴 하지만, 컴퓨터에서 0과 1의 조합으로 저장될 때 다른 값으로 저장됩니다. 그리고 BINARY를 붙이는 건 단지 알파벳 비교 뿐만 아니라 대소문자 구분까지 할 수 있도록 0과 1을 보는 수준까지 문자열 비교를 하라는 뜻인 거죠.
이번엔 대문자 G와 BINARY를 함께 써볼까요?
이번에도 역시 대문자 G가 있는 문자열만 잘 조회됩니다.
이 대소문자 구분 문제는 문자열 패턴 조건을 사용하시는 많은 분들이 처음에 당황해하는 부분입니다. MySQL 설정에 상관없이 대소문자를 명확하게 구분하고 싶다면 BINARY를 잘 활용해보세요.