|
| 1 | +/* ========================================================= |
| 2 | + * V1: 전체 스키마 초기화 |
| 3 | + * - 시퀀스, 기본 테이블, FK, 인덱스 전부 포함 |
| 4 | + * ========================================================= */ |
| 5 | + |
| 6 | +/* =========================================== |
| 7 | + * 1. SEQUENCES |
| 8 | + * =========================================== */ |
| 9 | +CREATE SEQUENCE IF NOT EXISTS store_seq START WITH 1 INCREMENT BY 1; |
| 10 | +CREATE SEQUENCE IF NOT EXISTS user_seq START WITH 1 INCREMENT BY 100; |
| 11 | +CREATE SEQUENCE IF NOT EXISTS seat_seq START WITH 1 INCREMENT BY 100; |
| 12 | +CREATE SEQUENCE IF NOT EXISTS ticket_seq START WITH 1 INCREMENT BY 100; |
| 13 | +CREATE SEQUENCE IF NOT EXISTS pre_register_seq START WITH 1 INCREMENT BY 100; |
| 14 | +CREATE SEQUENCE IF NOT EXISTS queue_entry_seq START WITH 1 INCREMENT BY 100; |
| 15 | + |
| 16 | +/* =========================================== |
| 17 | + * 2. stores |
| 18 | + * =========================================== */ |
| 19 | +CREATE TABLE IF NOT EXISTS stores ( |
| 20 | + id BIGINT PRIMARY KEY DEFAULT nextval('store_seq'), |
| 21 | + name VARCHAR(30) NOT NULL, |
| 22 | + registration_number VARCHAR(16) NOT NULL, |
| 23 | + address VARCHAR(255) NOT NULL, |
| 24 | + deleted_at TIMESTAMP, |
| 25 | + created_at TIMESTAMP, |
| 26 | + modified_at TIMESTAMP |
| 27 | +); |
| 28 | + |
| 29 | +/* =========================================== |
| 30 | + * 3. users |
| 31 | + * =========================================== */ |
| 32 | +CREATE TABLE IF NOT EXISTS users ( |
| 33 | + id BIGINT PRIMARY KEY DEFAULT nextval('user_seq'), |
| 34 | + email VARCHAR(100), |
| 35 | + full_name VARCHAR(30) NOT NULL, |
| 36 | + nickname VARCHAR(20) NOT NULL UNIQUE, |
| 37 | + password VARCHAR(255) NOT NULL, |
| 38 | + birth_date DATE, |
| 39 | + role VARCHAR(20) NOT NULL, |
| 40 | + deleted_status VARCHAR(20) NOT NULL, |
| 41 | + deleted_at TIMESTAMP, |
| 42 | + provider_type VARCHAR(20), |
| 43 | + provider_id VARCHAR(255), |
| 44 | + store_id BIGINT, |
| 45 | + created_at TIMESTAMP, |
| 46 | + modified_at TIMESTAMP |
| 47 | +); |
| 48 | + |
| 49 | +/* =========================================== |
| 50 | + * 4. events |
| 51 | + * =========================================== */ |
| 52 | +CREATE TABLE IF NOT EXISTS events ( |
| 53 | + id BIGSERIAL PRIMARY KEY, |
| 54 | + title VARCHAR(255) NOT NULL, |
| 55 | + category VARCHAR(50) NOT NULL, |
| 56 | + description TEXT, |
| 57 | + place VARCHAR(255) NOT NULL, |
| 58 | + image_url VARCHAR(500), |
| 59 | + min_price INTEGER NOT NULL, |
| 60 | + max_price INTEGER NOT NULL, |
| 61 | + pre_open_at TIMESTAMP NOT NULL, |
| 62 | + pre_close_at TIMESTAMP NOT NULL, |
| 63 | + ticket_open_at TIMESTAMP NOT NULL, |
| 64 | + ticket_close_at TIMESTAMP NOT NULL, |
| 65 | + event_date TIMESTAMP NOT NULL, |
| 66 | + max_ticket_amount INTEGER NOT NULL, |
| 67 | + status VARCHAR(20) NOT NULL, |
| 68 | + deleted BOOLEAN NOT NULL DEFAULT false, |
| 69 | + store_id BIGINT NOT NULL, |
| 70 | + created_at TIMESTAMP, |
| 71 | + modified_at TIMESTAMP |
| 72 | +); |
| 73 | + |
| 74 | +/* =========================================== |
| 75 | + * 5. seats |
| 76 | + * =========================================== */ |
| 77 | +CREATE TABLE IF NOT EXISTS seats ( |
| 78 | + id BIGINT PRIMARY KEY DEFAULT nextval('seat_seq'), |
| 79 | + event_id BIGINT NOT NULL, |
| 80 | + seat_code VARCHAR(20) NOT NULL, |
| 81 | + grade VARCHAR(20) NOT NULL, |
| 82 | + price INTEGER NOT NULL, |
| 83 | + seat_status VARCHAR(20) NOT NULL, |
| 84 | + version INTEGER DEFAULT 0, |
| 85 | + created_at TIMESTAMP, |
| 86 | + modified_at TIMESTAMP |
| 87 | +); |
| 88 | + |
| 89 | +/* =========================================== |
| 90 | + * 6. tickets |
| 91 | + * =========================================== */ |
| 92 | +CREATE TABLE IF NOT EXISTS tickets ( |
| 93 | + id BIGINT PRIMARY KEY DEFAULT nextval('ticket_seq'), |
| 94 | + owner_user_id BIGINT NOT NULL, |
| 95 | + seat_id BIGINT, |
| 96 | + event_id BIGINT NOT NULL, |
| 97 | + ticket_status VARCHAR(20) NOT NULL, |
| 98 | + issued_at TIMESTAMP, |
| 99 | + used_at TIMESTAMP, |
| 100 | + transferred BOOLEAN NOT NULL DEFAULT false, |
| 101 | + created_at TIMESTAMP, |
| 102 | + modified_at TIMESTAMP |
| 103 | +); |
| 104 | + |
| 105 | +/* =========================================== |
| 106 | + * 7. ticket_transfer_history |
| 107 | + * =========================================== */ |
| 108 | +CREATE TABLE IF NOT EXISTS ticket_transfer_history ( |
| 109 | + id BIGSERIAL PRIMARY KEY, |
| 110 | + ticket_id BIGINT NOT NULL, |
| 111 | + from_user_id BIGINT NOT NULL, |
| 112 | + to_user_id BIGINT NOT NULL, |
| 113 | + transferred_at TIMESTAMP NOT NULL, |
| 114 | + created_at TIMESTAMP, |
| 115 | + modified_at TIMESTAMP |
| 116 | +); |
| 117 | + |
| 118 | +/* =========================================== |
| 119 | + * 8. orders (legacy Order entity) |
| 120 | + * =========================================== */ |
| 121 | +CREATE TABLE IF NOT EXISTS orders ( |
| 122 | + id BIGSERIAL PRIMARY KEY, |
| 123 | + ticket_id BIGINT NOT NULL, |
| 124 | + amount BIGINT, |
| 125 | + status VARCHAR(20), |
| 126 | + payment_key VARCHAR(255), |
| 127 | + order_key VARCHAR(255), |
| 128 | + order_number VARCHAR(50), |
| 129 | + paid_at TIMESTAMP, |
| 130 | + created_at TIMESTAMP, |
| 131 | + modified_at TIMESTAMP |
| 132 | +); |
| 133 | + |
| 134 | +/* =========================================== |
| 135 | + * 9. payments |
| 136 | + * =========================================== */ |
| 137 | +CREATE TABLE IF NOT EXISTS payments ( |
| 138 | + payment_id BIGSERIAL PRIMARY KEY, |
| 139 | + payment_key VARCHAR(255) NOT NULL, |
| 140 | + order_id VARCHAR(255) NOT NULL, |
| 141 | + amount BIGINT NOT NULL, |
| 142 | + method VARCHAR(50) NOT NULL, |
| 143 | + status VARCHAR(20) NOT NULL, |
| 144 | + created_at TIMESTAMP, |
| 145 | + modified_at TIMESTAMP |
| 146 | +); |
| 147 | + |
| 148 | +/* =========================================== |
| 149 | + * 10. v2_orders |
| 150 | + * =========================================== */ |
| 151 | +CREATE TABLE IF NOT EXISTS v2_orders ( |
| 152 | + v2_order_id VARCHAR(36) PRIMARY KEY, |
| 153 | + ticket_id BIGINT NOT NULL, |
| 154 | + amount BIGINT NOT NULL, |
| 155 | + status VARCHAR(20) NOT NULL DEFAULT 'PENDING', |
| 156 | + payment_key VARCHAR(255), |
| 157 | + payment_id BIGINT, |
| 158 | + created_at TIMESTAMP, |
| 159 | + modified_at TIMESTAMP |
| 160 | +); |
| 161 | + |
| 162 | +/* =========================================== |
| 163 | + * 11. pre_registers |
| 164 | + * =========================================== */ |
| 165 | +CREATE TABLE IF NOT EXISTS pre_registers ( |
| 166 | + id BIGINT PRIMARY KEY DEFAULT nextval('pre_register_seq'), |
| 167 | + pre_register_status VARCHAR(20) NOT NULL, |
| 168 | + event_id BIGINT NOT NULL, |
| 169 | + user_id BIGINT NOT NULL, |
| 170 | + pre_register_agree_terms BOOLEAN NOT NULL, |
| 171 | + pre_register_agree_privacy BOOLEAN NOT NULL, |
| 172 | + pre_register_agreed_at TIMESTAMP NOT NULL, |
| 173 | + created_at TIMESTAMP, |
| 174 | + modified_at TIMESTAMP |
| 175 | +); |
| 176 | + |
| 177 | +/* =========================================== |
| 178 | + * 12. queue_entries |
| 179 | + * =========================================== */ |
| 180 | +CREATE TABLE IF NOT EXISTS queue_entries ( |
| 181 | + id BIGINT PRIMARY KEY DEFAULT nextval('queue_entry_seq'), |
| 182 | + queue_rank INTEGER NOT NULL, |
| 183 | + queue_entry_status VARCHAR(20) NOT NULL, |
| 184 | + entered_at TIMESTAMP, |
| 185 | + expired_at TIMESTAMP, |
| 186 | + user_id BIGINT NOT NULL, |
| 187 | + event_id BIGINT NOT NULL, |
| 188 | + created_at TIMESTAMP, |
| 189 | + modified_at TIMESTAMP |
| 190 | +); |
| 191 | + |
| 192 | +/* =========================================== |
| 193 | + * 13. refresh_tokens |
| 194 | + * =========================================== */ |
| 195 | +CREATE TABLE IF NOT EXISTS refresh_tokens ( |
| 196 | + id BIGSERIAL PRIMARY KEY, |
| 197 | + user_id BIGINT NOT NULL, |
| 198 | + token VARCHAR(512) NOT NULL, |
| 199 | + jti VARCHAR(36), |
| 200 | + issued_at TIMESTAMP, |
| 201 | + expires_at TIMESTAMP, |
| 202 | + session_id VARCHAR(36), |
| 203 | + token_version BIGINT, |
| 204 | + revoked BOOLEAN DEFAULT false, |
| 205 | + user_agent VARCHAR(500), |
| 206 | + ip_address VARCHAR(50), |
| 207 | + created_at TIMESTAMP, |
| 208 | + modified_at TIMESTAMP |
| 209 | +); |
| 210 | + |
| 211 | +/* =========================================== |
| 212 | + * 14. active_sessions |
| 213 | + * =========================================== */ |
| 214 | +CREATE TABLE IF NOT EXISTS active_sessions ( |
| 215 | + id BIGSERIAL PRIMARY KEY, |
| 216 | + user_id BIGINT NOT NULL, |
| 217 | + session_id VARCHAR(36) NOT NULL, |
| 218 | + token_version BIGINT NOT NULL, |
| 219 | + last_login_at TIMESTAMP NOT NULL, |
| 220 | + created_at TIMESTAMP, |
| 221 | + modified_at TIMESTAMP |
| 222 | +); |
| 223 | + |
| 224 | +/* =========================================== |
| 225 | + * 15. notifications |
| 226 | + * =========================================== */ |
| 227 | +CREATE TABLE IF NOT EXISTS notifications ( |
| 228 | + id BIGSERIAL PRIMARY KEY, |
| 229 | + type VARCHAR(50) NOT NULL, |
| 230 | + type_detail VARCHAR(50) NOT NULL, |
| 231 | + title VARCHAR(255) NOT NULL, |
| 232 | + message TEXT NOT NULL, |
| 233 | + is_read BOOLEAN NOT NULL DEFAULT false, |
| 234 | + read_at TIMESTAMP, |
| 235 | + domain_name VARCHAR(50) NOT NULL, |
| 236 | + domain_id BIGINT, |
| 237 | + user_id BIGINT NOT NULL, |
| 238 | + created_at TIMESTAMP, |
| 239 | + modified_at TIMESTAMP |
| 240 | +); |
| 241 | + |
| 242 | +/* =========================================== |
| 243 | + * 16. FOREIGN KEYS |
| 244 | + * =========================================== */ |
| 245 | + |
| 246 | +-- users -> stores |
| 247 | +ALTER TABLE users |
| 248 | + ADD CONSTRAINT fk_user_store |
| 249 | + FOREIGN KEY (store_id) REFERENCES stores(id); |
| 250 | + |
| 251 | +-- events -> stores |
| 252 | +ALTER TABLE events |
| 253 | + ADD CONSTRAINT fk_events_store |
| 254 | + FOREIGN KEY (store_id) REFERENCES stores(id); |
| 255 | + |
| 256 | +-- seats -> events |
| 257 | +ALTER TABLE seats |
| 258 | + ADD CONSTRAINT fk_seat_event |
| 259 | + FOREIGN KEY (event_id) REFERENCES events(id); |
| 260 | + |
| 261 | +-- tickets -> users, seats, events |
| 262 | +ALTER TABLE tickets |
| 263 | + ADD CONSTRAINT fk_ticket_owner |
| 264 | + FOREIGN KEY (owner_user_id) REFERENCES users(id); |
| 265 | + |
| 266 | +ALTER TABLE tickets |
| 267 | + ADD CONSTRAINT fk_ticket_seat |
| 268 | + FOREIGN KEY (seat_id) REFERENCES seats(id); |
| 269 | + |
| 270 | +ALTER TABLE tickets |
| 271 | + ADD CONSTRAINT fk_ticket_event |
| 272 | + FOREIGN KEY (event_id) REFERENCES events(id); |
| 273 | + |
| 274 | +-- orders -> tickets |
| 275 | +ALTER TABLE orders |
| 276 | + ADD CONSTRAINT fk_order_ticket |
| 277 | + FOREIGN KEY (ticket_id) REFERENCES tickets(id); |
| 278 | + |
| 279 | +-- v2_orders -> tickets, payments |
| 280 | +ALTER TABLE v2_orders |
| 281 | + ADD CONSTRAINT fk_v2_order_ticket |
| 282 | + FOREIGN KEY (ticket_id) REFERENCES tickets(id); |
| 283 | + |
| 284 | +ALTER TABLE v2_orders |
| 285 | + ADD CONSTRAINT fk_v2_order_payment |
| 286 | + FOREIGN KEY (payment_id) REFERENCES payments(payment_id); |
| 287 | + |
| 288 | +-- pre_registers -> events, users |
| 289 | +ALTER TABLE pre_registers |
| 290 | + ADD CONSTRAINT fk_pre_register_event |
| 291 | + FOREIGN KEY (event_id) REFERENCES events(id); |
| 292 | + |
| 293 | +ALTER TABLE pre_registers |
| 294 | + ADD CONSTRAINT fk_pre_register_user |
| 295 | + FOREIGN KEY (user_id) REFERENCES users(id); |
| 296 | + |
| 297 | +-- queue_entries -> users, events |
| 298 | +ALTER TABLE queue_entries |
| 299 | + ADD CONSTRAINT fk_queue_entry_user |
| 300 | + FOREIGN KEY (user_id) REFERENCES users(id); |
| 301 | + |
| 302 | +ALTER TABLE queue_entries |
| 303 | + ADD CONSTRAINT fk_queue_entry_event |
| 304 | + FOREIGN KEY (event_id) REFERENCES events(id); |
| 305 | + |
| 306 | +-- refresh_tokens -> users |
| 307 | +ALTER TABLE refresh_tokens |
| 308 | + ADD CONSTRAINT fk_refresh_token_user |
| 309 | + FOREIGN KEY (user_id) REFERENCES users(id); |
| 310 | + |
| 311 | +-- active_sessions -> users |
| 312 | +ALTER TABLE active_sessions |
| 313 | + ADD CONSTRAINT fk_active_session_user |
| 314 | + FOREIGN KEY (user_id) REFERENCES users(id); |
| 315 | + |
| 316 | +-- notifications -> users |
| 317 | +ALTER TABLE notifications |
| 318 | + ADD CONSTRAINT fk_notification_user |
| 319 | + FOREIGN KEY (user_id) REFERENCES users(id); |
| 320 | + |
| 321 | +/* =========================================== |
| 322 | + * 17. UNIQUE CONSTRAINTS |
| 323 | + * =========================================== */ |
| 324 | + |
| 325 | +-- seats: 이벤트별 등급+좌석코드 유니크 |
| 326 | +ALTER TABLE seats |
| 327 | + ADD CONSTRAINT uk_event_grade_seatcode |
| 328 | + UNIQUE (event_id, grade, seat_code); |
| 329 | + |
| 330 | +-- pre_registers: 이벤트+유저 유니크 |
| 331 | +ALTER TABLE pre_registers |
| 332 | + ADD CONSTRAINT uk_pre_register_event_user |
| 333 | + UNIQUE (event_id, user_id); |
| 334 | + |
| 335 | +-- active_sessions: 유저당 하나의 세션 |
| 336 | +ALTER TABLE active_sessions |
| 337 | + ADD CONSTRAINT uk_active_session_user |
| 338 | + UNIQUE (user_id); |
| 339 | + |
| 340 | +/* =========================================== |
| 341 | + * 18. INDEXES |
| 342 | + * =========================================== */ |
| 343 | + |
| 344 | +-- users |
| 345 | +CREATE INDEX IF NOT EXISTS idx_users_store_id ON users(store_id); |
| 346 | + |
| 347 | +-- events |
| 348 | +CREATE INDEX IF NOT EXISTS idx_events_store_id ON events(store_id); |
| 349 | + |
| 350 | +-- seats |
| 351 | +CREATE INDEX IF NOT EXISTS idx_seats_event_id ON seats(event_id); |
| 352 | + |
| 353 | +-- tickets |
| 354 | +CREATE INDEX IF NOT EXISTS idx_tickets_owner ON tickets(owner_user_id); |
| 355 | +CREATE INDEX IF NOT EXISTS idx_tickets_event ON tickets(event_id); |
| 356 | +CREATE INDEX IF NOT EXISTS idx_tickets_seat ON tickets(seat_id); |
| 357 | + |
| 358 | +-- ticket_transfer_history |
| 359 | +CREATE INDEX IF NOT EXISTS idx_transfer_history_ticket_id ON ticket_transfer_history(ticket_id); |
| 360 | + |
| 361 | +-- orders |
| 362 | +CREATE INDEX IF NOT EXISTS idx_orders_ticket_id ON orders(ticket_id); |
| 363 | + |
| 364 | +-- v2_orders |
| 365 | +CREATE INDEX IF NOT EXISTS idx_v2_orders_ticket_id ON v2_orders(ticket_id); |
| 366 | +CREATE INDEX IF NOT EXISTS idx_v2_orders_payment_id ON v2_orders(payment_id); |
| 367 | +CREATE INDEX IF NOT EXISTS idx_v2_orders_payment_key ON v2_orders(payment_key); |
| 368 | + |
| 369 | +-- pre_registers |
| 370 | +CREATE INDEX IF NOT EXISTS idx_pre_registers_event ON pre_registers(event_id); |
| 371 | +CREATE INDEX IF NOT EXISTS idx_pre_registers_user ON pre_registers(user_id); |
| 372 | + |
| 373 | +-- queue_entries |
| 374 | +CREATE INDEX IF NOT EXISTS idx_queue_entries_user ON queue_entries(user_id); |
| 375 | +CREATE INDEX IF NOT EXISTS idx_queue_entries_event ON queue_entries(event_id); |
| 376 | + |
| 377 | +-- refresh_tokens |
| 378 | +CREATE INDEX IF NOT EXISTS idx_refresh_token_token ON refresh_tokens(token); |
| 379 | +CREATE INDEX IF NOT EXISTS idx_refresh_token_user_revoked ON refresh_tokens(user_id, revoked); |
| 380 | +CREATE INDEX IF NOT EXISTS idx_refresh_token_user_expires_at ON refresh_tokens(user_id, expires_at); |
| 381 | + |
| 382 | +-- active_sessions |
| 383 | +CREATE INDEX IF NOT EXISTS idx_active_session_session_id ON active_sessions(session_id); |
| 384 | + |
| 385 | +-- notifications |
| 386 | +CREATE INDEX IF NOT EXISTS idx_notifications_user ON notifications(user_id); |
0 commit comments