DBeaver 환경에서 Oracle DBMS를 실습하며 정리한 DDL 기초 개념 노트입니다.
테이블의 특정 컬럼에 자동으로 순차적인 번호를 부여하고 싶을 때 사용하는 독립적인 객체다.
MySQL의 AUTO_INCREMENT와 유사한 역할이지만, Oracle은 테이블에 내장된 개념이 아니라 별도의 객체로 분리되어 있다는 차이가 있다.
CREATE SEQUENCE SEQ_CAR;
SEQUENCE와 TABLE은 DDL 단계에서 직접 연결되지 않는다.
CREATE SEQUENCE SEQ_CAR;
CREATE TABLE TBL_CAR(
ID NUMBER CONSTRAINT PK_CAR PRIMARY KEY,
CAR_NAME VARCHAR2(255) NOT NULL,
CAR_BRAND VARCHAR2(255) NOT NULL,
CAR_PRICE NUMBER NOT NULL,
CAR_COLOR VARCHAR2(255) NOT NULL,
CAR_CREATE_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CAR_SEATER NUMBER NOT NULL
);
위 코드만 봐서는 SEQUENCE와 TABLE 사이의 연결고리가 없어 보이는게 정상이다.
실제 연결은 INSERT 시점에 .NEXTVAL을 호출하는 방식으로 이루어진다. (INSERT는 추후 정리 예정)
| 키워드 | 설명 |
|---|---|
SEQ_CAR.NEXTVAL | 다음 값 반환 (호출할 때마다 1씩 증가) |
SEQ_CAR.CURRVAL | 현재 값 반환 (증가하지 않음) |
CREATE TABLE TBL_CAR(
ID NUMBER DEFAULT SEQ_CAR.NEXTVAL CONSTRAINT PK_CAR PRIMARY KEY,
-- ...
);
이렇게 하면 INSERT 시 ID 컬럼을 생략해도 자동으로 SEQUENCE 값이 들어간다.
ID NUMBER CONSTRAINT PK_CAR PRIMARY KEY
PRIMARY KEY 하나에 아래 두 가지 제약이 자동으로 포함된다.
즉, PRIMARY KEY 컬럼에 별도로 UNIQUE나 NOT NULL을 추가로 선언할 필요가 없다.
EMAIL처럼 중요한 컬럼이지만 PRIMARY KEY가 아닌 경우, 두 제약조건을 모두 명시해야 완전한 무결성을 확보할 수 있다.
EMAIL VARCHAR2(255) NOT NULL UNIQUE
각각 빠졌을 때의 문제점은 아래와 같다.
-- UNIQUE만 있을 때 → NULL 값을 여러 행에 허용 (이메일 없는 회원 여럿 가능)
EMAIL VARCHAR2(255) UNIQUE
-- NOT NULL만 있을 때 → 같은 이메일로 여러 계정 생성 가능 (중복 허용)
EMAIL VARCHAR2(255) NOT NULL
-- 둘 다 있을 때 ✅ → 반드시 입력해야 하고, 중복도 불가
EMAIL VARCHAR2(255) NOT NULL UNIQUE
Oracle에서 UNIQUE 제약조건은 NULL을 중복으로 보지 않기 때문에,
NULL은 여러 행에 들어갈 수 있다는 점을 주의하자.
| 제약조건 | UNIQUE | NOT NULL |
|---|---|---|
UNIQUE | ✅ | ❌ (NULL 허용) |
PRIMARY KEY | ✅ | ✅ (NULL 불가) |
Oracle에서 두 자료형의 차이는 자주 헷갈리는 부분이다.
주의: MySQL 등 다른 DB와 달리 Oracle의 DATE는 시/분/초까지 저장한다.
DATE | TIMESTAMP | |
|---|---|---|
| 년 / 월 / 일 | ✅ | ✅ |
| 시 / 분 / 초 | ✅ | ✅ |
| 밀리초 / 마이크로초 | ❌ | ✅ |
| 시간대 (TimeZone) | ❌ | ✅ (옵션) |
-- DATE : 초까지
2024-01-15 14:30:25
-- TIMESTAMP : 나노초까지
2024-01-15 14:30:25.123456789
-- TIMESTAMP WITH TIME ZONE : 시간대까지
2024-01-15 14:30:25.123456789 +09:00
-- 일반적인 날짜/시간 기록은 DATE로 충분
JOIN_DATE DATE -- 가입일, 생년월일 등
-- 정밀한 시간이 필요할 때 TIMESTAMP
CAR_CREATE_AT TIMESTAMP -- 로그, 트랜잭션 기록 등
테이블을 생성한 이후에도 구조를 변경할 수 있다.
-- 컬럼 추가
ALTER TABLE TBL_CAR ADD CAR_FUEL VARCHAR2(50);
-- 컬럼 삭제 (COLUMN 키워드 필수!)
ALTER TABLE TBL_CAR DROP COLUMN CAR_COLOR;
-- 자료형 / 크기 변경
ALTER TABLE TBL_CAR MODIFY CAR_NAME VARCHAR2(500);
-- 컬럼 이름 변경
ALTER TABLE TBL_CAR RENAME COLUMN CAR_COLOR TO CAR_COLOUR;
-- NOT NULL 추가
ALTER TABLE TBL_USER MODIFY USER_NAME NOT NULL;
-- NOT NULL 해제
ALTER TABLE TBL_USER MODIFY USER_NAME NULL;
-- DEFAULT 값 설정
ALTER TABLE TBL_USER MODIFY USER_NAME DEFAULT 'SAM';
-- DEFAULT 값 제거
ALTER TABLE TBL_USER MODIFY USER_NAME DEFAULT NULL;
DROP COLUMN에서 COLUMN 키워드를 빠뜨리면 오류가 발생하니 주의하자.
ALTER TABLE TBL_CAR DROP CAR_COLOR;← 이렇게 하면 오류!
-- UNIQUE 추가
ALTER TABLE TBL_USER ADD CONSTRAINT UQ_USER_EMAIL UNIQUE (USER_EMAIL);
-- UNIQUE 제거
ALTER TABLE TBL_USER DROP CONSTRAINT UQ_USER_EMAIL;
ALTER로 제약조건을 추가했을 때 실제로 적용됐는지 확인하는 방법은 아래와 같다.
-- 제약조건 타입 확인
SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE, STATUS
FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'TBL_CAR';
| CONSTRAINT_TYPE | 의미 |
|---|---|
P | PRIMARY KEY |
U | UNIQUE |
C | CHECK / NOT NULL |
R | FOREIGN KEY |
-- 어떤 컬럼에 걸려있는지 함께 확인
SELECT C.CONSTRAINT_NAME, C.CONSTRAINT_TYPE, CC.COLUMN_NAME
FROM USER_CONSTRAINTS C
JOIN USER_CONS_COLUMNS CC ON C.CONSTRAINT_NAME = CC.CONSTRAINT_NAME
WHERE C.TABLE_NAME = 'TBL_CAR';
ALTER로 UNIQUE를 나중에 추가하는 문법 자체는 간단하지만, 이미 중복 데이터가 들어가 있으면 제약조건 추가 자체가 실패한다.
-- 중복 데이터가 있을 경우 아래 오류 발생
-- ORA-02299: 중복 키가 있어서 제약조건 추가 불가
| CREATE 단계 | ALTER 나중에 | |
|---|---|---|
| 문법 복잡도 | 간단 | 간단 |
| 데이터 없을 때 | ✅ | ✅ |
| 데이터 이미 있을 때 | — | ❌ 중복 있으면 오류 |
따라서 설계 단계에서 확실히 정해두는 습관이 중요하다.
두 테이블이 관계를 맺을 때 기본키(PK)와 외래키(FK)를 사용한다.
FK가 참조하는 PK 테이블이 반드시 먼저 존재해야 한다.
-- ✅ 올바른 생성 순서
CREATE TABLE TBL_MEMBER ( -- 1️⃣ PK 테이블 먼저
ID NUMBER PRIMARY KEY,
EMAIL VARCHAR2(255) NOT NULL UNIQUE
);
CREATE TABLE TBL_ORDER ( -- 2️⃣ FK 테이블 나중에
ID NUMBER PRIMARY KEY,
MEMBER_ID NUMBER REFERENCES TBL_MEMBER(ID)
);
DROP TABLE TBL_ORDER; -- 1️⃣ FK 테이블 먼저 삭제
DROP TABLE TBL_MEMBER; -- 2️⃣ PK 테이블 나중에 삭제
생성은 PK → FK 순서, 삭제는 FK → PK 순서
"참조 당하는 쪽이 먼저 존재해야 한다"고 기억하면 쉽다.
이번 학습에서 다룬 내용을 한 줄씩 정리하면 아래와 같다.
.NEXTVAL로 연결DROP COLUMN 키워드 필수다음 포스팅에서는 INSERT, UPDATE, DELETE 등 DML 구문을 정리할 예정이다.