본문 바로가기
정보관리(데이터베이스, DB)/DB

DB 릴레이션 관계선 references 생략 시 문제

by 3604 2025. 9. 24.
728x90
물리 테이블을 만들 때 FK(외래 키)용 CONSTRAINT에서 REFERENCES 절을 아예 생략하면 문법 오류부터 데이터 무결성 붕괴까지 단계별로 다음과 같은 문제가 발생합니다.
  1. DDL 단계에서 문법 오류
    • 표준 SQL(Oracle·PostgreSQL·SQL Server 등)은
      FOREIGN KEY (col) REFERENCES parent(col) 형태를 강제합니다.
      REFERENCES 키워드가 없으면 “ORA-00906: missing left parenthesis”
      또는 “Syntax error near FOREIGN” 등으로 CREATE TABLE 자체가 실패합니다.
  2. MySQL만 특이 케이스 – 문법은 통과하지만 FK 자체가 생성 안 됨
    • MySQL(InnoDB)에서
      CONSTRAINT fk_name FOREIGN KEY (child_id) ← REFERENCES 없이 끝내면
      문법 오류는 나지 않지만 실제로 외래 키 객체가 생성되지 않습니다.
      SHOW CREATE TABLE을 해도 FK 정의가 보이지 않으며,
      information_schema.table_constraints에도 CONSTRAINT_TYPE='FOREIGN KEY' 레코드가 없습니다.
      결과적으로 아래 3~5번의 모든 무결성 기능이 완전히 작동하지 않습니다.
  3. 부모-자식 관계 무결성 검사 자체가 사라짐
    • 부모 테이블에 없는 값을 자식 테이블에 입력해도 에러 없이 들어갑니다.
    • 부모 row를 삭제/변경해도 자식 row에 영향을 주지 않습니다(ON DELETE/UPDATE 규칙이 없으므로).
      고아 데이터(orphan row) 가 무한 증가합니다.
  4. 조인 결과 오류, 애플리케이션 버그 유발
    • 개발자는 “FK가 걸려 있겠지”라고 가정하고 조인하거나 삭제 로직을 짜지만,
      실제로는 존재하지 않는 부모 키와 조인되어 NULL 또는 중복 exploding이 발생합니다.
    • 추후에 진짜 FK를 추가하려고 하면 이미 무결성 깨진 데이터 때문에
      ALTER TABLE ... ADD CONSTRAINT가 실패합니다(불일치 값 존재).
  5. 옵티마이저 힌트 및 성능 이점 상실
    • FK가 없으면 옵티마이저가 부모 테이블 통계·인덱스 활용을 할 수 없고,
      일부 DBMS(MySQL, PostgreSQL)는 FK 정보를 이용한 내부 join elimination도 하지 못합니다.
  6. 도구/프레임워크와의 계약 위반
    • JPA, Hibernate, Rails ActiveRecord, Django ORM 등은
      데이터베이스에 FK가 있어야 cascade, restrict, nullify 동작을 맡깁니다.
      FK 정의가 아예 없으면 애플리케이션 레벨 cascade도 작동하지 않습니다.
정리
REFERENCES를 생략하면
  • 대부분의 DBMS는 CREATE TABLE 단계에서 실패하고,
  • 유일하게 MySQL은 무성의한 정의를 그대로 무시해 주는데,
    이 경우 외래 키 자체가 존재하지 않으므로 데이터 무결성, 삭제 규칙, 성능 최적화,
    애플리케이션 로직까지 전 분야에 걸쳐 치명적인 문제를 낳습니다.
    따라서 FK가 필요한 상황이면 반드시
    FOREIGN KEY (child_col) REFERENCES parent(parent_col) [ON DELETE ...] [ON UPDATE ...]
    형태로 완전한 CONSTRAINT를 선언해야 합니다.

 

TIBERO(티베로)에서도 Oracle 문법을 그대로 따르기 때문에,
CONSTRAINT … FOREIGN KEY(컬럼) 뒤에 REFERENCES 부모테이블(컬럼) 절을 빼면 컴파일(구문 분석) 단계에서 즉시 에러가 발생합니다.
  1. 구문 오류로 CREATE TABLE 자체가 실패
    Copy
    CREATE TABLE child
    ( id        NUMBER PRIMARY KEY,
      parent_id NUMBER,
      CONSTRAINT fk_child_parent FOREIGN KEY(parent_id)   -- REFERENCES 없음
    );
    실행 즉시
    TBR-00906: missing LEFT PARENTHESIS
    또는
    ORA-00906: missing left parenthesis
    가 리턴됩니다. (Tibero는 Oracle error 번호를 그대로 매핑해 줍니다.)
  2. REFERENCES를 쓰지 않으면 FOREIGN KEY 객체가 생성되지 않음
    Tibero 딕셔너리(USER_CONSTRAINTS, USER_CONS_COLUMNS)에는
    CONSTRAINT_TYPE = 'R' 레코드가 INSERT되지 않습니다.
    → 데이터 무결성 검사, 옵티마이저의 join-elimination, cascade 동작 등 모든 FK 기능이 사라집니다.
  3. 결과적으로 발생하는 운영 문제
    • 부모 테이블에 없는 값을 자식이 가질 수 있어 고아 데이터(orphan) 가 무한 증가
    • 부모 row를 삭제·변경해도 자식이 제약받지 않아 의도하지 않은 데이터 누락
    • 나중에 ALTER TABLE … ADD CONSTRAINT … REFERENCES로 추가하려면
      이미 쌓인 무결성 깨진 데이터 때문에 ALTER 문이 실패
    • JPA/ORM 툴은 FK 메타데이터를 읽지 못해 cascade 설정이 동작하지 않음
  4. Tibero에서의 권장写法
    sql
    Copy
    CREATE TABLE parent
    ( p_id NUMBER PRIMARY KEY );
    
    CREATE TABLE child
    ( c_id      NUMBER PRIMARY KEY,
      parent_id NUMBER      NOT NULL,
      CONSTRAINT fk_child_parent
          FOREIGN KEY(parent_id)
          REFERENCES parent(p_id)   -- 반드시 명시
          ON DELETE CASCADE         -- 필요 시 규칙 추가
    );
요약
Tibero는 REFERENCES 키워드가 없으면 DDL 단계에서 구문 오류를 내며 테이블 생성이 불가능합니다.
따라서 “REFERENCES를 안 써도 묵시적으로 FK가 동작한다”는 일은 어떤 DBMS에서도 없으며,
Tibero 역시 명시적인 REFERENCES 절이 필수입니다.
728x90