7.1 쿼리와 연관된 시스템 설정


7.1.1 SQL 모드

  • MySQL 서버의 설정 파일에서 sql_mode를 설정할 때는 구분자 (,)를 이용해 다음에 설명되는 키워드를 동시에 설정할 수 있다.

STRICT_ALL_TABLES

  • 일반적으로 MySQL에서는 저장하려는 값의 길이가 칼럼의 길이보다 더 긴 경우라 하더라도 에러가 발생하지 않는다. 칼럼의 길이를 초과하는 부분은 버리고 저장 가능한 만큼만 칼럼에 저장한다.
  • 칼럼의 정해진 길이보다 큰 값을 저장할 때 경고가 아닌 오류가 발생하고 쿼리 실행이 중지된다.

STRICT_TRANS_TABLES

  • 칼럼의 타입과 호환되지 않는 값을 저장할 때, MySQL 서버는 비슷한 값으로 최대한 바꿔서 저장하려고 한다. 하지만 STRICT_ALL_TABLES와 비슷하게 이러한 부분이 사용자를 오히려 더 혼란스럽게 하는 원인이 되기도 한다.
  • 위 값을 설정하면 원하지 않는 데이터 타입의 변환이 필요할 때 MySQL 서버는 강제 변환하지 않고 에러를 발생시킨다.

TRADITIONAL

  • STRICT_TRANS_TABLES나 STRICT_ALL_TABLES와 비슷하지만 조금 더 엄격한 방법으로 SQL의 작동을 제어한다.
  • STRICT_ALL_TABLES, STRICT_TRANS_TABLES, TRADITIONAL 등의 설정은 MySQL 서버가 조금 더 ANSI 표준 모드로 작동하도록 유도한다.

ANSI_QUOTES

  • MySQL에서는 문자열 값을 표현하기 위해 홑따옴표오 쌍따옴표를 동시에 사용할 수 있다. 하지만 오라클과 같은 DBMS에서는 홑따옴표는 문자열 값을 표기하는 데 사용하고, 쌍따옴표는 칼럼 명이나 테이블 명과 같은 식별자를 구분하는 용도로만 사용한다. 이 또한 MySQL에 익숙하지 않은 사용자에게는 혼란스러울 수 있다. 때로는 MySQL에 익숙하다 하더라도 하나의 SQL 문장에서 홑따옴표와 쌍따옴표가 엉켜 있으면 가독성이 떨어지기도 한다.
  • sql_mode 시스템 설정에 ANSI_QUOTES를 설정하면 홑따옴표만 문자열 값 표기로 사용할 수 있고, 쌍따옴표는 칼럼명이나 테이블 명과 같은 식별자를 표기하는 데만 사용할 수 있다.

ONLY_FULL_GROUP_BY

  • MySQL의 쿼리에서는 GROUP BY 절에 포함되지 않은 칼럼이더라도 집합 함수의 사용 없이 그대로 SELECT 절이나 HAVING 절에 사용할 수 있다.

PIPE_AS_CONCAT

  • MySQL에서 “   “는 OR 연산자와 같은 의미로 사용된다. 하지만 sql_mode 시스템 설정에 PIPE_AS_CONCAT 값을 설정하면 오라클과 같이 문자열 연결(CONCAT)연산자로 사용할 수 있다.

PAD_CHAR_TO_FULL_LENGTH

  • MySQL에서는 CHAR 타입이라 하더라도 VARCHAR와 같이 유효 문자열 뒤의 공백 문자는 제거되어 반환된다.
  • CHAR 타입의 칼럼 값을 가져오는 경우, 뒤 쪽의 공백이 제거되지 않고, 반환된다.

NO_BACKSLASH_ESCAPES

  • 역 슬래시를 문자의 이스케이프 용도로 사용하지 못한다.
  • 백 슬래시 문자도 다른 문자와 동일하게 취급한다.

IGNORE_SPACE

  • MySQL에서 스토어드 프로시저나 함수의 이름 뒤에 공백이 있으면 “스토어드 프로시저나 함수가 없습니다”라는 에러가 출력될 수 있다. MySQL에서는 스토어드 프로시저나 함수명과 괄호 사이에 있는 공백까지도 스토어드 프로시저나 함수의 이름으로 간주한다.
  • 프로시저나 함수명과 괄호 사이의 공백은 무시한다.

ANSI

  • 위에서 설명한 여러 가지 옵션을 조합해서 MySQL 서버가 최대한 SQL 표준에 맞게 동작하게 만들어준다.

7.1.2 영문 대소문자 구분

  • MySQL은 설치된 운영체제에 따라 테이블명의 대소문자를 구분한다. 이것은 MySQL의 DB나 테이블이 디스크의 디렉터리나 파일로 맵핑되기 때문이다. 즉 윈도우에 설치된 MySQL에서는 대소문자를 구분하지 않지만 유닉스 계열의 운영체제에서는 대소문자를 구분한다.
  • DB나 테이블 명의 대소문자 구분은 가끔 윈도우에서 운영되던 MySQL 데이터를 리눅스로 가져오거나 그 반대의 경우 문제가 되기도 한다.
  • 대소문자 구분의 영향을 받지 않게 하려면 설정파일에 “lower_case_table_names” 시스템 변수를 설정하면 된다. 이 변수를 1로 설정하면 모두 소문자로만 저장되고, MySQL 서버가 대소문자를 구분하지 않게 해준다. 이 설정의 기본값은0으로, DB나 테이블 명에 대해 대소문자를 구분한다.
  • 또한 이 설정 값에 2를 설정할 수도 있는데 이 경우에는 저장은 대소문자를 구분해서 하지만 MySQL의 쿼리에서는 대소문자를 구분하지 않게 해준다.

7.1.3 MySQL 예약어

  • 데이터베이스나 테이블, 칼럼의 이름을 예약어와 같은 키워드로 생성하면 해당 칼럼이나 테이블을 SQL에서 사용하기 위해서는 항상 역따옴표(`)나 쌍따옴표로 감싸줘야 한다.
  • 만약 역따옴표로 둘러싸고 테이블을 생성하는 경우 예약어를 사용했다고 하더라도 에러나 경고를 보여주지 않고 그대로 테이블을 생성한다.
  • 항상 테이블을 생성할 때는 역따옴표로 테이블이나 칼럼의 이름을 둘러싸지 않은 상태로 사용한다. 그래야만 예약어인지 아닌지 MySQL에서 에러로 알려주기 때문이다. 만약 테이블 생성이 실패하는 경우라면 해당 예약어는 역따옴표로 감싸지 않고는 사용할 수 없다.

7.2 메뉴얼의 SQL 문법 표기를 읽는 방법


MySQL 메뉴얼에 명시된 SQL 문법은 사용할 수 있는 모든 키워드나 기능을 하나의 문장에 다 표기해뒀기 때문에 한눈에 이해되지 않는다는 단점이 있다. 하지만 해당 버전에 맞는 SQL 문법을 참조하기에는 매뉴얼만큼 정확한 자료가 없다. 그래서 더 정확하고 더 상세한 문법을 확인하려면 MySQL 메뉴얼의 SQL 문법을 참조하는 것이 좋다.

1

위 표기법에서 대문자로 표현된 단어는 모두 키워드를 의미한다. 키워드는 대소문자를 특별히 구분하지 않고 사용할 수 있다.

이탤릭체로 표현한 단어는 사용자가 선택해서 작성하는 토큰을 의미하는데 대부분 테이블명이나 칼럼명 또는 표현식을 사용한다.

대괄호 (“[]”)는 해당 키워드나 표현식 자체가 선택사항 임을 의미한다.

파이프(“ “)는 앞과 뒤의 키워드나 표현식 중에서 단 하나만 선택해서 사용할 수 있음을 의미한다. 첫번째 라인의 LOW_PRIORITY와 DELAYED 그리고 HIGH_PRIORITY는 셋 중에서 단 하나만 선택해서 사용할 수 있음을 의미한다.

중괄호(“{}”)는 괄호 내의 아이템 중에서 반드시 하나를 사용해야 하는 경우를 의미한다. 3번째 라인에서 expr이나 DEFAULT중 무조건 하나는 사용해야 한다.

“…” 표기는 아펭 명시돈 키워드나 표현식의 조합이 반복될 수 있음을 의미한다. 마지막 라인에서 “…“은 “, col_name=expr”을 여러번 반복해서 사용할 수 있음을 의미한다.