[데이터베이스] SQL

허경두·2025년 4월 22일

Database

목록 보기
2/9

SQL

SQL(Structured Query Language)은 관계형 데이터베이스 관리 시스템(RDBMS)의 데이터를 관리하기 위해 설계한 특수 목적의 프로그래밍 언어이다

DDL

DDL(Data Definition Language) : 데이터베이스 구조 정의에 사용하는 언어

CREATE

객체 생성 명령어

MySQL

테이블 생성

CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(255) UNIQUE,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='회원 정보 테이블';
  • column options

    옵션설명
    NOT NULLNULL 허용 안 함
    NULLNULL 허용
    DEFAULT 값기본값 지정
    AUTO_INCREMENT자동 증가
    UNIQUE유일값 제약
    PRIMARY KEY기본 키 지정
    COMMENT '설명'컬럼 주석
    CHECK (조건)제약 조건 (MySQL 8.0 이상)
    GENERATED ALWAYS AS (...) STORED생성된 컬럼 (계산된 값 저장)
  • table options

    옵션설명
    ENGINE=InnoDB스토리지 엔진 지정
    DEFAULT CHARSET=utf8mb4문자셋 지정
    COLLATE=utf8mb4_unicode_ci정렬 방식 지정
    COMMENT='테이블 설명'테이블 주석
    AUTO_INCREMENT=1000자동 증가 시작 값

인덱스 생성

CREATE UNIQUE INDEX idx_email ON users(email) USING BTREE;
  • options

    옵션설명
    UNIQUE유일한 값만 허용되는 인덱스 생성
    USING BTREE인덱스 알고리즘 지정 (BTREE, HASH 등)
    VISIBLE / INVISIBLE인덱스 사용 여부 제어 (8.0 이상)

뷰 생성

CREATE ALGORITHM=MERGE SQL SECURITY DEFINER VIEW user_view AS
SELECT * FROM users WHERE is_active = 1
WITH CHECK OPTION;
  • options

    옵션설명
    ALGORITHM뷰 생성 알고리즘 지정 (UNDEFINED, MERGE, TEMPTABLE)
    DEFINER뷰 생성자 명시 (DEFINER = 'user'@'host')
    SQL SECURITY권한 설정 (DEFINER 또는 INVOKER)
    WITH CHECK OPTION수정 시 WHERE 조건 강제

트리거 생성

CREATE TRIGGER trg_users_insert
BEFORE INSERT ON users
FOR EACH ROW
SET NEW.created_at = NOW();
  • options

    옵션설명
    BEFORE / AFTER트리거 실행 시점 지정
    INSERT/UPDATE/DELETE작동할 DML 종류 지정
    FOR EACH ROW행 단위 트리거

시퀀스 생성 (MySQL 8.0부터)

CREATE SEQUENCE user_seq
START WITH 1000 INCREMENT BY 1 CYCLE;
  • options

    옵션설명
    START WITH시작값
    INCREMENT BY증가값
    MINVALUE / MAXVALUE최소/최대값
    CYCLE / NO CYCLE값이 최대 도달 시 재순환 여부
    CACHE메모리에 미리 저장할 숫자 수

Oracle

테이블 생성

CREATE TABLE users (
  id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  name VARCHAR2(100) NOT NULL,
  email VARCHAR2(255) UNIQUE,
  created_at DATE DEFAULT SYSDATE,
  full_name VARCHAR2(255) GENERATED ALWAYS AS (name || ' ' || email) VIRTUAL
) TABLESPACE userspace LOGGING;
  • column options

    옵션설명
    NOT NULLNULL 허용 안 함
    DEFAULT 값기본값 지정
    UNIQUE유일값 제약
    PRIMARY KEY기본 키 지정
    CHECK (조건)제약 조건
    GENERATED ALWAYS AS IDENTITY자동 증가 컬럼 (Oracle 12c 이상)
    INVISIBLE기본적으로 SELECT 시 보이지 않게 설정
    VIRTUAL or STORED계산된 컬럼 설정
  • table options

    옵션설명
    TABLESPACE저장할 테이블스페이스 지정
    PCTFREE, PCTUSED블록 내 여유공간 관리
    INITRANS, MAXTRANS동시 트랜잭션 수 설정
    LOGGING / NOLOGGING로깅 여부 설정
    COMPRESS / NOCOMPRESS데이터 압축 설정
    ENABLE ROW MOVEMENT파티션 간 행 이동 허용

인덱스 생성

CREATE UNIQUE INDEX idx_email ON users(email) TABLESPACE indexspace;
  • options

    옵션설명
    UNIQUE유일한 값만 허용되는 인덱스 생성
    TABLESPACE인덱스를 저장할 테이블스페이스 지정
    NOPARALLEL / PARALLEL병렬 인덱스 생성 여부
    COMPRESS인덱스 압축

뷰 생성

CREATE VIEW active_users AS
SELECT * FROM users WHERE is_active = 1
WITH CHECK OPTION;
  • options

    옵션설명
    WITH CHECK OPTIONINSERT/UPDATE 시 조건 강제
    WITH READ ONLY뷰를 읽기 전용으로 설정

트리거 생성

CREATE OR REPLACE TRIGGER trg_users_insert
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
  :NEW.created_at := SYSDATE;
END;
  • options

    옵션설명
    BEFORE / AFTER트리거 실행 시점
    INSERT/UPDATE/DELETE작동할 DML 지정
    FOR EACH ROW행 단위 트리거
    WHEN (조건)특정 조건일 때만 작동

시퀀스 생성

CREATE SEQUENCE user_seq
START WITH 1000 INCREMENT BY 1 NOCACHE NOCYCLE;
  • options

    옵션설명
    START WITH시작값
    INCREMENT BY증가값
    MINVALUE / MAXVALUE최소/최대값
    CYCLE / NOCYCLE값이 최대 도달 시 재순환 여부
    CACHE / NOCACHE메모리 캐싱 여부
    ORDER / NOORDER순서 보장 여부

ALTER

객체 구조 변경 명령어

MySQL

ALTER TABLE users ADD COLUMN age INT;
ALTER TABLE users MODIFY COLUMN name VARCHAR(200);
ALTER TABLE users CHANGE COLUMN email email_address VARCHAR(255);
ALTER TABLE users DROP COLUMN age;
ALTER TABLE users RENAME TO members;
구문 종류설명
ADD COLUMN새로운 컬럼 추가
DROP COLUMN컬럼 삭제
MODIFY COLUMN기존 컬럼의 타입/속성 변경
CHANGE COLUMN컬럼 이름 및 속성 변경
RENAME COLUMN컬럼 이름 변경 (MySQL 8.0 이상)
RENAME TO테이블 이름 변경
ADD CONSTRAINT제약 조건 추가 (PRIMARY KEY, FOREIGN KEY)
DROP PRIMARY KEY기본 키 삭제
DROP FOREIGN KEY외래 키 삭제
ADD INDEX, ADD UNIQUE인덱스 추가
DROP INDEX인덱스 삭제
ALTER COLUMN ... SET DEFAULT기본값 설정
ALTER COLUMN ... DROP DEFAULT기본값 제거
CONVERT TO CHARACTER SET문자셋 변경

Oracle

ALTER TABLE users ADD age NUMBER;
ALTER TABLE users MODIFY name VARCHAR2(200);
ALTER TABLE users RENAME COLUMN email TO email_address;
ALTER TABLE users RENAME TO members;
ALTER TABLE users ADD CONSTRAINT pk_users PRIMARY KEY (id);
ALTER TABLE users DROP CONSTRAINT pk_users;
구문 종류설명
ADD새로운 컬럼 추가
DROP COLUMN컬럼 삭제
MODIFY컬럼의 데이터 타입, 제약 조건 변경
RENAME COLUMN ... TO컬럼 이름 변경 (Oracle 12c 이상)
RENAME TO테이블 이름 변경
ADD CONSTRAINT제약 조건 추가 (PRIMARY KEY, FOREIGN KEY 등)
DROP CONSTRAINT제약 조건 삭제
ENABLE / DISABLE CONSTRAINT제약 조건 활성/비활성
SET UNUSED / DROP UNUSED COLUMNS컬럼 논리적 제거
ALTER COLUMN ... SET DEFAULT기본값 설정
ALTER COLUMN ... DROP DEFAULT기본값 제거
MOVE TABLESPACE테이블을 다른 테이블스페이스로 이동

MySQL vs. Oracle

ALTER INDEX

기능MySQLOracle
이름 변경ALTER TABLE DROP INDEX + ADD INDEX 조합 사용ALTER INDEX index_name RENAME TO new_name
재생성직접 삭제 후 재생성 필요ALTER INDEX index_name REBUILD
비활성화/활성화없음ALTER INDEX index_name UNUSABLE
저장 위치 변경없음ALTER INDEX index_name REBUILD TABLESPACE ts

ALTER VIEW

기능MySQLOracle
뷰 정의 수정CREATE OR REPLACE VIEW 사용CREATE OR REPLACE VIEW 사용
읽기 전용 설정WITH READ ONLY 포함하여 다시 정의WITH READ ONLY 포함하여 다시 정의
권한 변경GRANT, REVOKE 명령으로 처리GRANT, REVOKE 명령으로 처리
직접 ALTER 명령어❌ 없음❌ 없음

ALTER TRIGGER

기능MySQLOracle
트리거 수정삭제 후 재생성 필요ALTER TRIGGER trigger_name 문법 사용 가능
활성/비활성화❌ 지원 안 함 (삭제 후 재생성 필요)ENABLE / DISABLE 지원
이름 변경❌ 직접 불가❌ 직접 불가 (삭제 후 재생성 필요)

ALTER SEQUENCE

기능MySQL (8.0 이상)Oracle
시작값/증가값 변경ALTER SEQUENCE 일부 지원ALTER SEQUENCE 완전 지원
캐시 설정CACHE, NOCACHE 등 지원CACHE, NOCACHE, CYCLE, NOCYCLE 등 완전 지원
재시작RESTART WITH 사용 가능START WITH 변경 불가 → 새로 만들어야 함

DROP

객체 삭제 명령어

MySQL

객체 종류문법 예시설명
TABLEDROP TABLE users;테이블 삭제
IF EXISTSDROP TABLE IF EXISTS users;존재할 때만 삭제
VIEWDROP VIEW active_users;뷰 삭제
INDEXDROP INDEX idx_name ON users;인덱스 삭제 (테이블 이름 필요)
TRIGGERDROP TRIGGER trg_users_insert;트리거 삭제
SEQUENCEDROP SEQUENCE user_seq;시퀀스 삭제 (MySQL 8.0 이상)
DATABASEDROP DATABASE shopdb;데이터베이스 전체 삭제
USERDROP USER 'user'@'localhost';사용자 삭제

Oracle

객체 종류문법 예시설명
TABLEDROP TABLE users;테이블 삭제
PURGE 옵션DROP TABLE users PURGE;휴지통(RECYCLEBIN) 건너뛰고 완전 삭제
VIEWDROP VIEW active_users;뷰 삭제
INDEXDROP INDEX idx_name;인덱스 삭제
TRIGGERDROP TRIGGER trg_users_insert;트리거 삭제
SEQUENCEDROP SEQUENCE user_seq;시퀀스 삭제
USERDROP USER shop_user CASCADE;사용자 및 그 소유 객체 모두 삭제
SYNONYMDROP SYNONYM syn_name;시노님 삭제
TYPEDROP TYPE object_type_name;사용자 정의 타입 삭제

TRUNCATE

테이블 데이터 전체 삭제 명령어
* MySQL, Oracle 동일

TRUNCATE TABLE table_name;

RENAME

객체 이름 변경 명령어

MySQL

RENAME TABLE users TO customers;
ALTER TABLE users RENAME COLUMN email TO email_address;
대상문법 예시설명
테이블RENAME TABLE old_name TO new_name;테이블 이름 변경
여러 테이블RENAME TABLE a TO b, c TO d;여러 개 테이블 이름 한번에 변경 가능
컬럼ALTER TABLE tbl RENAME COLUMN old TO new;컬럼 이름 변경 (MySQL 8.0 이상)
데이터베이스❌ 직접 RENAME 불가 (백업 후 생성 필요)
RENAME TABLE view_name TO new_view;뷰도 테이블처럼 이름 변경 가능

Oracle

RENAME users TO customers;
ALTER TABLE users RENAME COLUMN email TO email_address;
대상문법 예시설명
테이블RENAME old_name TO new_name;테이블 이름 변경
컬럼ALTER TABLE tbl RENAME COLUMN old TO new;컬럼 이름 변경 (12c 이상 지원)
시노님(SYNONYM)RENAME old_syn TO new_syn;시노님 이름 변경
인덱스❌ 직접 RENAME 불가 (ALTER INDEX ... RENAME TO) 사용
시퀀스❌ 직접 RENAME 불가 (DROP + CREATE 필요)
RENAME view_name TO new_view;뷰 이름 변경

COMMENT

객체 주석 추가 명령어
* MySQL은 CREATE 시에 주석을 추가한다

Oracle

COMMENT ON TABLE users IS '회원 정보를 저장하는 테이블';
COMMENT ON COLUMN users.name IS '사용자 이름';
대상문법 예시설명
테이블COMMENT ON TABLE users IS '유저 테이블';테이블에 주석 달기
컬럼COMMENT ON COLUMN users.email IS '이메일 주소';컬럼에 주석 달기
COMMENT ON TABLE active_users IS '활성 사용자 뷰';뷰도 테이블처럼 작성

DROP vs. TRUNCATE vs. DELETE

항목TRUNCATEDELETEDROP
데이터 삭제만❌ (구조까지 삭제)
테이블 구조 유지
롤백 가능 여부❌ (Oracle: DDL로 취급, 자동 커밋)✅ (트랜잭션 안에서 사용 가능)
WHERE 절 사용 가능
속도🔥 빠름느림 (로그 기록됨)가장 빠름 (전체 제거)
트리거 작동❌ 작동안함✅ 작동❌ (트리거 대상 없음)
제약 조건 검사❌ (제한적 적용)

DML

DML(Data Manipulation Language) : 데이터 조작에 사용하는 언어

SELECT

데이터를 조회할 때 사용하는 명령어

MySQL

-- 모든 컬럼 조회
SELECT * FROM users;

-- 특정 컬럼 조회
SELECT name, email FROM users;

-- 조건으로 필터링
SELECT name, email FROM users WHERE age > 30;

-- 정렬
SELECT * FROM users ORDER BY name DESC;

-- 개수 제한
SELECT * FROM users LIMIT 10;

Oracle

-- 모든 컬럼 조회
SELECT * FROM users;

-- 특정 컬럼 조회
SELECT name, email FROM users;

-- 조건으로 필터링
SELECT name, email FROM users WHERE age > 30;

-- 정렬
SELECT * FROM users ORDER BY name DESC;

-- 개수 제한 (Oracle 12c 이상에서는 `FETCH FIRST` 사용)
SELECT * FROM users FETCH FIRST 10 ROWS ONLY;

MySQL vs. Oracle

항목MySQLOracle
결과 개수 제한LIMIT 사용ROWNUM, FETCH FIRST 사용
조인JOIN 지원 (INNER, LEFT, RIGHT 등)JOIN 지원 (INNER, LEFT, RIGHT 등)
정렬ORDER BYORDER BY
집합 함수COUNT(), AVG(), MAX(), MIN(), SUM()동일
문자열 연산CONCAT() 함수 사용|| 연산자 또는 CONCAT() 함수 사용
GROUP BY + HAVING동일동일

INSERT

데이터를 테이블에 추가할 때 사용하는 명령어

MySQL

INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);

-- 다중 행 INSERT
INSERT INTO users (name, email) 
VALUES 
('Charlie', 'charlie@example.com'),
('David', 'david@example.com'),
('Eve', 'eve@example.com');

-- UPSERT : 없으면 INSERT 있으면 UPDATE
INSERT INTO users (id, name, email) 
VALUES (1, 'Alice', 'alice@example.com')
ON DUPLICATE KEY UPDATE name = 'Updated Name';

-- 오류 발생 시 무시하고 진행
INSERT IGNORE INTO users (id, name, email) 
VALUES (1, 'Alice', 'alice@example.com');

Oracle

INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);

-- 다중 행 INSERT
INSERT ALL
  INTO users (name, email) VALUES ('Charlie', 'charlie@example.com')
  INTO users (name, email) VALUES ('David', 'david@example.com')
  INTO users (name, email) VALUES ('Eve', 'eve@example.com')
SELECT * FROM dual;

-- UPSERT
MERGE INTO users u
USING (SELECT 1 AS id, 'Alice' AS name, 'alice@example.com' AS email FROM dual) src
ON (u.id = src.id)
WHEN MATCHED THEN
  UPDATE SET u.name = src.name, u.email = src.email
WHEN NOT MATCHED THEN
  INSERT (id, name, email) VALUES (src.id, src.name, src.email);
  
-- 자동 증가 컬럼 처리
INSERT INTO users (id, name, email)
VALUES (user_seq.NEXTVAL, 'Frank', 'frank@example.com');

MySQL, Oracle 둘 다 다른 테이블 데이터를 조회하여 삽입할 수 있다

INSERT INTO users (name, email)
SELECT name, email FROM new_users WHERE active = 1;

UPDATE

기존 데이터를 수정할 때 사용하는 명령어

UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;

MySQL vs. Oracle

항목MySQLOracle
기본 UPDATE 문법UPDATE ... SET ... WHERE ...동일
JOIN을 활용한 업데이트UPDATE ... JOIN ... 가능MERGE INTO 또는 UPDATE + EXISTS 활용 필요
다중 테이블 업데이트UPDATE t1, t2 SET ... WHERE ... 가능불가능 (단일 테이블만 가능)
서브쿼리 활용 가능 여부가능가능
UPSERT 지원ON DUPLICATE KEY UPDATEMERGE INTO 사용

DELETE

데이터를 삭제할 때 사용하는 명령어

DELETE FROM table_name
WHERE condition;

MySQL vs. Oracle

항목MySQLOracle
기본 문법DELETE FROM table WHERE ...동일
조건 없는 전체 삭제가능 (DELETE FROM table)가능 (DELETE FROM table)
JOIN 기반 삭제DELETE FROM t1 USING ... JOIN ...EXISTS, IN 사용
다중 테이블 삭제가능 (DELETE t1, t2 FROM ...)불가능 (한 번에 하나만)
트랜잭션 처리지원 (START TRANSACTION, ROLLBACK)지원 (BEGIN, SAVEPOINT, ROLLBACK)

DCL

DCL(Data Control Language) : 데이터베이스 접근 권한 제어에 사용하는 언어

GRANT

사용자에게 권한을 부여할 때 사용하는 명령어

MySQL

GRANT privileges
ON database_name.table_name
TO 'username'@'host'
[WITH GRANT OPTION];

Oracle

GRANT privileges
TO username
[WITH GRANT OPTION];

Mysql vs. Oracle

항목MySQLOracle
기본 문법GRANT ... ON db.table TO 'user'@'host'GRANT ... TO username
대상 지정 방식'user'@'host'username (DB 계정)
시스템 권한일부 가능 (GRANT ALL PRIVILEGES, etc.)명시적 (CREATE SESSION, CREATE TABLE, etc.)
객체 권한테이블, DB, 뷰, 프로시저 등에 권한 부여 가능테이블, 뷰, 시퀀스 등 개별 객체에 권한 부여
권한 위임 (전가)WITH GRANT OPTIONWITH GRANT OPTION
역할(Role) 사용MySQL 8.0 이상에서 지원역할(Role) 시스템 내장됨 (CONNECT, RESOURCE, 등)
권한 확인 방법SHOW GRANTS FOR 'user'@'host'USER_TAB_PRIVS, ALL_TAB_PRIVS, DBA_TAB_PRIVS 등 조회

REVOKE

사용자에게 권한을 회수할 때 사용하는 명령어

MySQL

REVOKE privileges
ON database_name.table_name
FROM 'username'@'host';

Oracle

REVOKE privileges
ON object_name
FROM username;

MySQL vs. Oracle

항목MySQLOracle
기본 문법REVOKE ... ON db.table FROM 'user'@'host'REVOKE ... ON object FROM user
시스템 권한 회수REVOKE ALL PRIVILEGES 포함REVOKE CREATE SESSION, CREATE TABLE
객체 권한 회수테이블, 뷰, 프로시저 등테이블, 뷰, 시퀀스 등
역할(Role) 회수REVOKE 'role' FROM 'user'@'host' (8.0 이상)REVOKE role FROM user
권한 위임 제거REVOKE GRANT OPTION FOR ... 가능 (제한적)REVOKE ... WITH GRANT OPTION도 제거됨

TCL

TCL(Transaction Control Language) : 트랜잭션을 제어할 때 사용하는 언어. DCL로 분류되기도 한다

항목MySQLOracle
트랜잭션 시작START TRANSACTION, BEGIN 필요DML 수행 시 자동 시작
COMMIT변경 사항 영구 반영동일
ROLLBACK변경 사항 모두 취소동일
SAVEPOINT중간 지점 설정 가능동일
ROLLBACK TO SAVEPOINT저장점까지 부분 롤백동일
자동 커밋기본적으로 비활성화 (autocommit=0 설정 시)대부분의 클라이언트에서 자동커밋 OFF
격리 수준 설정SET TRANSACTION ISOLATION LEVEL ...동일

0개의 댓글