데이터베이스 네이밍(RDBMS Naming)

관계형 데이터베이스에 명명규칙에 대해


참고

  • 이 문서는 이 포스팅을 참고하여 작성되었습니다.
  • 의역과 오역이 있을 수 있습니다…
  • 프로젝트나 서비스에 맞게 변경 될 수 있습니다.
  • 더 좋은 의견이 있다면 언제든지 알려주세요.

1. 명명규칙

1.1. 따옴표 사용금지

나쁜 예: 'FirstName' 혹은 "All Employees"

  • 이름에 공백을 포함하지 않는다.
  • 따옴표가 포함된 식별자로 SQL 작성이 어려워진다.

1.2. 식별자는 모두 소문자로 작성 되어야 한다.

  • 테이블, 뷰, 컬럼 그리고 기타 모든 항목이 포함된다.
  • 대소문자를 섞어 사용하면 따옴표를 사용해야 한다.(따옴표 사용금지)

1.3. 데이터타입(데이터유형)을 이름으로 작성하지 않는다.

나쁜 예: text 혹은 timestamp

  • 데이터베이스 객체 이름, 특히 컬럼명은 필드나 객체를 설명하는 명사여야 한다.

1.4. 언더스코어(_)를 사용하여 단어를 분할한다.

좋은 예: word_count 혹은 team_member_id
나쁜 예: wordcount 혹은 wordCount

1.5. 약어 사용을 지양하고 전체 단어를 사용해야 한다.

  • 객체 이름은 전체 영어단어여야 한다.
  • 특히 모음을 삭제하는 유형일 경우에는 지양한다.
  • 대부분의 SQL 데이터베이스는 최소 30자로 된 이름을 지원한다.
  • PostgreSQL은 식별자를 63자까지 지원한다.

1.6. 공통 약어를 사용한다.

몇몇 긴 단어에서는 그 단어 자체보다 약어가 흔히 사용된다.

하지만 약어의 의미전달이 의심스럽다면 전체 단어를 사용한다.

1.7. 예약어 사용금지

나쁜 예: user, lock, table 등.

1.8. 단수형

데이터를 보유하는 테이블, 뷰 및 기타 객체는 복수가 아니라 단수형이어야 한다.

좋은 예: team
나쁜 예: teams

자바의 클래스나 파이썬의 변수명등으로 쉽게 변환된다.

1.9. 접두사와 접미사 사용금지


2. 키 필드

2.1. Primary keys

  • Primary key 필드명은 id 로 한다.
    CREATE TABLE person (
    id            bigint PRIMARY KEY,
    full_name     text NOT NULL,
    birth_date    date NOT NULL);
    

2.2. Foreign Keys

  • Foreign Key 필드명은 참조한 테이블과 필드의 조합이어야 한다.
    CREATE TABLE team_member (
    team_id       bigint NOT NULL REFERENCES team(id),
    person_id     bigint NOT NULL REFERENCES person(id),
    CONSTRAINT team_member_pkey PRIMARY KEY (team_id, person_id));
    

3. 명시적 이름 지정

3.1. 인덱스(Indexes)

인덱스명은 명시적으로 지정해줘야 하며, 테이블명과 컬럼명을 모두 포함해야 한다.

CREATE TABLE person (
  id          bigserial PRIMARY KEY,
  email       text NOT NULL,
  first_name  text NOT NULL,
  last_name   text NOT NULL,
  CONSTRAINT person_ck_email_lower_case CHECK (email = LOWER(email)));

CREATE INDEX person_ix_first_name_last_name ON person (first_name, last_name);

이름과 성에 대한 index person_ix_first_name_last_name가 사용 된다.

=# EXPLAIN SELECT * FROM person WHERE first_name = 'alice' AND last_name = 'smith';
                                          QUERY PLAN                                          
----------------------------------------------------------------------------------------------
 Index Scan using person_ix_first_name_last_name on person  (cost=0.15..8.17 rows=1 width=72)
   Index Cond: ((first_name = 'alice'::text) AND (last_name = 'smith'::text))
(2 rows)

3.2. 제약조건(Constraints)

제약조건에 대한 체크나 디버깅시 용이성을 위해 설명을 지정한다.

CREATE TABLE team (
  id          bigserial PRIMARY KEY,
  name        text NOT NULL);

CREATE TABLE team_member (
  team_id     bigint REFERENCES team(id),
  person_id   bigint REFERENCES person(id),
  CONSTRAINT team_member_pkey PRIMARY KEY (team_id, person_id));

PostgreSQL에서 외래키 작업 제한 설명 이름 지정

=# \d team_member
   Table "public.team_member"
  Column   |  Type  | Modifiers 
-----------+--------+-----------
 team_id   | bigint | not null
 person_id | bigint | not null
Indexes:
    "team_member_pkey" PRIMARY KEY, btree (team_id, person_id)
Foreign-key constraints:
    "team_member_person_id_fkey" FOREIGN KEY (person_id) REFERENCES person(id)
    "team_member_team_id_fkey" FOREIGN KEY (team_id) REFERENCES team(id)

제약 조건을 위반하는 행을 삽입하려고 시도할 경우 제약조건 이름으로 파악하기 쉽다.

INSERT INTO team_member(team_id, person_id) VALUES (1234, 5678);
ERROR:  insert or update on table "team_member" violates foreign key constraint "team_member_team_id_fkey"
DETAIL:  Key (team_id)=(1234) is not present in table "team".

마찬가지로, 3.1. 에서 생성한 person 테이블에 새로운 행을 추가할 때, 무엇이 잘못되었는지 알려주는 제약 조건 위반 오류가 표시된다.

-- This insert will work:
=> INSERT INTO person (email, first_name, last_name) VALUES ('alice@example.com', 'Alice', 'Anderson');
INSERT 0 1

-- This insert will not work:
=> INSERT INTO person (email, first_name, last_name) VALUES ('bob@EXAMPLE.com', 'Bob', 'Barker');
ERROR:  new row for relation "person" violates check constraint "person_ck_email_lower_case"
DETAIL:  Failing row contains (2, bob@EXAMPLE.com, Bob, Barker).

마치며

잘못된 명명 규칙보다 더 나쁜 것은 다중 명명 규칙이다. 기존에 사용하던 방식이 있다면 계속 사용해야 한다.