멀티캠퍼스 데이터분석 4월 17일 수업 내용 + 시험 대비 프로그래밍 기초 정리
이론
1. DataBase 개요
2. MySQL — DDL (CREATE / ALTER / DROP)
3. MySQL — DML (INSERT / UPDATE / DELETE / SELECT)
4. MySQL — WHERE / JOIN / ORDER BY / GROUP BY
5. MongoDB
실습
시험 대비 기초 정리
데이터베이스는 통합하여 관리되는 데이터의 집합체입니다.
중복된 데이터를 없애고 자료를 구조화하여 효율적인 처리를 할 수 있도록 관리됩니다.

SQL은 데이터베이스에서 데이터를 정의·조작·제어하기 위한 언어입니다.



데이터의 무결성을 지키기 위해 데이터 입력 시 실행되는 검사 규칙입니다.
| 제약조건 | 설명 |
|---|---|
NOT NULL | NULL 값 저장 불가 |
UNIQUE | 서로 다른 값만 허용 |
PRIMARY KEY | NOT NULL + UNIQUE, 기본키 |
FOREIGN KEY | 다른 테이블에 의존 (외래키) |
DEFAULT | 기본값 설정 |
AUTO_INCREMENT | 1부터 시작해 새 레코드마다 1씩 증가 |



DROP DATABASE 데이터베이스이름;
DROP TABLE 테이블이름;
⚠️
DROP은 테이블 자체를 삭제합니다.
테이블 내 데이터만 삭제하려면DELETE를 사용하세요.

💡 필드명을 생략하면 테이블의 필드 순서대로 자동 대입됩니다.

⚠️
WHERE절이 없으면 테이블의 모든 행이 수정됩니다.

⚠️
WHERE절이 없으면 테이블의 모든 데이터가 삭제됩니다.

💡 필드명에
*를 사용하면 모든 컬럼을 선택합니다.

💡 리스트에 없는 값을 선택할 때는
NOT IN을 사용합니다.
여러 테이블에서 컬럼 값을 조합하여 하나의 집합으로 표현합니다.

| JOIN 종류 | 설명 |
|---|---|
LEFT JOIN | 왼쪽 테이블 전체 + 오른쪽 일치하는 것 |
RIGHT JOIN | 오른쪽 테이블 전체 + 왼쪽 일치하는 것 |
INNER JOIN | 두 테이블의 교집합 |
FULL OUTER JOIN | MySQL 미지원 → LEFT + RIGHT JOIN으로 구현 |
LEFT JOIN

INNER JOIN

SELECT 문에 추가하여 특정 컬럼 기준으로 정렬합니다.

유형별 집계가 필요할 때 사용합니다.

💡 WHERE vs HAVING
WHERE: 그룹화 전 조건HAVING: 그룹화 후 조건





MongoDB는 NoSQL 데이터베이스로, JSON과 유사한 BSON 형태의 도큐먼트를 저장합니다.
전통적인 테이블 기반 관계형 DB 구조 대신 동적 스키마형 도큐먼트를 사용합니다.
| 개념 | MySQL 대응 | 설명 |
|---|---|---|
| Database | Database | Collection의 물리적 컨테이너 |
| Collection | Table | Document의 그룹 |
| Document | Row | 실제 데이터 단위 (JSON 형태) |





1. pymysql 라이브러리 설치
2. 라이브러리 로드
3. DB 서버와 연결
4. Cursor(가상공간) 생성
5. SQL 쿼리 작성 후 질의
6. 결과 수신 (SELECT → fetchall())
7. 연결 종료
# !pip install pymysql cryptography
import pymysql
# DB 서버 연결
# 내 컴퓨터 주소: 127.0.0.1 또는 localhost
_db = pymysql.connect(
host = '127.0.0.1', # 서버 주소
port = 3306, # MySQL 기본 포트
user = 'root', # DB 접속 아이디
password = '1234', # 비밀번호
db = 'multicam' # 사용할 데이터베이스명
)
# 기본 Cursor — 결과가 튜플 형태
cursor = _db.cursor()
# DictCursor — 결과가 딕셔너리 형태 (컬럼명이 key)
cursor2 = _db.cursor(pymysql.cursors.DictCursor)
select_query = """
SELECT * FROM `emp`
"""
# 커서에 쿼리 전달
cursor.execute(select_query)
cursor2.execute(select_query)
# SELECT 결과 가져오기
# fetchall() 호출 후 cursor 내부 데이터는 제거됨
select1 = cursor.fetchall() # 튜플 형태
select2 = cursor2.fetchall() # 딕셔너리 형태
import pandas as pd
df1 = pd.DataFrame(select1) # 기본 Cursor 결과
df2 = pd.DataFrame(select2) # DictCursor 결과 (컬럼명 자동 적용)
df1.head(1)
df2.head(1)
| Cursor 종류 | 결과 타입 | DataFrame 변환 시 컬럼명 |
|---|---|---|
기본 cursor() | 튜플 | 자동 생성 (0, 1, 2...) |
DictCursor | 딕셔너리 | DB 컬럼명 자동 적용 ✅ |
💡 SELECT vs INSERT/UPDATE/DELETE
SELECT→fetchall()로 결과를 받아옴INSERT/UPDATE/DELETE→ 반환 데이터 없음,_db.commit()으로 DB에 반영 필요
데이터가 저장되는 공간에 주소 대신 사용하는 별칭입니다.
| 구분 | 종류 | 특징 |
|---|---|---|
| 불변 | 문자, 숫자, 튜플 | 각각 다른 공간에 저장, 복사해도 원본 불변 |
| 가변 | 리스트, 딕셔너리 | = 대입 시 같은 주소 공유, copy() 필요 |
# 불변 데이터 — 독립적
a = 10
b = a
b += 1
print(a) # 10 (영향 없음)
# 가변 데이터 — 주소 공유
list_a = [1, 2, 3]
list_b = list_a # 같은 주소를 가리킴
list_b.append(4)
print(list_a) # [1, 2, 3, 4] — list_a도 변경됨!
list_c = list_a.copy() # 독립적인 복사본
⚠️ 함수 매개변수 기본값에 가변 데이터를 쓸 때 주의
def func(a, b=[]): b.append(a) return b func(1) # [1] func(2) # [1, 2] — b가 유지됨! (의도치 않은 동작) # 해결: 기본값을 None으로, 내부에서 copy() def func(a, b=None): if b is None: b = [] b.append(a) return b
# 기본형
if 조건식:
실행 코드
# if ~ else
if 조건식:
참인 경우
else:
거짓인 경우
# 다중 조건
if 조건식1:
...
elif 조건식2:
...
else:
...
💡
if뒤에 조건식이 아닌 다른 데이터가 오면 강제로bool로 변환됩니다.
빈 문자열, 빈 리스트,0,None→False
값이 있는 데이터 →True(존재 여부 판단)
# range 사용
for 변수 in range(시작값, 종료값, 증가값):
반복 코드
# 자료형 데이터 순회
for 변수 in [리스트 | 딕셔너리 | 튜플 | Series]:
반복 코드
# 2차원 데이터라면 각 행(1차원)이 순서대로 대입됨
# 조건이 거짓이 될 때까지 반복
while 조건식:
반복 코드
i += 1 # 조건이 거짓이 되도록 값 변화 필수 (안 하면 무한 루프)
| 키워드 | 동작 |
|---|---|
break | 반복문 강제 종료 |
continue | 아래 코드 건너뛰고 반복문 처음으로 |
💡 반복 횟수가 명확하지 않을 때는
for보다while이 더 적합합니다.
def 함수명(매개변수):
실행 코드
return 결과
# 기본값 설정 — 뒤쪽 매개변수부터
def func(a, b=5):
return a + b
# 가변 인자
def func(*args):
return sum(args)
# 키워드 강제
def func(*, x, y):
return x + y
붕어빵 틀! — 변수 + 함수의 결합체
class MyClass:
class_var = [] # 클래스 변수 — 모든 인스턴스가 공유
def __init__(self, x):
self.x = x # 인스턴스 변수 — 각 인스턴스가 독립적으로 보유
def method(self):
return self.x ** 2
| 개념 | 설명 |
|---|---|
__init__ | 클래스 생성 시 자동 호출되는 생성자 |
self | 클래스 자기 자신을 가리키는 참조 |
| 인스턴스 변수 | self.변수 — 각 인스턴스가 독립적으로 소유 |
| 클래스 변수 | 클래스명.변수 — 모든 인스턴스가 공유 |
| 상속 | class 자식(부모) — 부모 기능 재사용 |
| 오버라이드 | 부모 메서드를 자식에서 같은 이름으로 재정의 |
코드를 분할 관리하기 위한 단위입니다.
| 단위 | 구성 | 설명 |
|---|---|---|
| 모듈 | .py 파일 1개 | 변수·함수·클래스를 담은 파일 |
| 라이브러리 | 여러 모듈의 폴더 | 관련 모듈들의 집합 |
| 프레임워크 | 여러 라이브러리 | 전체 개발 구조를 제공 |
import 모듈명 # 모듈 전체 import
from 모듈명 import 함수명 # 특정 함수만 import
import importlib
importlib.reload(모듈명) # 수정된 모듈 재로드
분할 관리의 장점:
| 분류 | 명령어 | 설명 |
|---|---|---|
| DDL | CREATE | 테이블/DB 생성 |
| DDL | ALTER | 테이블/DB 수정 |
| DDL | DROP | 테이블/DB 삭제 |
| DML | INSERT | 데이터 추가 |
| DML | UPDATE | 데이터 수정 |
| DML | DELETE | 데이터 삭제 |
| DML | SELECT | 데이터 조회 |
| 조건 | WHERE | 조건 필터 (그룹화 전) |
| 조건 | HAVING | 조건 필터 (그룹화 후) |
| 정렬 | ORDER BY | 컬럼 기준 정렬 |
| 그룹 | GROUP BY | 유형별 그룹화 |
| 결합 | JOIN | 테이블 결합 |
import pymysql
import pandas as pd
# 1. 연결
_db = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='1234', db='DB명')
# 2. 커서 생성
cursor = _db.cursor(pymysql.cursors.DictCursor)
# 3. 쿼리 실행
cursor.execute("SELECT * FROM 테이블명")
# 4. 결과 수신
result = cursor.fetchall()
# 5. DataFrame 변환
df = pd.DataFrame(result)
# 6. 연결 종료
_db.close()