초보자도 가능한 실습형 예제 (Sakila DB 활용)
🧩 데이터.. 어디에 쓰지?
💭 "SQL로 데이터는 뽑았는데, 이제 뭘 하지?"
💭 "시각화 어렵지 않을까?"
그 궁금증, 오늘 한방에 해결합니다.
오늘은 Sakila DB를 기반으로 MySQL + Python + Claude 조합으로
‘데이터 추출 → CSV 저장 → AI 시각화’ 흐름을 실습하며 정리해봤습니다.
1. 준비물 & 환경 세팅
💻 사용 도구
- MySQL (Sakila DB 설치)
- Python (pymysql, pandas, matplotlib)
- Claude (또는 ChatGPT, AI 이미지 시각화 도구)
- anaconda3 (python)
✅ anaconda3 설치 후 환경변수 세팅하기.
✅ 아나콘다3 설치 제대로 됐는지 cmd 에서 확인할 것.
** 환경 변수 세팅 및 cmd 확인 관련 내용은 따로 블로그로 올릴 예정
📦 필수 라이브러리 설치
pip install pymysql pandas matplotlib
2. MySQL과 Python 연결하기
✅ 기본 연결 코드
import pymysql
import pandas as pd
conn = pymysql.connect(
host='localhost',
user='your_user',
password='your_password',
db='sakila',
charset='utf8mb4'
)
3. 데이터 추출 + CSV 저장
1️⃣ 카테고리별 영화 수
SELECT c.name AS category_name, COUNT(*) AS film_count
FROM film_category fc
JOIN category c ON fc.category_id = c.category_id
GROUP BY c.name
ORDER BY film_count DESC;
2️⃣ 월별 대여 건수
SELECT DATE_FORMAT(rental_date, '%Y-%m') AS rental_month, COUNT(*) AS rental_count
FROM rental
GROUP BY rental_month
ORDER BY rental_month;
3️⃣ 고객별 총 지출 Top 10
SELECT CONCAT(c.first_name, ' ', c.last_name) AS customer_name,
SUM(p.amount) AS total_spent
FROM payment p
JOIN customer c ON p.customer_id = c.customer_id
GROUP BY c.customer_id
ORDER BY total_spent DESC
LIMIT 10;

Export 를 누른 후 csv 로 저장하기.
4. Claude를 활용한 시각화
📁 Claude에 전달한 방식
- CSV 3개를 업로드하고,
- 명확하게 명령:
1. category_film_count.csv → 수직 막대그래프
2. rental_by_month.csv → 꺾은선 그래프 & 막대그래프 비교
3. top10_spenders.csv → 고객 이름 포함한 수평 막대그래프
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from matplotlib.ticker import FuncFormatter
# 한글 폰트 설정 (필요시 주석 해제 후 사용)
# import matplotlib.font_manager as fm
# font_path = '/usr/share/fonts/truetype/nanum/NanumGothic.ttf' # 시스템에 맞는 폰트 경로로 변경 필요
# font_name = fm.FontProperties(fname=font_path).get_name()
# plt.rc('font', family=font_name)
# plt.rc('axes', unicode_minus=False) # 마이너스 기호 깨짐 방지
# 스타일 설정
plt.style.use('seaborn-v0_8-whitegrid')
colors = sns.color_palette('tab10', 16)
custom_palette = sns.color_palette('husl', 16)
# Figure 사이즈 설정
plt.figure(figsize=(15, 24))
# 1. 카테고리별 영화수 데이터
category_data = pd.DataFrame({
'category_name': ["Sports", "Foreign", "Family", "Documentary", "Animation", "Action",
"New", "Drama", "Games", "Sci-Fi", "Children", "Comedy",
"Classics", "Travel", "Horror", "Music"],
'COUNT_FILM_CATEGORY': [74, 73, 69, 68, 66, 64, 63, 62, 61, 61, 60, 58, 57, 57, 56, 51]
})
# 내림차순으로 정렬 - 시각화를 위해
category_data_sorted = category_data.sort_values('COUNT_FILM_CATEGORY', ascending=False)
# 2. 월별 대여 건수 데이터
rental_data = pd.DataFrame({
'rental_month': ["2005-05", "2005-06", "2005-07", "2005-08", "2006-02"],
'rental_count': [1156, 2311, 6709, 5686, 182]
})
# 3. 고객별 총 지출 Top 10
customer_data = pd.DataFrame({
'customer_id': [526, 148, 144, 137, 178, 459, 469, 468, 236, 181],
'customer_name': ["KARL SEAL", "ELEANOR HUNT", "CLARA SHAW", "RHONDA KENNEDY",
"MARION SNYDER", "TOMMY COLLAZO", "WESLEY BULL", "TIM CARY",
"MARCIA DEAN", "ANA BRADLEY"],
'total_spent': [221.55, 216.54, 195.58, 194.61, 194.61, 186.62, 177.60, 175.61, 175.58, 174.66]
})
# 내림차순으로 정렬 (수평 막대 그래프용)
customer_data_sorted = customer_data.sort_values('total_spent', ascending=False)
# ================ 그래프 1: 카테고리별 영화수 ================
plt.subplot(3, 1, 1)
ax1 = sns.barplot(x='category_name', y='COUNT_FILM_CATEGORY', data=category_data_sorted,
palette=custom_palette)
# 막대 위에 값 표시
for i, v in enumerate(category_data_sorted['COUNT_FILM_CATEGORY']):
ax1.text(i, v + 0.5, str(v), ha='center')
plt.title('카테고리별 영화수', fontsize=16, pad=20)
plt.xlabel('카테고리명', fontsize=12, labelpad=10)
plt.ylabel('영화수', fontsize=12)
plt.xticks(rotation=45, ha='right')
# 여백 조정
plt.subplots_adjust(hspace=0.4)
# ================ 그래프 2: 월별 대여 건수 (막대 그래프 + 꺾은선 그래프) ================
plt.subplot(3, 1, 2)
ax2 = plt.gca()
# 막대 그래프
bar_plot = sns.barplot(x='rental_month', y='rental_count', data=rental_data,
alpha=0.7, color='#0066FF', ax=ax2)
# 막대 위에 값 표시
for i, v in enumerate(rental_data['rental_count']):
ax2.text(i, v + 200, f"{v:,}", ha='center')
# 꺾은선 그래프 (같은 축에)
line_plot = sns.lineplot(x='rental_month', y='rental_count', data=rental_data,
marker='o', linewidth=2.5, color='#003399', ax=ax2)
plt.title('월별 대여 건수', fontsize=16, pad=20)
plt.xlabel('월', fontsize=12, labelpad=10)
plt.ylabel('대여 건수', fontsize=12)
# y축 천 단위 콤마 포맷팅
def thousands_formatter(x, pos):
return f'{int(x):,}'
ax2.yaxis.set_major_formatter(FuncFormatter(thousands_formatter))
# 추이 분석 텍스트 추가
plt.figtext(0.5, 0.49, "추이 분석: 2005년 7월에 대여 건수가 가장 많았으며 (6,709건), 이후 8월에는 감소하였습니다. 2006년 2월에는 급격히 감소한 것으로 나타납니다.",
ha="center", bbox={"facecolor":"lightgrey", "alpha":0.2, "pad":5}, fontsize=10)
# ================ 그래프 3: 고객별 총 지출 Top 10 (수평 막대 그래프) ================
plt.subplot(3, 1, 3)
ax3 = sns.barplot(y='customer_name', x='total_spent', data=customer_data_sorted,
palette=sns.color_palette('YlOrRd_r', len(customer_data_sorted)), orient='h')
# 막대 끝에 값 표시
for i, v in enumerate(customer_data_sorted['total_spent']):
ax3.text(v + 1, i, f"${v:.2f}", va='center')
plt.title('고객별 총 지출 Top 10', fontsize=16, pad=20)
plt.xlabel('총 지출 ($)', fontsize=12, labelpad=10)
plt.ylabel('고객 이름', fontsize=12)
# x축의 범위를 조정하여 레이블이 잘 보이도록 함
plt.xlim(0, max(customer_data_sorted['total_spent']) * 1.1)
# 전체 레이아웃 조정
plt.tight_layout(h_pad=6)
plt.savefig('data_visualization.png', dpi=300, bbox_inches='tight')
plt.show()
# 그래프 3개를 각각 별도로 저장
# 카테고리별 영화수
plt.figure(figsize=(12, 8))
ax = sns.barplot(x='category_name', y='COUNT_FILM_CATEGORY', data=category_data_sorted,
palette=custom_palette)
# 막대 위에 값 표시
for i, v in enumerate(category_data_sorted['COUNT_FILM_CATEGORY']):
ax.text(i, v + 0.5, str(v), ha='center')
plt.title('카테고리별 영화수', fontsize=16, pad=20)
plt.xlabel('카테고리명', fontsize=12, labelpad=10)
plt.ylabel('영화수', fontsize=12)
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.savefig('category_chart.png', dpi=300, bbox_inches='tight')
# 월별 대여 건수 - 두 가지 버전 (막대 그래프와 꺾은선 그래프)
# 막대 그래프 버전
plt.figure(figsize=(10, 6))
ax = sns.barplot(x='rental_month', y='rental_count', data=rental_data, color='#0066FF')
# 막대 위에 값 표시
for i, v in enumerate(rental_data['rental_count']):
ax.text(i, v + 200, f"{v:,}", ha='center')
plt.title('월별 대여 건수 (막대 그래프)', fontsize=16, pad=20)
plt.xlabel('월', fontsize=12, labelpad=10)
plt.ylabel('대여 건수', fontsize=12)
plt.tight_layout()
plt.savefig('rental_bar_chart.png', dpi=300, bbox_inches='tight')
# 꺾은선 그래프 버전
plt.figure(figsize=(10, 6))
ax = sns.lineplot(x='rental_month', y='rental_count', data=rental_data,
marker='o', linewidth=2.5, color='#003399')
# 선 위에 값 표시
for i, v in enumerate(rental_data['rental_count']):
ax.text(i, v + 200, f"{v:,}", ha='center')
plt.title('월별 대여 건수 (꺾은선 그래프)', fontsize=16, pad=20)
plt.xlabel('월', fontsize=12, labelpad=10)
plt.ylabel('대여 건수', fontsize=12)
plt.tight_layout()
plt.savefig('rental_line_chart.png', dpi=300, bbox_inches='tight')
# 복합 그래프 버전
plt.figure(figsize=(10, 6))
ax = plt.gca()
sns.barplot(x='rental_month', y='rental_count', data=rental_data, alpha=0.7, color='#0066FF', ax=ax)
sns.lineplot(x='rental_month', y='rental_count', data=rental_data,
marker='o', linewidth=2.5, color='#003399', ax=ax)
# 막대 위에 값 표시
for i, v in enumerate(rental_data['rental_count']):
ax.text(i, v + 200, f"{v:,}", ha='center')
plt.title('월별 대여 건수 (복합 그래프)', fontsize=16, pad=20)
plt.xlabel('월', fontsize=12, labelpad=10)
plt.ylabel('대여 건수', fontsize=12)
plt.tight_layout()
plt.savefig('rental_combined_chart.png', dpi=300, bbox_inches='tight')
# 고객별 총 지출 Top 10
plt.figure(figsize=(12, 8))
ax = sns.barplot(y='customer_name', x='total_spent', data=customer_data_sorted,
palette=sns.color_palette('YlOrRd_r', len(customer_data_sorted)), orient='h')
# 막대 끝에 값 표시
for i, v in enumerate(customer_data_sorted['total_spent']):
ax.text(v + 1, i, f"${v:.2f}", va='center')
plt.title('고객별 총 지출 Top 10', fontsize=16, pad=20)
plt.xlabel('총 지출 ($)', fontsize=12, labelpad=10)
plt.ylabel('고객 이름', fontsize=12)
plt.xlim(0, max(customer_data_sorted['total_spent']) * 1.1)
plt.tight_layout()
plt.savefig('customer_chart.png', dpi=300, bbox_inches='tight')
print("모든 그래프가 생성되었습니다!")

vscode 에 py 라는 python 파일에 해당 명령어 복사붙여넣기 후 재생버튼을 클릭하면
아래와 같은 그래프가 뜬다.
✅ Claude가 반환한 예시 그래프

5. 실무 팁 💡
- 그래프를 직접 그릴 필요 없다: Claude에게 적절한 명령만 하면 자동으로 예쁜 시각화 제공.
- CSV 파일은 컬럼명을 명확하게: category, count, month, amount 등 직관적 명명 중요.
- 시각화 용도에 따라 그래프 타입 지정:
막대 vs 꺾은선 vs 수평형을 직접 지시하면 정확도 높아짐.
🔚 마무리
SQL + Python + Claude 조합은 초보자에게도 시각화까지 가는 최단 루트입니다.
데이터 분석 입문자뿐 아니라, 마케팅 리포트/포트폴리오를 준비 중이라면
이 조합은 진짜 꿀입니다.
'국비지원 - 실버마케팅(코딩) 250206~' 카테고리의 다른 글
| 🐍 [Python 입문] 자바스크립트 개발자를 위한 파이썬 기초 정복! (문법 & 예제 총정리) (0) | 2025.05.22 |
|---|---|
| 💡 MySQL CREATE VIEW 완전 정복: 초보자도 이해하고 실력자도 팁 챙겨가는 뷰(View) 사용법! (0) | 2025.05.20 |
| 데이터 결측치가 무슨 의미야? (0) | 2025.05.16 |
| “복잡한 SQL은 이제 그만! VIEW로 가독성 높이기” (0) | 2025.05.16 |
| “UNION? JOIN? 뭘 붙이냐에 따라 다릅니다 – SQL 쿼리 꿀팁 정리” (0) | 2025.05.16 |