PostgreSQL, MySQL, SQLite, 및 SQL Server를 지원하는 전문가 수준의 SQL 쿼리 작성, 최적화 및 데이터베이스 스키마 설계입니다. 데이터베이스 작업 시 다음을 위해 사용하세요: (1) JOIN, 서브쿼리, 윈도우 함수를 포함한 복잡한 SQL 쿼리 작성, (2) 느린 쿼리 최적화 및 실행 계획 분석, (3) 올바른 정규화를 적용한 데이터베이스 스키마 설계, (4) 인덱스 생성 및 쿼리 성능 개선, (5) 마이그레이션 작성 및 스키마 변경 처리, (6) SQL 에러 및 쿼리 문제 디버깅
SQL expert for PostgreSQL, MySQL, SQLite, and SQL Server. Use it to write complex queries with JOINs and window functions, optimize slow queries using execution plans, and design normalized database schemas with proper indexes.
/plugin marketplace add icartsh/icartsh_plugin/plugin install icartsh-plugin@icartsh-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
README.mdexamples/complex_queries.sqlexamples/migrations.sqlexamples/schema_examples.sqlreferences/advanced-patterns.mdreferences/best-practices.mdreferences/common-pitfalls.mdreferences/indexes-performance.mdreferences/query-optimization.mdscripts/sql_helper.pyPostgreSQL, MySQL, SQLite 및 SQL Server 전반에 걸친 SQL 데이터베이스의 작성, 최적화 및 관리를 위한 전문가 가이드입니다.
이 SKILL을 통해 다음을 수행할 수 있습니다:
적합한 사례: 복잡한 쿼리, JSON 데이터, 고급 기능, ACID 준수
pip install psycopg2-binary sqlalchemy
적합한 사례: 웹 애플리케이션, WordPress, 읽기 비중이 높은 워크로드
pip install mysql-connector-python sqlalchemy
적합한 사례: 로컬 개발, 임베디드 데이터베이스, 테스트
pip install sqlite3 # Python 내장
적합한 사례: 엔터프라이즈 애플리케이션, Windows 환경
pip install pyodbc sqlalchemy
-- 필터링이 포함된 단순 SELECT
SELECT
column1,
column2,
column3
FROM
table_name
WHERE
condition = 'value'
AND another_condition > 100
ORDER BY
column1 DESC
LIMIT 10;
-- INNER JOIN
SELECT
users.name,
orders.order_date,
orders.total_amount
FROM
users
INNER JOIN
orders ON users.id = orders.user_id
WHERE
orders.status = 'completed';
-- LEFT JOIN (주문이 없는 사용자를 포함하여 모두 조회)
SELECT
users.name,
COUNT(orders.id) as order_count,
COALESCE(SUM(orders.total_amount), 0) as total_spent
FROM
users
LEFT JOIN
orders ON users.id = orders.user_id
GROUP BY
users.id, users.name;
-- WHERE 절의 서브쿼리
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
-- CTE (가독성 향상을 위해 권장)
WITH high_value_customers AS (
SELECT
user_id,
SUM(total_amount) as lifetime_value
FROM orders
GROUP BY user_id
HAVING SUM(total_amount) > 1000
)
SELECT
users.name,
users.email,
hvc.lifetime_value
FROM users
INNER JOIN high_value_customers hvc ON users.id = hvc.user_id;
-- 그룹 내 순위 지정
SELECT
name,
department,
salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) as salary_rank
FROM
employees;
-- 누계 (Running totals)
SELECT
order_date,
total_amount,
SUM(total_amount) OVER (ORDER BY order_date) as running_total
FROM
orders;
-- 이동 평균 (Moving averages)
SELECT
order_date,
total_amount,
AVG(total_amount) OVER (
ORDER BY order_date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) as moving_avg_7days
FROM
daily_sales;
더 복잡한 쿼리 패턴은 examples/complex_queries.sql을 참조하세요.
-- 쿼리 성능 분석
EXPLAIN ANALYZE
SELECT
users.name,
COUNT(orders.id) as order_count
FROM users
LEFT JOIN orders ON users.id = orders.user_id
GROUP BY users.id, users.name;
-- 확인할 내용:
-- - Seq Scan (나쁨) vs Index Scan (좋음)
-- - 높은 비용(cost) 수치
-- - 처리되는 대량의 행 수(row counts)
-- 나쁨: 인덱스 컬럼에 함수 사용
SELECT * FROM users WHERE LOWER(email) = 'user@example.com';
-- 좋음: 인덱스 컬럼을 가공하지 않음
SELECT * FROM users WHERE email = LOWER('user@example.com');
-- 나쁨: SELECT * 사용
SELECT * FROM large_table WHERE id = 123;
-- 좋음: 필요한 컬럼만 선택
SELECT id, name, email FROM large_table WHERE id = 123;
포괄적인 최적화 기법은 references/query-optimization.md를 참조하세요.
제1정규형 (1NF): 반복되는 그룹 제거, 원자성(atomic) 확보
-- 좋음: 주문 항목을 위한 별도 테이블 구성
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_name VARCHAR(100)
);
CREATE TABLE order_items (
order_item_id INT PRIMARY KEY,
order_id INT REFERENCES orders(order_id),
product_name VARCHAR(100)
);
제2정규형 (2NF): 기본키가 아닌 모든 속성이 기본키 전체에 의존해야 함
-- 좋음: 제품 정보를 분리하여 관리
CREATE TABLE products (
product_id INT PRIMARY KEY,
product_name VARCHAR(100),
product_price DECIMAL(10, 2)
);
CREATE TABLE order_items (
order_id INT,
product_id INT,
quantity INT,
PRIMARY KEY (order_id, product_id),
FOREIGN KEY (product_id) REFERENCES products(product_id)
);
제3정규형 (3NF): 이행적 종속성(transitive dependency)이 없어야 함
일대다 (One-to-Many):
CREATE TABLE authors (
author_id INT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100) UNIQUE
);
CREATE TABLE books (
book_id INT PRIMARY KEY,
title VARCHAR(200),
author_id INT NOT NULL,
published_date DATE,
FOREIGN KEY (author_id) REFERENCES authors(author_id)
);
다대다 (Many-to-Many):
CREATE TABLE students (
student_id INT PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE courses (
course_id INT PRIMARY KEY,
course_name VARCHAR(100)
);
-- 교차(Junction) 테이블
CREATE TABLE enrollments (
enrollment_id INT PRIMARY KEY,
student_id INT NOT NULL,
course_id INT NOT NULL,
enrollment_date DATE,
grade CHAR(2),
FOREIGN KEY (student_id) REFERENCES students(student_id),
FOREIGN KEY (course_id) REFERENCES courses(course_id),
UNIQUE (student_id, course_id)
);
더 많은 스키마 패턴은 examples/schema_examples.sql을 참조하세요.
-- 단일 컬럼 인덱스
CREATE INDEX idx_users_email ON users(email);
-- 복합 인덱스 (컬럼 순서가 중요합니다!)
CREATE INDEX idx_orders_user_date ON orders(user_id, order_date);
-- 고유 인덱스
CREATE UNIQUE INDEX idx_users_username ON users(username);
-- 부분 인덱스 (PostgreSQL)
CREATE INDEX idx_active_users ON users(email) WHERE status = 'active';
인덱스가 필요한 경우:
인덱스를 피해야 하는 경우:
상세한 인덱스 전략은 references/indexes-performance.md를 참조하세요.
-- 1단계: nullable 컬럼으로 추가
ALTER TABLE users ADD COLUMN status VARCHAR(20);
-- 2단계: 기존 데이터 채우기
UPDATE users SET status = 'active' WHERE status IS NULL;
-- 3단계: NOT NULL 제약 조건 부여
ALTER TABLE users ALTER COLUMN status SET NOT NULL;
-- 4단계: 새 행을 위한 기본값 설정
ALTER TABLE users ALTER COLUMN status SET DEFAULT 'active';
-- 롤백 계획
ALTER TABLE users DROP COLUMN status;
-- 좋음: 컬럼을 먼저 nullable로 추가한 뒤 데이터 채움
ALTER TABLE large_table ADD COLUMN new_column VARCHAR(100);
-- 대량 업데이트는 배치(batch) 단위로 수행
UPDATE large_table SET new_column = 'value' WHERE new_column IS NULL LIMIT 1000;
-- 완료될 때까지 반복
-- 그 다음 NOT NULL 설정
ALTER TABLE large_table ALTER COLUMN new_column SET NOT NULL;
추가 마이그레이션 패턴은 examples/migrations.sql을 참조하세요.
-- PostgreSQL
INSERT INTO users (user_id, name, email, updated_at)
VALUES (1, 'John Doe', 'john@example.com', NOW())
ON CONFLICT (user_id)
DO UPDATE SET
name = EXCLUDED.name,
email = EXCLUDED.email,
updated_at = NOW();
-- MySQL
INSERT INTO users (user_id, name, email, updated_at)
VALUES (1, 'John Doe', 'john@example.com', NOW())
ON DUPLICATE KEY UPDATE
name = VALUES(name),
email = VALUES(email),
updated_at = NOW();
-- 계층형 데이터 탐색
WITH RECURSIVE employee_hierarchy AS (
-- Anchor: 최상위 직원
SELECT id, name, manager_id, 1 as level
FROM employees
WHERE manager_id IS NULL
UNION ALL
-- Recursive: 이전 레벨에 보고하는 직원들
SELECT e.id, e.name, e.manager_id, eh.level + 1
FROM employees e
INNER JOIN employee_hierarchy eh ON e.manager_id = eh.id
)
SELECT * FROM employee_hierarchy ORDER BY level, name;
피벗 테이블, JSON 작업 및 벌크 작업을 포함한 고급 패턴은 references/advanced-patterns.md를 참조하세요.
모범 사례 적용 예시:
CREATE TABLE orders (
order_id INT PRIMARY KEY,
user_id INT NOT NULL,
order_date DATE NOT NULL DEFAULT CURRENT_DATE,
total_amount DECIMAL(10, 2) CHECK (total_amount >= 0),
status VARCHAR(20) CHECK (status IN ('pending', 'completed', 'cancelled')),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(user_id)
);
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_orders_status ON orders(status);
포괄적인 모범 사례는 references/best-practices.md를 참조하세요.
다음을 주의하세요:
예시 - N+1 문제 피하기:
# 나쁨: N+1 쿼리
users = db.query("SELECT * FROM users")
for user in users:
orders = db.query("SELECT * FROM orders WHERE user_id = ?", user.id)
# 좋음: JOIN을 이용한 단일 쿼리
result = db.query("""
SELECT users.*, orders.*
FROM users
LEFT JOIN orders ON users.id = orders.user_id
""")
문제 해결 방법의 전체 목록은 references/common-pitfalls.md를 참조하세요.
헬퍼 스크립트 (scripts/):
sql_helper.py - 쿼리 빌딩, 스키마 내성 조사(introspection), 인덱스 분석 및 마이그레이션 보조 유틸리티예시 (examples/):
complex_queries.sql - CTE, 윈도우 함수, 서브쿼리를 활용한 고급 쿼리 패턴schema_examples.sql - 다양한 유스케이스를 위한 전체 스키마 설계 예시migrations.sql - 안전한 마이그레이션 패턴 및 무중단 기법참조 문서 (references/):
query-optimization.md - 포괄적인 쿼리 최적화 기법 및 EXPLAIN 분석indexes-performance.md - 상세 인덱스 전략, 유지보수 및 모니터링advanced-patterns.md - UPSERT, 벌크 작업, 피벗 테이블, JSON 작업, 재귀 쿼리best-practices.md - 전체 SQL 모범 사례 가이드common-pitfalls.md - 일반적인 실수와 방지 방법references/query-optimization.md를 확인하세요.examples/schema_examples.sql을 참조하세요.references/advanced-patterns.md를 확인하세요.scripts/sql_helper.py를 활용하세요.SQL 데이터베이스 작업 시:
마이그레이션 시: