Oracle DB Sequence 완벽 가이드: 생성부터 삭제까지
안녕하세요.
이번 포스팅은 Oracle 데이터베이스에서 일련번호를 자동으로 생성해주는 Sequence 객체에 대해 상세히 알아보겠습니다. Sequence는 고유한 값이 필요한 기본 키나 순차적인 번호가 필요할 때 매우 유용한 데이터베이스 객체입니다. 이 글에서는 Sequence의 생성부터 삭제까지 모든 과정을 자세히 설명하겠습니다.

목차
- Sequence란?
- Sequence 생성하기
- Sequence 사용하기
- Sequence 수정하기
- Sequence 삭제하기
- Sequence 정보 조회하기
- Sequence 활용 사례
- Sequence 성능 최적화
- 다른 DBMS의 Sequence
- 자주 묻는 질문
#1. Sequence란?
Sequence는 일련의 숫자를 자동으로 생성해주는 데이터베이스 객체입니다. 주로 기본 키(Primary Key)나 고유 식별자를 생성하는데 사용됩니다.
Sequence의 주요 특징:
- 유일한 숫자 값을 자동 생성
- 공유 가능한 객체로 여러 테이블에서 사용 가능
- 독립적인 객체로 테이블과 별도로 관리
- 메모리에 캐싱되어 빠른 접근 가능
- 순차적 또는 특정 간격으로 증가/감소 가능
#2. Sequence 생성하기
Sequence를 생성하는 기본 구문은 다음과 같습니다:
CREATE SEQUENCE 시퀀스_이름 [INCREMENT BY n] [START WITH n] [MAXVALUE n | NOMAXVALUE] [MINVALUE n | NOMINVALUE] [CYCLE | NOCYCLE] [CACHE n | NOCACHE] [ORDER | NOORDER]; |
각 옵션의 의미는 다음과 같습니다:
- INCREMENT BY n: 시퀀스 증가/감소 값 (기본값 1)
- START WITH n: 시퀀스 시작 값 (기본값 1)
- MAXVALUE n: 최대값 지정
- NOMAXVALUE: 최대값 없음 (기본값, 오름차순일 경우 10^27)
- MINVALUE n: 최소값 지정
- NOMINVALUE: 최소값 없음 (기본값, 오름차순일 경우 1)
- CYCLE: 최대/최소값 도달 시 다시 시작
- NOCYCLE: 최대/최소값 도달 시 에러 발생 (기본값)
- CACHE n: 메모리에 시퀀스 값을 미리 할당 (기본값 20)
- NOCACHE: 메모리에 캐싱하지 않음
- ORDER: 요청 순서대로 값 생성 보장
- NOORDER: 요청 순서 보장하지 않음 (기본값)
2.1 기본 Sequence 생성
가장 간단한 형태의 Sequence 생성 예제입니다:
CREATE SEQUENCE employee_seq; |
이 명령은 1부터 시작하여 1씩 증가하는 기본 시퀀스를 생성합니다.
2.2 다양한 옵션을 사용한 Sequence 생성
CREATE SEQUENCE order_seq INCREMENT BY 10 START WITH 1000 MAXVALUE 9999999 CACHE 50 NOCYCLE; |
이 시퀀스는 1000부터 시작하여 10씩 증가하며, 최대값은 9,999,999입니다. 또한 성능 향상을 위해 50개의 값을 메모리에 캐싱합니다.
2.3 감소하는 Sequence 생성
CREATE SEQUENCE countdown_seq INCREMENT BY -1 START WITH 100 MINVALUE 1 MAXVALUE 100 CYCLE NOCACHE; |
이 시퀀스는 100부터 시작하여 1씩 감소하며, 1에 도달하면 다시 100부터 반복합니다.
#3. Sequence 사용하기
Sequence에서 값을 가져오는 방법은 두 가지가 있습니다:
- NEXTVAL: 다음 시퀀스 값을 반환하고 시퀀스를 증가시킵니다.
- CURRVAL: 현재 세션에서 마지막으로 생성된 시퀀스 값을 반환합니다.
3.1 NEXTVAL 사용
-- 새로운 시퀀스 값 가져오기 SELECT employee_seq.NEXTVAL FROM dual; -- 테이블에 삽입 시 사용 INSERT INTO employees (employee_id, first_name, last_name) VALUES (employee_seq.NEXTVAL, 'John', 'Doe'); |
3.2 CURRVAL 사용
-- 현재 시퀀스 값 조회 (같은 세션에서 NEXTVAL을 한 번 이상 호출한 후에만 사용 가능) SELECT employee_seq.CURRVAL FROM dual; -- 조회 후 다른 테이블에 같은 값 사용 INSERT INTO employee_log (log_id, employee_id, action) VALUES (log_seq.NEXTVAL, employee_seq.CURRVAL, 'INSERT'); |
중요: CURRVAL을 사용하기 전에 같은 세션에서 해당 시퀀스의 NEXTVAL을 최소 한 번 호출해야 합니다.
3.3 Sequence 사용 가능한 위치
Sequence는 다음 위치에서 사용할 수 있습니다:
- SELECT 문의 SELECT 목록
- INSERT 문의 VALUES 절
- UPDATE 문의 SET 절
- 서브쿼리의 SELECT 목록
하지만 다음 위치에서는 사용할 수 없습니다:
- VIEW의 SELECT 문
- DISTINCT가 있는 SELECT 문
- GROUP BY, HAVING, ORDER BY 절
- 서브쿼리의 SELECT 문
- CHECK 제약 조건의 DEFAULT 값
#4. Sequence 수정하기
이미 생성된 Sequence의 설정을 변경해야 할 때는 ALTER SEQUENCE 명령을 사용합니다:
ALTER SEQUENCE 시퀀스_이름 [INCREMENT BY n] [MAXVALUE n | NOMAXVALUE] [MINVALUE n | NOMINVALUE] [CYCLE | NOCYCLE] [CACHE n | NOCACHE] [ORDER | NOORDER]; |
주의할 점은 START WITH 값은 ALTER 명령으로 변경할 수 없다는 것입니다. 시작 값을 변경하려면 시퀀스를 삭제하고 다시 생성해야 합니다.
4.1 Sequence 증분 값 변경
ALTER SEQUENCE employee_seq INCREMENT BY 5; |
4.2 최대값 및 캐시 설정 변경
ALTER SEQUENCE order_seq MAXVALUE 20000000 CACHE 100; |
4.3 CYCLE 옵션 추가
ALTER SEQUENCE countdown_seq CYCLE; |
#5. Sequence 삭제하기
Sequence가 더 이상 필요하지 않을 때는 DROP SEQUENCE 명령으로 삭제할 수 있습니다:
DROP SEQUENCE 시퀀스_이름; |
5.1 기본 삭제 예제
DROP SEQUENCE employee_seq; |
5.2 조건부 삭제
시퀀스가 존재할 경우에만 삭제하는 방법입니다(Oracle 10g 이상):
DROP SEQUENCE IF EXISTS temp_seq; |
12c 이전 버전에서는 PL/SQL 블록을 사용해야 합니다:
BEGIN EXECUTE IMMEDIATE 'DROP SEQUENCE temp_seq'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -2289 THEN RAISE; END IF; END; |
#6. Sequence 정보 조회하기
데이터베이스에 생성된 시퀀스 정보를 조회하려면 데이터 딕셔너리 뷰를 사용합니다:
6.1 모든 시퀀스 조회
-- 현재 사용자의 모든 시퀀스 목록 SELECT sequence_name, min_value, max_value, increment_by, last_number, cache_size, cycle_flag FROM user_sequences; -- 모든 시퀀스 목록 (DBA 권한 필요) SELECT sequence_owner, sequence_name, min_value, max_value, increment_by, last_number, cache_size, cycle_flag FROM dba_sequences; |
6.2 특정 시퀀스 정보 조회
SELECT sequence_name, min_value, max_value, increment_by, last_number, cache_size, cycle_flag FROM user_sequences WHERE sequence_name = 'EMPLOYEE_SEQ'; |
#7. Sequence 활용 사례
7.1 테이블 기본 키 자동 생성
-- 테이블 생성 CREATE TABLE customers ( customer_id NUMBER PRIMARY KEY, customer_name VARCHAR2(100) NOT NULL, email VARCHAR2(100) ); -- 시퀀스 생성 CREATE SEQUENCE customer_seq START WITH 1000 INCREMENT BY 1 NOCACHE NOCYCLE; -- 데이터 삽입 INSERT INTO customers (customer_id, customer_name, email) VALUES (customer_seq.NEXTVAL, 'Alice Johnson', 'alice@example.com'); INSERT INTO customers (customer_id, customer_name, email) VALUES (customer_seq.NEXTVAL, 'Bob Smith', 'bob@example.com'); |
7.2 트리거와 함께 사용하기
-- 시퀀스 생성 CREATE SEQUENCE invoice_seq START WITH 10001 INCREMENT BY 1; -- 트리거 생성 CREATE OR REPLACE TRIGGER trg_invoice_id BEFORE INSERT ON invoices FOR EACH ROW BEGIN IF :NEW.invoice_id IS NULL THEN :NEW.invoice_id := invoice_seq.NEXTVAL; END IF; END; -- 이제 아래와 같이 invoice_id를 명시하지 않아도 자동 생성됩니다 INSERT INTO invoices (customer_id, amount, invoice_date) VALUES (1001, 599.99, SYSDATE); |
7.3 주문 번호 형식 생성하기
-- 시퀀스 생성 CREATE SEQUENCE order_num_seq START WITH 1 INCREMENT BY 1; -- 주문 번호 생성 함수 CREATE OR REPLACE FUNCTION generate_order_number RETURN VARCHAR2 IS v_order_num VARCHAR2(20); BEGIN v_order_num := 'ORD-' || TO_CHAR(SYSDATE, 'YYYYMMDD') || '-' || LPAD(order_num_seq.NEXTVAL, 5, '0'); RETURN v_order_num; END; -- 함수 사용 예 INSERT INTO orders (order_id, customer_id, order_date) VALUES (generate_order_number(), 1001, SYSDATE); -- 예: ORD-20250330-00001 |
#8. Sequence 성능 최적화
8.1 캐시 설정 최적화
시퀀스 성능을 최적화하는 가장 효과적인 방법은 적절한 캐시 크기를 설정하는 것입니다:
-- 트랜잭션이 많은 테이블을 위한 대용량 캐시 설정 ALTER SEQUENCE high_volume_seq CACHE 1000; |
캐시 크기를 결정할 때 고려할 사항:
- 트랜잭션 볼륨(초당 INSERT 수)
- 인스턴스 재시작 시 손실 가능한 값의 수
- 메모리 사용량
8.2 NOORDER 옵션 사용
분산 시스템이나 RAC 환경이 아니라면 성능 향상을 위해 NOORDER 옵션을 사용하세요:
CREATE SEQUENCE perf_seq CACHE 100 NOORDER; |
8.3 병렬 처리 최적화
대량 데이터 로드 시, 여러 세션에서 효율적으로 시퀀스를 사용하려면:
-- 대량 로드를 위한 시퀀스 설정 CREATE SEQUENCE bulk_load_seq INCREMENT BY 1000 CACHE 10000 NOORDER; -- 각 세션별로 다른 시작점 설정 -- 세션 1 ALTER SEQUENCE bulk_load_seq INCREMENT BY 1; SELECT bulk_load_seq.NEXTVAL FROM dual; -- 1 반환 -- 세션 2 ALTER SEQUENCE bulk_load_seq INCREMENT BY 1; SELECT bulk_load_seq.NEXTVAL + 1 FROM dual; -- 2 반환 -- 세션 3 ALTER SEQUENCE bulk_load_seq INCREMENT BY 1; SELECT bulk_load_seq.NEXTVAL + 2 FROM dual; -- 3 반환 |
#9. 다른 DBMS의 Sequence
9.1 MySQL에서의 Sequence 대안
MySQL 8.0 이전 버전에서는 Sequence 객체가 없었습니다. 대신 AUTO_INCREMENT 속성을 사용합니다:
-- MySQL에서 AUTO_INCREMENT 사용 CREATE TABLE customers ( customer_id INT AUTO_INCREMENT PRIMARY KEY, customer_name VARCHAR(100) NOT NULL, email VARCHAR(100) ); -- 시작값 설정 ALTER TABLE customers AUTO_INCREMENT = 1000; |
MySQL 8.0부터는 시퀀스 객체 지원:
-- MySQL 8.0+ 시퀀스 생성 CREATE SEQUENCE customer_seq START WITH 1000 INCREMENT BY 1; -- 사용 방법 SELECT NEXT VALUE FOR customer_seq; |
9.2 SQL Server에서의 Sequence
SQL Server 2012부터 Sequence 객체를 지원합니다:
-- SQL Server 시퀀스 생성 CREATE SEQUENCE customer_seq START WITH 1000 INCREMENT BY 1 MINVALUE 1000 MAXVALUE 9999999 CYCLE CACHE 100; -- 사용 방법 SELECT NEXT VALUE FOR customer_seq; |
9.3 PostgreSQL에서의 Sequence
PostgreSQL은 오래 전부터 시퀀스를 지원했습니다:
-- PostgreSQL 시퀀스 생성 CREATE SEQUENCE customer_seq INCREMENT BY 1 START WITH 1000 NO MAXVALUE NO CYCLE CACHE 20; -- 사용 방법 SELECT nextval('customer_seq'); SELECT currval('customer_seq'); |
#10. 자주 묻는 질문
Q1: 시퀀스 값이 갑자기 건너뛰는 이유는 무엇인가요?
A: 시퀀스 값이 건너뛰는 주요 원인은 다음과 같습니다:
- 시퀀스 캐싱: 캐시된 값이 사용되지 않고 인스턴스가 재시작된 경우
- 롤백: 트랜잭션이 롤백되어도 시퀀스 값은 롤백되지 않음
- 세션 종료: 세션이 비정상 종료되면 할당된 시퀀스 값이 손실됨
Q2: CURRVAL을 사용할 때 "ORA-08002: sequence XXXX.YYYY.nextval must be used before this pseudo-column" 오류가 발생합니다.
A: CURRVAL을 사용하기 전에 반드시 같은 세션에서 해당 시퀀스의 NEXTVAL을 한 번 이상 호출해야 합니다. 새 세션이 시작되면 NEXTVAL을 다시 호출해야 CURRVAL을 사용할 수 있습니다.
Q3: 시퀀스를 특정 값으로 재설정하는 방법은 무엇인가요?
A: Oracle에서는 시퀀스의 현재 값을 직접 변경할 수 없습니다. 대신 다음과 같은 방법을 사용할 수 있습니다:
-- 시퀀스 증분 값을 원하는 값과의 차이로 변경 DECLARE v_next_val NUMBER; v_desired_val NUMBER := 5000; -- 원하는 값 BEGIN SELECT seq_name.NEXTVAL INTO v_next_val FROM dual; EXECUTE IMMEDIATE 'ALTER SEQUENCE seq_name INCREMENT BY ' || (v_desired_val - v_next_val); SELECT seq_name.NEXTVAL INTO v_next_val FROM dual; EXECUTE IMMEDIATE 'ALTER SEQUENCE seq_name INCREMENT BY 1'; END; |
Q4: 시퀀스 값에 갭(gap)이 생기지 않게 하려면 어떻게 해야 하나요?
A: 시퀀스는 기본적으로 갭이 생길 수 있도록 설계되었으며, 이는 성능을 위한 것입니다. 갭 없는 시퀀스가 필요하다면 다음 방법을 고려하세요:
- NOCACHE 옵션 사용 (성능 저하 감수)
- 테이블을 사용한 자체 시퀀스 구현
- 트랜잭션 테이블 사용
-- 갭 없는 시퀀스를 위한 테이블 방식 CREATE TABLE gapless_sequence ( sequence_name VARCHAR2(30) PRIMARY KEY, current_value NUMBER NOT NULL ); INSERT INTO gapless_sequence VALUES ('MY_SEQUENCE', 0); -- 다음 값 얻기 (PL/SQL 함수) CREATE OR REPLACE FUNCTION get_next_gapless_value(p_seq_name VARCHAR2) RETURN NUMBER IS v_value NUMBER; BEGIN UPDATE gapless_sequence SET current_value = current_value + 1 WHERE sequence_name = p_seq_name RETURNING current_value INTO v_value; RETURN v_value; END; |
Q5: 기존 테이블의 데이터를 기반으로 시퀀스 시작 값을 설정하려면 어떻게 해야 하나요?
A: 테이블의 최대값 + 1로 시퀀스를 생성하려면:
DECLARE v_max_id NUMBER; BEGIN -- 최대 ID 값 조회 SELECT NVL(MAX(employee_id), 0) INTO v_max_id FROM employees; -- 시퀀스 삭제 (있을 경우) BEGIN EXECUTE IMMEDIATE 'DROP SEQUENCE emp_id_seq'; EXCEPTION WHEN OTHERS THEN NULL; END; -- 최대값 + 1부터 시작하는 시퀀스 생성 EXECUTE IMMEDIATE 'CREATE SEQUENCE emp_id_seq START WITH ' || (v_max_id + 1) || ' INCREMENT BY 1 NOCACHE NOCYCLE'; END; |
결론
이 글에서는 Oracle 데이터베이스의 Sequence 객체에 대해 생성부터 삭제, 그리고 다양한 활용 방법까지 자세히 살펴보았습니다. Sequence는 기본 키나 고유 식별자를 생성하는 데 매우 유용한 도구로, 올바르게 설계하고 최적화하면 데이터베이스 애플리케이션의 성능과 무결성을 향상시킬 수 있습니다.
특히 캐시 설정, 증분 값 조정, 그리고 다양한 옵션을 통해 다양한 비즈니스 요구사항에 맞게 Sequence를 구성할 수 있습니다. 또한 트리거나 기본값과 함께 사용하면 데이터 입력 작업을 더욱 간소화할 수 있습니다.
다른 DBMS에서도 비슷한 기능을 제공하므로, 이 지식은 Oracle뿐만 아니라 다양한 데이터베이스 환경에서도 활용할 수 있습니다.
긴 글 읽어주셔서 감사합니다.
끝.
'■Development■ > 《Database》' 카테고리의 다른 글
[DB] Oracle SQL 완벽 정리 (0) | 2022.08.31 |
---|---|
[DB] Oracle Listener 완벽 가이드 (0) | 2020.04.08 |
[DB] ROWNUM과 ROWID의 완벽한 이해 (0) | 2020.04.08 |
[DB] ORACLE DB 사용자 계정 패스워드 없애는 방법 (0) | 2020.04.08 |
[DB] ORACLE DB SYSTEM, SYS 암호 변경 (0) | 2020.04.08 |