kt-event-marketing/design/backend/database/user-service-schema.psql
jhbkjh 3075a5d49f 물리아키텍처 설계 완료
 주요 기능
- Azure 기반 물리아키텍처 설계 (개발환경/운영환경)
- 7개 마이크로서비스 물리 구조 설계
- 네트워크 아키텍처 다이어그램 작성 (Mermaid)
- 환경별 비교 분석 및 마스터 인덱스 문서

📁 생성 파일
- design/backend/physical/physical-architecture.md (마스터)
- design/backend/physical/physical-architecture-dev.md (개발환경)
- design/backend/physical/physical-architecture-prod.md (운영환경)
- design/backend/physical/*.mmd (4개 Mermaid 다이어그램)

🎯 핵심 성과
- 비용 최적화: 개발환경 월 $143, 운영환경 월 $2,860
- 확장성: 개발환경 100명 → 운영환경 10,000명 (100배)
- 가용성: 개발환경 95% → 운영환경 99.9%
- 보안: 다층 보안 아키텍처 (L1~L4)

🛠️ 기술 스택
- Azure Kubernetes Service (AKS)
- Azure Database for PostgreSQL Flexible
- Azure Cache for Redis Premium
- Azure Service Bus Premium
- Application Gateway + WAF

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 15:13:01 +09:00

245 lines
8.1 KiB
Plaintext

-- ============================================
-- User Service Database Schema
-- Database: user_service_db
-- Version: 1.0.0
-- Description: 사용자 및 가게 정보 관리
-- ============================================
-- ============================================
-- 1. 데이터베이스 및 Extension 생성
-- ============================================
-- UUID 확장 활성화
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- ============================================
-- 2. 테이블 생성
-- ============================================
-- 2.1 users 테이블
-- 목적: 사용자(소상공인) 정보 관리
CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(100) NOT NULL,
phone_number VARCHAR(20) NOT NULL,
email VARCHAR(255) NOT NULL,
password_hash VARCHAR(255) NOT NULL,
role VARCHAR(20) NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
last_login_at TIMESTAMP,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- 제약조건
CONSTRAINT uk_users_email UNIQUE (email),
CONSTRAINT uk_users_phone_number UNIQUE (phone_number),
CONSTRAINT ck_users_role CHECK (role IN ('OWNER', 'ADMIN')),
CONSTRAINT ck_users_status CHECK (status IN ('ACTIVE', 'INACTIVE', 'LOCKED', 'WITHDRAWN'))
);
-- users 테이블 코멘트
COMMENT ON TABLE users IS '사용자(소상공인) 정보 테이블';
COMMENT ON COLUMN users.id IS '사용자 고유 식별자 (UUID)';
COMMENT ON COLUMN users.name IS '사용자 이름';
COMMENT ON COLUMN users.phone_number IS '전화번호 (중복 불가)';
COMMENT ON COLUMN users.email IS '이메일 (로그인 ID, 중복 불가)';
COMMENT ON COLUMN users.password_hash IS 'bcrypt 암호화된 비밀번호';
COMMENT ON COLUMN users.role IS '사용자 역할 (OWNER: 소상공인, ADMIN: 관리자)';
COMMENT ON COLUMN users.status IS '계정 상태 (ACTIVE: 활성, INACTIVE: 비활성, LOCKED: 잠김, WITHDRAWN: 탈퇴)';
COMMENT ON COLUMN users.last_login_at IS '최종 로그인 시각';
COMMENT ON COLUMN users.created_at IS '생성 시각';
COMMENT ON COLUMN users.updated_at IS '수정 시각';
-- 2.2 stores 테이블
-- 목적: 가게(매장) 정보 관리
CREATE TABLE IF NOT EXISTS stores (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL,
name VARCHAR(200) NOT NULL,
industry VARCHAR(100) NOT NULL,
address VARCHAR(500) NOT NULL,
business_hours TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- 제약조건
CONSTRAINT uk_stores_user_id UNIQUE (user_id),
CONSTRAINT fk_stores_user_id FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
-- stores 테이블 코멘트
COMMENT ON TABLE stores IS '가게(매장) 정보 테이블';
COMMENT ON COLUMN stores.id IS '가게 고유 식별자 (UUID)';
COMMENT ON COLUMN stores.user_id IS '사용자 ID (FK, 1:1 관계)';
COMMENT ON COLUMN stores.name IS '가게 이름';
COMMENT ON COLUMN stores.industry IS '업종 (예: 음식점, 카페)';
COMMENT ON COLUMN stores.address IS '주소';
COMMENT ON COLUMN stores.business_hours IS '영업시간 정보';
COMMENT ON COLUMN stores.created_at IS '생성 시각';
COMMENT ON COLUMN stores.updated_at IS '수정 시각';
-- ============================================
-- 3. 인덱스 생성
-- ============================================
-- 3.1 users 테이블 인덱스
-- 로그인 조회 최적화
CREATE INDEX IF NOT EXISTS idx_users_email
ON users(email);
-- 전화번호 중복 검증 최적화
CREATE INDEX IF NOT EXISTS idx_users_phone_number
ON users(phone_number);
-- 활성 사용자 필터링 최적화
CREATE INDEX IF NOT EXISTS idx_users_status
ON users(status);
-- 3.2 stores 테이블 인덱스
-- User-Store 조인 최적화
CREATE INDEX IF NOT EXISTS idx_stores_user_id
ON stores(user_id);
-- 인덱스 코멘트
COMMENT ON INDEX idx_users_email IS '로그인 조회 성능 최적화';
COMMENT ON INDEX idx_users_phone_number IS '전화번호 중복 검증 최적화';
COMMENT ON INDEX idx_users_status IS '활성 사용자 필터링 최적화';
COMMENT ON INDEX idx_stores_user_id IS 'User-Store 조인 성능 최적화';
-- ============================================
-- 4. 트리거 생성 (updated_at 자동 갱신)
-- ============================================
-- 4.1 updated_at 갱신 함수 생성
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- 4.2 users 테이블 트리거
CREATE TRIGGER trigger_users_updated_at
BEFORE UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- 4.3 stores 테이블 트리거
CREATE TRIGGER trigger_stores_updated_at
BEFORE UPDATE ON stores
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
-- ============================================
-- 5. 초기 데이터 (Optional)
-- ============================================
-- 5.1 관리자 계정 (Optional - 개발/테스트용)
-- 비밀번호: admin123 (bcrypt 해시)
-- INSERT INTO users (id, name, phone_number, email, password_hash, role, status)
-- VALUES (
-- uuid_generate_v4(),
-- 'System Admin',
-- '010-0000-0000',
-- 'admin@kt-event.com',
-- '$2a$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewY5GyYCdOzHxKuK',
-- 'ADMIN',
-- 'ACTIVE'
-- );
-- ============================================
-- 6. 권한 설정
-- ============================================
-- 애플리케이션 사용자에게 권한 부여 (사용자명은 환경에 맞게 수정)
-- GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO user_service_app;
-- GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO user_service_app;
-- ============================================
-- 7. 통계 정보 갱신
-- ============================================
-- 쿼리 플래너를 위한 통계 정보 수집
ANALYZE users;
ANALYZE stores;
-- ============================================
-- 8. 스키마 버전 정보
-- ============================================
-- 스키마 버전 관리 테이블 (Flyway/Liquibase 사용 시 자동 생성됨)
-- CREATE TABLE IF NOT EXISTS schema_version (
-- installed_rank INT NOT NULL,
-- version VARCHAR(50),
-- description VARCHAR(200) NOT NULL,
-- type VARCHAR(20) NOT NULL,
-- script VARCHAR(1000) NOT NULL,
-- checksum INT,
-- installed_by VARCHAR(100) NOT NULL,
-- installed_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- execution_time INT NOT NULL,
-- success BOOLEAN NOT NULL,
-- PRIMARY KEY (installed_rank)
-- );
-- ============================================
-- 9. 검증 쿼리
-- ============================================
-- 테이블 생성 확인
SELECT
table_name,
table_type
FROM
information_schema.tables
WHERE
table_schema = 'public'
AND table_name IN ('users', 'stores')
ORDER BY
table_name;
-- 인덱스 생성 확인
SELECT
tablename,
indexname,
indexdef
FROM
pg_indexes
WHERE
schemaname = 'public'
AND tablename IN ('users', 'stores')
ORDER BY
tablename, indexname;
-- 제약조건 확인
SELECT
conname AS constraint_name,
contype AS constraint_type,
conrelid::regclass AS table_name
FROM
pg_constraint
WHERE
conrelid IN ('users'::regclass, 'stores'::regclass)
ORDER BY
table_name, constraint_name;
-- ============================================
-- 10. 성능 튜닝 설정 (Optional)
-- ============================================
-- 테이블 통계 수집 비율 조정 (필요 시)
-- ALTER TABLE users SET (autovacuum_vacuum_scale_factor = 0.05);
-- ALTER TABLE stores SET (autovacuum_vacuum_scale_factor = 0.05);
-- 테이블 통계 수집 임계값 조정 (필요 시)
-- ALTER TABLE users SET (autovacuum_analyze_threshold = 50);
-- ALTER TABLE stores SET (autovacuum_analyze_threshold = 50);
-- ============================================
-- END OF SCHEMA
-- ============================================