rastalion.dev
Docs / Database / 데이터베이스 네이밍 규칙

0. 핵심 원칙 — 식별자 케이스 폴딩(Case Folding)

가장 먼저 이해해야 할 이식성 규칙이다. 엔진마다 따옴표 없는 식별자(unquoted identifier) 를 다르게 처리한다.

엔진 unquoted 식별자 처리 표준 준수
표준 SQL 대문자로 폴딩
Oracle 대문자로 폴딩 준수
PostgreSQL 18 소문자로 폴딩 비표준
MySQL — 테이블·DB·테이블 별칭 lower_case_table_names 에 따라 다름 비표준
MySQL — 그 밖의 식별자 폴딩하지 않고 비교에서만 무시 비표준

폴딩의 표준 방향은 대문자다. PostgreSQL 문서는 소문자 폴딩이 표준 SQL 과 호환되지 않는다고 스스로 밝힌다 — 표준대로라면 foo"foo" 가 아니라 "FOO" 와 같아야 한다. PostgreSQL 에서 FOO·foo·"foo" 는 같은 식별자이고, "Foo""FOO" 는 그 셋과도 서로와도 다르다. Oracle 은 따옴표 없는 식별자를 대문자로 해석하므로 표준 쪽에 있다.

IMPORTANT — 결론

  1. 모든 식별자는 소문자 snake_case 로 작성한다. 대문자에 의미를 부여하는 규칙(대문자 접미사 등)은 PostgreSQL 의 소문자 폴딩에서 형태가 사라진다.
  2. 식별자 길이는 63자 이하로 유지한다. PostgreSQL 은 63 바이트, MySQL 은 64 문자다. 두 값이 63자에서 만나는 것은 식별자에 ASCII 만 쓸 때뿐이다(1-5).
  3. 따옴표("...", `...`) 없이 쓸 수 있는 이름만 쓴다. PostgreSQL 문서도 이식 가능한 애플리케이션을 쓰려면 특정 이름을 항상 따옴표로 감싸거나 아예 감싸지 말라고 권고한다(0-2).
  4. 제약·인덱스 이름은 스키마 전역에서 유일하게 짓는다. 두 엔진과 표준의 유일성 범위를 모두 만족하는 최소 공통 규칙이다(4-3).

0-1. lower_case_table_names 가 좌우하는 것

이 변수가 좌우하는 대상은 테이블명·데이터베이스명·테이블 별칭 세 가지뿐이다.

디스크 저장 이름 비교
0 CREATE 문에 쓴 대소문자 그대로 대소문자 구분
1 소문자로 변환해 저장 대소문자 무시
2 쓴 대소문자 그대로, 조회 시 소문자 변환 대소문자 무시

기본값은 플랫폼마다 다르다 — Unix 0, Windows 1, macOS 2 다. 값 2 는 대소문자를 구분하지 않는 파일시스템에서만 동작하고, 그런 파일시스템에 0 을 강제하면 MyISAM 인덱스가 손상될 수 있다. 그리고 이 변수는 서버를 초기화할 때만 설정할 수 있다 — 이후 변경은 금지된다. 개발자 macOS(기본 2)와 운영 Linux(기본 0)가 갈리는 지점이므로 테이블명을 소문자로만 쓴다.

컬럼·인덱스·파티션·서브파티션·스토어드 루틴·이벤트·리소스 그룹 이름과 컬럼 별칭은 모든 플랫폼에서 대소문자를 구분하지 않는다. 쓴 대소문자가 보존되고 비교할 때만 무시되며, 이 변수와 무관하다. 트리거 이름도 이 변수의 영향을 받지 않는다. 로그 파일 그룹 이름은 반대로 대소문자를 구분하고, MySQL 문서는 이 동작이 표준 SQL 과 다르다고 밝힌다.

따라서 “MySQL 에서는 컬럼명 대문자가 보존된다” 는 사실이다. 대문자를 섞은 이름이 깨지는 경로는 PostgreSQL 의 소문자 폴딩 하나이고, 그것만으로도 소문자 통일 규칙이 필요하다.

0-2. 따옴표를 쓰면 무엇이 깨지는가

PostgreSQL 문서는 이식 가능한 애플리케이션을 쓰려면 특정 이름을 항상 따옴표로 감싸거나 아예 감싸지 말라고 권고한다. 결론 3번은 그 권고의 뒤쪽을 택한 것이다.

  • PostgreSQL: "Foo"foo"FOO" 가 서로 다른 세 식별자다. 폴딩 방향이 표준과 반대이므로 Oracle 로 옮기면 Oracle 이 만든 "FOO" 와 어긋난다. 따옴표는 길이 한계를 우회하지도 못한다 — 인용 식별자에도 63바이트 제한이 적용된다.
  • MySQL: 기본 인용 문자는 백틱이다. 겹따옴표는 sql_modeANSI_QUOTES 에 따라 의미가 바뀐다 — 꺼져 있으면 문자열 리터럴이라 CREATE TABLE "test" (...)ERROR 1064 이고, 켜면 식별자로 해석되어 통과한다. 같은 DDL 이 서버 설정에 따라 성공하거나 실패한다.

예약어와 충돌하는 이름은 따옴표로 감싸지 말고 이름을 바꾼다(2-2).


Advertisement