MySQL

CREATE TABLE

powergirl 2025. 8. 26. 10:28
기본 문법
CREATE TABLE users (
    id INT,
    name VARCHAR(50),
    age INT
);
users 라는 테이블을 생성합니다.
테이블 내에는 id, name, age 의 정보가 들어갑니다.
id 는 정수형(INT)
name 은 문자열(최대 50글자)
age 는 정수형(INT)

 

자료형 의미
INT 정수
(-2,147,483,648 ~ 2,147,483,647)
123
TINYINT 아주 작은 정수
(-128 ~ 127)
1
(주로 boolean 대용)
BIGINT 큰 정수
(-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807)
9999999999
UNSIGNED 음수 금지
(0 이상만 저장 가능)
UNSIGNED INT
0 ~ 4,294,967,295
VARCHAR(n) 가변 길이 문자열 (최대 n자) 'power'
CHAR(n) 고정 길이 문자열
(n자 고정, 부족하면 공백으로 채움)
'A'
(CHAR(1))
TEXT 긴 문자열
(최대 65,535자)
'긴 설명입니다...'
DATE 날짜
(YYYY-MM-DD)
'2025-07-11'
TIME 시간
(HH:MM:SS)
'13:45:00'
DATETIME 날짜 + 시간
(YYYY-MM-DD HH:MM:SS)
'2025-07-11 18:00:00'
TIMESTAMP 날짜 + 시간
(UTC 기준, 자동 기록/갱신 가능)
'2025-07-11 18:00:00'
YEAR 연도
(YYYY)
'2025'
FLOAT, DOUBLE 실수
(소수점 숫자, DOUBLE은 더 정밀)
3.14
BOOLEAN(= TINYINT(1)) 참/거짓 (0 = 거짓, 1 = 참) TRUE, FALSE
ENUM 제한된 값만 허용
(목록 중 선택)
'남자', '여자'
JSON 구조화된 데이터
(키-값 형태)
'{"name":"홍길동","age":25}'

 

 

 

 

기본 제약조건 (Constraints)
CREATE TABLE users (
    id INT PRIMARY KEY,       -- 고유 식별자
    name VARCHAR(50) NOT NULL,-- 반드시 입력해야 함
    age INT DEFAULT 0         -- 값이 없으면 기본값 0
);
id 는 회원 번호처럼 절대 겹치면 안 되는 값
name 은 꼭 필요함. NULL 은 안됨
age 는 입력 안 하면 0으로 입력됨.

 

제약조건 의미
PRIMARY KEY 기본 키(유일값 + NULL 불가)
NOT NULL 빈 값 금지
DEFAULT 값이 없으면 기본값 자동 입력
UNIQUE 중복 불가
CHECK 조건 만족 강제
FOREIGN KEY 참조 무결성

 

 

 

 

AUTO_INCREMENT

등록된 순번으로 1, 2, 3..... 자동으로 증가해야 하는 경우가 있다.

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    age INT DEFAULT 0
);
id 는 새로운 데이터가 들어올 때마다 자동으로 +1 이 된다.

 

 

 

 

외래 키 (Foreign Key)

회원이 공연 티켓을 구매할 때,

회원 테이블(users) 과 구매 테이블(ticket) 을 연결해야 한다.

 

CREATE TABLE tickets (
    ticket_id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT,
    show_name VARCHAR(100),
    FOREIGN KEY (user_id) REFERENCES users(id)
);

 

user_id 는 users 테이블의 id 를 참조한다. (곧, user_id == users.id)
즉, users 에 있는 회원만이 티켓을 살 수 있음

 

 

 


+ 심화

 

CREATE TABLE [IF NOT EXISTS] 스키마명.테이블명 (
    컬럼명 데이터타입 [NULL|NOT NULL] [DEFAULT 값] [AUTO_INCREMENT]
  , ...
  , [CONSTRAINT 제약이름] PRIMARY KEY (컬럼[, ...])
  , [CONSTRAINT 제약이름] UNIQUE KEY (컬럼[, ...])
  , [CONSTRAINT 제약이름] FOREIGN KEY (컬럼[, ...])
        REFERENCES 참조테이블(컬럼[, ...])
        [ON UPDATE {RESTRICT|CASCADE|SET NULL|NO ACTION}]
        [ON DELETE {RESTRICT|CASCADE|SET NULL|NO ACTION}]
  , [INDEX/KEY 인덱스이름 (컬럼[, ...])]
)
ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
[COLLATE=utf8mb4_general_ci]
[COMMENT='테이블 설명'];

 

IF NOT EXISTS : 같은 이름의 테이블이 이미 있으면 통과
ENGINE=InnnoDB : 트랜잭션 / 외래키 지원. 
CHARSET / COLLATE : 한글 / 이모지까지 안전한 utf9mb4 권장.
COMMENT : 스키마를 문서화 (팀 협업 필수)

 

 

 

 

인덱스 기본기

필요할 때만 만든다 (과도하면 쓰기 성능 / 공간 낭비)

PK / UNIQUE 는 자동 인덱스 생성
INDEX (col1, col2) 복합 인덱스 : 선두 컬럼 기준으로만 잘 탄다.
FULLTEXT : 자연어 검색 (name, details 등)
Prefix Index : 긴 문자열 앞부분만 인덱싱

 

 

 

 

외래키 와 참조 무결성

이력 보존이 중요하면 삭제 대신 소프트 삭제 (deleted_at) 권장

REFERENCES 로 부모/자식 테이블 연결
ON DELETE / ON UPDATE 정책 :

RESTRICT / NO ACTION:차단 (사실상 동일)
CASCADE : 부모 변경 / 삭제를 자식에 전파
SET NULL : 부모 삭제 시 자식을 NULL 로

 

 

 

 

테이블 옵션
ENGINE=InnoDB : 기본
DEFAULT CHARSET=utf8mb4, COLLATE=utf8mb4_general_ci
ROW_FORMAT, TABLESPACE 등은 특수한 경우에만

 

 

 

 

자주 쓰는 변형 문법
임시 테이블
CREATE TEMPORARY TABLE temp_result (...);

 

다른 테이블과 동일한 구조
CREATE TABLE new_like_old LIKE old;

 

조회 결과로 테이블 만들기
CREATE TABLE copy AS
SELECT * FROM original WHERE created_at >= CURDATE();

 

 

 

 

심화 기능 모음
생성(가상) 컬럼
age INT
    GENERATED ALWAYS AS (YEAR(CURDATE()) - CAST(birthyear AS UNSIGNED))
    VIRTUAL;

 

CHECK 제약
price INT UNSIGNED NOT NULL,
CHECK (price > 0);

 

JSON 컬럼과 검증
extra JSON NOT NULL,
CHECK (JSON_VALID(extra));

 

FULLTEXT (한국어면 ngram 파서 고려)
FULLTEXT KEY ft_perf (name, details) WITH PARSER ngram;

 

파티셔닝(대용량)
PARTITION BY RANGE (YEAR(created_at)) (
  PARTITION p2024 VALUES LESS THAN (2025),
  PARTITION p2025 VALUES LESS THAN (2026),
  PARTITION pmax  VALUES LESS THAN MAXVALUE
);

 

Invisible Column (8.0.13+)
internal_note VARCHAR(255) INVISIBLE

 

 

 

 

예제
더보기
-- =========================================
-- 회원 테이블
-- =========================================
CREATE TABLE users (
    num INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '등록 순번',
    user_id VARCHAR(50) NOT NULL COMMENT '유저 아이디',
    password VARCHAR(255) NOT NULL COMMENT '비밀번호(해시 저장)',
    name VARCHAR(50) NOT NULL COMMENT '이름',
    birthyear YEAR NOT NULL COMMENT '출생년',
    gender ENUM('M', 'F', 'O') NOT NULL COMMENT '성별(M: 남, F: 여, O: 기타)',
    email VARCHAR(100) DEFAULT NULL COMMENT '이메일',
    phone VARCHAR(20) DEFAULT NULL COMMENT '연락처',
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '계정 생성 시간',
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '마지막 수정 시간',
    PRIMARY KEY (user_id),
    UNIQUE KEY uq_user_num (num),
    UNIQUE KEY uq_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='유저 정보 테이블';

-- =========================================
-- 관리자 테이블
-- =========================================
CREATE TABLE admins (
    num INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '등록 순번',
    admin_id VARCHAR(50) NOT NULL COMMENT '관리자 아이디',
    password VARCHAR(255) NOT NULL COMMENT '비밀번호(해시 저장)',
    role_level TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '권한 등급(1: 일반, 9: 최고관리자)',
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '계정 생성 시간',
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '마지막 수정 시간',
    PRIMARY KEY (admin_id),
    UNIQUE KEY uq_admin_num (num)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='관리자 정보 테이블';

-- =========================================
-- 공연 정보 테이블
-- =========================================
CREATE TABLE performances (
    performance_id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '공연 ID',
    category ENUM('콘서트', '뮤지컬', '연극', '클래식', '무용', '전시', '행사') NOT NULL COMMENT '공연 분류',
    name VARCHAR(100) NOT NULL COMMENT '공연 이름',
    event_datetime DATETIME NOT NULL COMMENT '공연 일시',
    location VARCHAR(255) NOT NULL COMMENT '공연 장소',
    total_seats INT UNSIGNED NOT NULL COMMENT '총 좌석 수',
    price INT UNSIGNED NOT NULL COMMENT '티켓 가격(원화 단위)',
    rating ENUM('전체관람가', '7세 이상', '12세 이상', '15세 이상', '18세 이상') NOT NULL COMMENT '관람 등급',
    details TEXT DEFAULT NULL COMMENT '상세 정보',
    image_url VARCHAR(255) DEFAULT NULL COMMENT '공연 사진 URL',
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '등록일',
    created_by VARCHAR(50) NOT NULL COMMENT '등록자(관리자 ID)',
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '마지막 수정일',
    PRIMARY KEY (performance_id),
    FOREIGN KEY (created_by) REFERENCES admins(admin_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='공연 정보 테이블';

-- =========================================
-- 티켓 구매 테이블
-- =========================================
CREATE TABLE ticket_purchases (
    ticket_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '티켓 ID',
    user_id VARCHAR(50) NOT NULL COMMENT '구매자 ID(회원 테이블 FK)',
    user_name VARCHAR(50) NOT NULL COMMENT '구매자 이름',
    birthyear YEAR NOT NULL COMMENT '구매자 출생년도',
    gender ENUM('M', 'F', 'O') NOT NULL COMMENT '구매자 성별(스냅샷)',
    image_url VARCHAR(255) DEFAULT NULL COMMENT '유저 사진 URL',
    performance_id INT UNSIGNED NOT NULL COMMENT '공연 ID(공연 정보 FK)',
    performance_name VARCHAR(100) NOT NULL COMMENT '공연 이름',
    event_datetime DATETIME NOT NULL COMMENT '공연 일시',
    location VARCHAR(255) NOT NULL COMMENT '공연 장소',
    seat_number VARCHAR(10) DEFAULT NULL COMMENT '좌석 번호',
    qr_code VARCHAR(255) NOT NULL COMMENT 'QR 코드 URL',
    status ENUM('구매완료', '취소', '환불완료', '사용완료') NOT NULL DEFAULT '구매완료' COMMENT '티켓 상태',
    cancelled_at DATETIME DEFAULT NULL COMMENT '취소/환불 일시',
    cancel_reason VARCHAR(255) DEFAULT NULL COMMENT '취소/환불 사유',
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '구매일시',
    PRIMARY KEY (ticket_id),
    FOREIGN KEY (user_id) REFERENCES users(user_id),
    FOREIGN KEY (performance_id) REFERENCES performances(performance_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='티켓 구매 테이블';


-- =========================================
-- 티켓 검증 테이블
-- =========================================
CREATE TABLE ticket_validations (
    validation_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '검증 ID',
    admin_id VARCHAR(50) NOT NULL COMMENT '검증한 관리자 ID(관리자 테이블 FK)',
    user_id VARCHAR(50) NOT NULL COMMENT '구매자 ID(회원 테이블 FK)',
    performance_id INT UNSIGNED NOT NULL COMMENT '공연 ID(공연 테이블 FK)',
    ticket_id BIGINT UNSIGNED NOT NULL COMMENT '티켓 ID(티켓 구매 테이블 FK)',
    status ENUM('승인', '거부') NOT NULL COMMENT '검증 결과',
    reason VARCHAR(255) DEFAULT NULL COMMENT '거부 사유(선택)',
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '검증 일시',
    PRIMARY KEY (validation_id),
    FOREIGN KEY (user_id) REFERENCES users(user_id),
    FOREIGN KEY (admin_id) REFERENCES admins(admin_id),
    FOREIGN KEY (performance_id) REFERENCES performances(performance_id),
    FOREIGN KEY (ticket_id) REFERENCES ticket_purchases(ticket_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='티켓 검증 테이블';

 

 

'MySQL' 카테고리의 다른 글

MySQL - JOIN  (1) 2025.08.25
SELECT 문  (5) 2025.08.25
MySQL C API 주요 함수  (1) 2025.07.10