본문으로 바로가기

이스케이핑

category 데이터베이스/MySQL 2022. 1. 22. 14:40

1. 이스케이핑(escaping) 문제

예를 들어 이 test라는 테이블을 잠깐 봅시다. 

test 테이블 안에는 sentence라는 컬럼 하나가 있는데요. 

각 row의 값들을 보면 

위 그림의 빨간 박스 표시처럼

%

'

_

"

와 같은 문자들이 있습니다. 그런데 이런 문자들은 일반적인 문자임과 동시에 '어떤 것이 문자열이라는 것을 나타내거나(' / "), 문자열의 특정 패턴을 나타내는' 표현식(%, _)들인데요.

잠깐 이 테이블에서 sentence 컬럼에 퍼센트 기호(%)가 포함된 row를 찾아야한다고 해봅시다. 

우리가 이전에 배운대로 먼저 %를 써주고 그 앞 뒤로 임의의 길이의 문자열을 나타내는 %를 또 써준 뒤, 실행했습니다. 하지만 위 결과를 보니 우리가 예상했던 ‘For 51%’만 나온 게 아니라 전체 row가 조회되어버렸습니다. 그 이유는 바로 정가운데 %가 우리가 원하는 '문자로서의 %'가 아니라 'LIKE에서 쓰이는 표현식'으로 간주되어, ‘임의의 길이를 가진 문자열’을 나타내는 것으로 해석되었기 때문입니다.

그렇다면 이런 표현식이 아니라 '문자로서의 %'를 나타내려면 어떻게 해야 할까요?

이렇게 써주면 됩니다. 

위 그림을 보면 가운데 % 앞에 역슬래쉬(백슬래쉬, backslash) 기호를 붙여주니까, 우리가 원하는 대로 'For 51%'만 조회됐습니다. 가운데 %가 '문자로서의 %'로 해석이 잘 된 겁니다.

방금 한 것처럼 원래 특정 의미('임의의 길이를 가진 문자열')를 나타내던 문자(%)를 그 특정 의미가 아니라, 일반적인 문자처럼 취급하는 행위를 이스케이핑(escaping)이라고 합니다. 이스케이핑은 IT 분야에서 자주 등장하는 단어인데요. 어떤 문자가 그것에 부여된 특정한 의미, 기능으로 해석되는 게 아니라 그냥 단순한 문자 하나로 해석되도록 하는 것을 이스케이핑이라고 하는 거죠.

MySQL에서 이스케이핑을 하는 방법은 해당 문자 앞에 역슬래쉬를 붙여주는 겁니다. 다른 것들로도 실험해보겠습니다. 

(1) ' (작은따옴표) 이스케이핑 

(2) _(언더바) 이스케이핑

(3) “(큰따옴표) 이스케이핑

자, 이제 이스케이핑이 뭔지 알겠죠? 이미 특수한 기능(의미)을 갖고 있는 문자를, 그 특수한 기능(의미)이 아닌, 문자 그대로 해석하고 싶을 때는 이렇게 이스케이핑을 해주면 됩니다. 

2. 대소문자 구분 문제

자, 방금 전 사용한 테이블에서 이번에는 소문자 g가 포함된 값들을 찾아보겠습니다. 

그런데 뭔가 이상합니다. 저는 분명히 조건식에 소문자 g를 썼는데 대문자 G가 포함되어 있는 row도 함께 조회가 되어버렸네요. 

왜 그런 걸까요? 이것은 MySQL의 기본 설정 때문입니다. 

잠깐 이 테이블에 적용된 기본 설정을 보는 방법을 알려드릴게요.

위 그림의 i 표시를 클릭하면 test 테이블에 적용된 설정들을 볼 수 있습니다. 

여러 항목들 중에서 Table collation 항목을 봅시다. 이 항목은 문자열이 서로 동일한지를 비교할 때 적용되는 설정을 나타내는데요. 그 뒤에 utf8mb4_0900_ai_ci 라는 값이 써있습니다. 이 단어의 의미를 모두 당장 설명하기는 힘듭니다. 하지만 여기서 ci 부분의 의미는 알아야합니다. cicase-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를 잘 활용해보세요. 

'데이터베이스 > MySQL' 카테고리의 다른 글

집계 함수와 산술 함수  (0) 2022.01.25
정렬 text int 차이점  (0) 2022.01.23
DATE 데이터 타입 관련 함수  (0) 2022.01.22
SQL 조건표현식  (0) 2022.01.22
SQL 작성형식 4가지  (0) 2022.01.22