2026년 07월 06일 | DBMS Error 가이드
이 글에서 다루는 내용
42622 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
42622 name too long 는?
PostgreSQL 에러 코드 42622는 데이터베이스 객체(테이블, 컬럼, 인덱스, 함수 등)의 이름이 PostgreSQL이 허용하는 최대 길이를 초과했을 때 발생하는 에러입니다. PostgreSQL은 기본적으로 식별자(identifier)의 최대 길이를 63바이트로 제한하고 있으며, 이를 초과하는 이름을 사용하려 할 경우 이 에러가 발생합니다. 특히 자동 생성되는 인덱스 이름이나 제약조건 이름이 긴 테이블명과 컬럼명의 조합으로 인해 자동으로 63바이트를 초과하는 경우에도 자주 나타납니다.
주요 발생 원인
- 테이블, 컬럼, 인덱스 등의 객체 이름이 63바이트를 초과하는 경우
PostgreSQL 내부적으로 식별자는 pg_catalog.pg_class, pg_catalog.pg_attribute 등의 시스템 카탈로그에 name 데이터 타입으로 저장됩니다. 이 name 타입은 최대 63바이트(NAMEDATALEN – 1)만 저장할 수 있도록 컴파일 시점에 고정되어 있습니다. 따라서 영문 기준으로 64자 이상이거나, 멀티바이트 문자(예: 한글, 중국어 등)를 사용하는 경우 바이트 수가 빠르게 초과됩니다.
- 자동 생성되는 제약조건 이름 또는 인덱스 이름이 너무 긴 경우
PostgreSQL은 명시적으로 이름을 지정하지 않으면 테이블명_컬럼명_idx, 테이블명_컬럼명_fkey 등의 형식으로 이름을 자동 생성합니다. 테이블명과 컬럼명이 각각 길 경우, 이 조합이 63바이트를 초과하게 되어 에러가 발생하거나 PostgreSQL이 내부적으로 이름을 잘라버려 예기치 않은 동작을 유발할 수 있습니다.
- ORM(Object-Relational Mapping) 도구나 마이그레이션 툴이 자동으로 긴 이름을 생성하는 경우
Django, SQLAlchemy, Hibernate, Flyway, Liquibase 등의 ORM 또는 마이그레이션 도구는 규칙에 따라 테이블명, 인덱스명, 제약조건명을 자동 생성합니다. 이 과정에서 도메인 모델의 클래스명이나 필드명이 길 경우, 자동 생성된 이름이 PostgreSQL의 63바이트 제한을 초과하여 에러가 발생할 수 있습니다.
해결 방법
원인 1 해결: 객체 이름 직접 단축
객체 생성 시 이름을 63바이트 이내로 직접 줄여서 사용합니다.
-- 에러 발생 예시: 64자 이상의 테이블 이름
CREATE TABLE user_account_personal_information_detail_extended_history (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
-- ERROR: 42622 - identifier "user_account_personal_information_detail_extended_history" will be truncated to "user_account_personal_information_detail_extended_histor"
-- 해결: 테이블 이름을 의미를 유지하면서 축약
CREATE TABLE user_acct_personal_info_ext_history (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
현재 식별자의 바이트 수를 미리 확인하는 쿼리:
-- 식별자 길이를 바이트 단위로 확인
SELECT
'user_account_personal_information_detail_extended_history' AS identifier,
octet_length('user_account_personal_information_detail_extended_history') AS byte_length,
CASE
WHEN octet_length('user_account_personal_information_detail_extended_history') > 63
THEN '63바이트 초과! 축약 필요'
ELSE '정상 범위'
END AS status;
원인 2 해결: 제약조건 및 인덱스 이름을 명시적으로 지정
자동 생성 대신 명시적으로 짧은 이름을 지정하여 제약조건과 인덱스를 생성합니다.
-- 문제가 되는 자동 이름 생성 예시
CREATE TABLE order_management_system_transactions (
id SERIAL PRIMARY KEY,
customer_account_reference_number VARCHAR(50),
product_catalog_identifier VARCHAR(50)
);
-- 자동 생성 인덱스 이름이 너무 길어질 수 있음
-- order_management_system_transactions_customer_account_reference_number_idx
-- 위 이름은 명백히 63바이트 초과
-- 해결: 인덱스 이름을 명시적으로 지정
CREATE INDEX idx_oms_txn_cust_acct_ref
ON order_management_system_transactions (customer_account_reference_number);
CREATE INDEX idx_oms_txn_prod_cat_id
ON order_management_system_transactions (product_catalog_identifier);
-- 외래키 제약조건도 명시적으로 이름 지정
ALTER TABLE order_management_system_transactions
ADD CONSTRAINT fk_oms_txn_cust
FOREIGN KEY (customer_account_reference_number)
REFERENCES customers (account_reference_number);
원인 3 해결: ORM 설정에서 이름 오버라이드
Django를 예시로, 모델 수준에서 명시적인 이름을 지정합니다.
-- Django ORM이 생성하는 긴 이름의 마이그레이션을 직접 수정하는 예시
-- Django migrations 파일에서 직접 이름 지정 후 실행되는 SQL 예시
-- Django가 자동 생성하려는 인덱스 이름 (문제)
-- CREATE INDEX "myapp_useraccountpersonalinformationdetail_user_profile_id_abc12345_idx"
-- ON "myapp_useraccountpersonalinformationdetail" ("user_profile_id");
-- 직접 마이그레이션에서 명시적으로 짧은 이름을 지정한 결과 SQL
CREATE INDEX idx_user_acct_info_profile
ON myapp_user_acct_personal_info (user_profile_id);
-- SQLAlchemy 사용 시 명시적 이름 지정
-- Index('idx_user_acct_info_profile', UserAccountPersonalInfo.user_profile_id)
-- 위 Python 코드가 아래 SQL을 생성하도록 유도
CREATE INDEX idx_user_acct_info_profile
ON user_account_personal_info (user_profile_id);
기존에 잘린 이름을 가진 객체를 확인하고 수정하는 방법:
-- 현재 데이터베이스의 인덱스 이름 길이 확인
SELECT
schemaname,
tablename,
indexname,
octet_length(indexname) AS byte_length
FROM pg_indexes
WHERE octet_length(indexname) > 50 -- 위험 범위 내 인덱스 확인
ORDER BY byte_length DESC;
-- 제약조건 이름 길이 확인
SELECT
conname,
octet_length(conname) AS byte_length,
contype,
conrelid::regclass AS table_name
FROM pg_constraint
WHERE octet_length(conname) > 50
ORDER BY byte_length DESC;
-- 긴 이름의 인덱스를 새로운 짧은 이름으로 교체
-- 기존 인덱스 삭제 후 새 이름으로 재생성
DROP INDEX IF EXISTS old_very_long_index_name_that_exceeds_limit;
CREATE INDEX idx_new_short_name ON target_table (target_column);
예방 방법
- 네이밍 컨벤션(Naming Convention)을 팀 표준으로 정립하고 자동화된 검증을 도입하세요.
팀 내에서 테이블명은 최대 30자, 컬럼명은 최대 25자, 인덱스/제약조건명은 최대 40자 등 PostgreSQL의 63바이트 제한 안에서 여유 있는 규칙을 미리 정하고 문서화하세요. CI/CD 파이프라인에 SQL 리뷰 단계를 추가하거나, 마이그레이션 스크립트 실행 전에 아래와 같은 검증 쿼리를 자동으로 수행하도록 구성하면 사전에 문제를 차단할 수 있습니다.
“`sql
— DDL 검토 시 사용할 수 있는 길이 검증 쿼리 예시
— 스키마 내 모든 객체 이름의 바이트 길이 점검
SELECT
‘table’ AS object_type,
table_name AS object_name,
octet_length(table_name) AS byte_length
FROM information_schema.tables
WHERE table_schema = ‘public’
AND octet_length(table_name) > 50
UNION ALL
SELECT
‘column’ AS object_type,
column_name AS object_name,
octet_length(column_name) AS byte_length
FROM information_schema.columns
WHERE table_schema = ‘public’
AND octet_length(column_name) > 50
ORDER BY byte_length DESC;
“`
- ORM 및 마이그레이션 도구 사용 시 반드시 생성되는 SQL을 사전 검토하세요.
Django의 sqlmigrate, Alembic의 --sql 옵션, Flyway의 dry-run 기능 등을 활용하여 실제 데이터베이스에 적용되기 전에 생성될 SQL을 미리 확인하는 습관을 들이세요. 특히 자동으로 이름이 생성되는 인덱스나 외래키 제약조건은 반드시 명시적으로 짧은 이름을 Model 또는 Migration 파일에서 지정하는 방식을 팀 규칙으로 정해두면 장기적으로 유지보수성이 크게 향상됩니다.
관련 에러
- 42601 (syntax_error): SQL 문법 오류로, 잘못된 식별자 형식(예: 따옴표 누락, 예약어 충돌)과 함께 발생할 수 있습니다.
- 42939 (reserved_name): PostgreSQL 내부 예약어를 식별자로 사용하려 할 때 발생하며, 42622와 함께 식별자 관련 에러 그룹에 속합니다.
- 42P07 (duplicate_table): 동일한 이름의 테이블이 이미 존재할 때 발생하며, 이름 잘림(truncation)으로 인해 의도치 않게 중복 이름이 생성될 경우 42622 이후 연쇄적으로 나타날 수 있습니다.
- 42703 (undefined_column): 이름이 63바이트로 잘린 컬럼을 원래 이름으로 참조하려 할 때 발생할 수 있어, 42622와 밀접하게 연관됩니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.