같은 스키마 안에서 테이블과 시퀀스에 같은 이름을 쓸 수 있는지가 자주 문제가 된다. 흔히 "권장하지 않을 뿐 기술적으로는 가능하다"고 설명하지만 Oracle 에서는 사실이 아니다. 시도하면 ORA-00955: name is already used by an existing object 로 막힌다.
Oracle 은 스키마마다 이름공간(namespace)을 두고, 한 이름공간 안에서는 이름이 유일해야 한다. 중요한 점은 여러 종류의 객체가 하나의 이름공간을 공유한다는 것이다.
같은 이름공간을 쓰는 객체는 다음과 같다.
| 구분 | 객체 |
|---|---|
| 공유 이름공간 | 테이블, 뷰, 시퀀스, 프라이빗 시노님, 독립 프로시저, 독립 함수, 패키지, 구체화 뷰, 사용자 정의 타입 |
| 각자 별도 이름공간 | 인덱스, 제약조건, 클러스터, 데이터베이스 트리거, 프라이빗 데이터베이스 링크, 디멘션 |
따라서 테이블 ORDERS 가 있는 스키마에 시퀀스 ORDERS 를 만들 수 없다. 반대로 인덱스 이름은 별도 이름공간이므로 테이블과 같은 이름을 붙이는 것이 문법적으로 허용된다.
이름이 이미 쓰이고 있는지는 사전 뷰에서 확인한다.
SELECT object_type, object_name, status
FROM user_objects
WHERE object_name = UPPER('orders');
제약조건과 인덱스는 별도 뷰를 본다.
SELECT constraint_name, table_name FROM user_constraints WHERE constraint_name = UPPER('orders');
SELECT index_name, table_name FROM user_indexes WHERE index_name = UPPER('orders');
이름이 겹치지 않더라도 역할을 접미사로 구분해 두면 사전 조회와 코드 검색이 쉬워진다. ORDERS 테이블에는 ORDERS_SEQ 시퀀스, ORDERS_PK 기본키, ORDERS_IX01 인덱스처럼 붙이는 방식이 일반적이다.
12c 부터는 GENERATED BY DEFAULT AS IDENTITY 컬럼을 쓰면 시퀀스를 따로 만들지 않아도 되므로 이름 충돌 자체가 사라진다.
CREATE TABLE orders (
order_id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
ordered_at DATE DEFAULT SYSDATE
);