데이터 엑셀 key value 데이터베이스 테이블

HY_1023·2026년 3월 12일

헷갈리는 부분 정리

목록 보기
11/40

질문

key value 값도 데이터베이스와 엑셀 비슷한거니?

답변

Key-Value도 비슷하긴 한데, 살짝 달라요!


비교해보면

엑셀                DB (테이블)          Key-Value
────────────────────────────────────────────────────
열 제목 = 이름       컬럼명 = name        Key = "name"
셀 값   = 김철수     값     = "김철수"     Value = "김철수"

구조 차이가 핵심이에요

엑셀 / DB표 구조 (행과 열이 정해져 있음)

id | name  | age
1  | 김철수 | 25
2  | 이영희 | 30

Key-Value쌍으로만 존재 (표 구조 없음)

{
  "name": "김철수",
  "age": 25
}

결정적 차이

엑셀/DBKey-Valu
구조(행+열)쌍만 존재
컬럼고정모든 행이 같은 컬럼각자 다른 Key 가능
관계 표현|JOIN으로 연결어려움
대표 예시MySQL|Redis, JSON

실생활 비유

DB/엑셀  →  학교 출석부 (모든 학생이 같은 양식)

Key-Value →  각자 다른 포스트잇
             어떤 건 이름만, 어떤 건 전화번호만 적혀있어도 됨

핵심 한 줄

개념은 비슷하지만, DB/엑셀은 표 형태로 엄격하게 구조가 고정되고 Key-Value는 자유롭게 쌍으로만 저장한다는 게 차이예요! 🎯


나의 질문?

데이터 베이스와 엑셀 비슷하다고 했는데 그렇다면 필드명 테이블이라고 하고 컬럼은 필드명의 속성들값이라고 생각하면되나요?

답변

거의 다 왔는데 살짝 반대로 이해하신 것 같아요! 정확히 잡아드릴게요.


올바른 대응 관계

엑셀 열 제목 (이름, 나이, 이메일)  =  필드명 = 컬럼명
                ↕
엑셀 열 전체                       =  컬럼 (필드)
                ↕
각 셀의 값                         =  값 (Value)

예시로 보면

idnameage
1김철수25
2이영희30
테이블  = 표 전체
필드명  = "id", "name", "age"  ← 열 제목 자체
컬럼   = "name" 열 전체 (김철수, 이영희 포함한 열)
값     = "김철수", 25 같은 각각의 데이터

한 줄 정리

필드명 = 컬럼명 (같은 말이에요!) 테이블 안에 있는 열의 이름이 필드명이고, 그 열 전체가 컬럼입니다.

쉽게 말하면 필드명은 컬럼의 이름표 라고 생각하면 딱 맞아요! 🎯


SQL이란?

Structured(구조화된) Query(질문) Language

— 데이터베이스와 대화하는 언어예요. 데이터를 저장, 조회, 수정, 삭제하는 모든 작업을 SQL로 합니다.


데이터베이스 vs 엑셀

맞아요! 개념 잡을 때 엑셀이랑 비교하면 딱 이해됩니다.


구조가 거의 같아요

엑셀                    데이터베이스
─────────────────────────────────────
파일 (.xlsx)      ≈     데이터베이스
시트 (Sheet)      ≈     테이블 (Table)
열 (Column)       ≈     컬럼 (Column)
행 (Row)          ≈     행 (Row)
셀               ≈     값 (Value)

엑셀의 시트 한 장 = DB의 테이블 하나라고 보면 됩니다.


그럼 왜 DB를 쓰냐?

상황엑셀데이터베이스
데이터 100만 건버벅거리거나 뻗음 💀거뜬함 ✅
동시 접속한 명만 수정 가능1000명이 동시에 읽기/쓰기 ✅
앱이랑 연동불가능API로 바로 연결 ✅
실수로 삭제ctrl+Z 조마조마트랜잭션으로 롤백 ✅
데이터 검색필터 직접 클릭SQL로 0.001초 ✅
보안파일 공유하면 다 보임권한별 접근 제어 ✅

한 줄 요약

엑셀은 사람이 눈으로 보는 도구, DB는 프로그램이 자동으로 처리하는 도구

개인 가계부 → 엑셀로 충분 쇼핑몰/앱 → 무조건 DB 필요

1. 데이터베이스 구조 이해

데이터베이스 (Database)
└── 테이블 (Table)  ← 엑셀 시트라고 생각
    ├── 컬럼 (Column) ← 열 (이름, 나이, 이메일...)
    └── 행 (Row)     ← 실제 데이터 한 줄

예시 테이블 users:

idnameageemail
1김철수25chul@gmail.com
2이영희30young@gmail.com
3박민수22min@gmail.com

2. DDL — 테이블 구조 만들기

Data Definition Language — 테이블을 생성/수정/삭제

CREATE — 테이블 생성

CREATE TABLE users (
    id      INT PRIMARY KEY AUTO_INCREMENT,  -- 고유 번호, 자동 증가
    name    VARCHAR(100) NOT NULL,           -- 최대 100자, 필수
    age     INT,
    email   VARCHAR(200) UNIQUE,             -- 중복 불가
    created_at DATETIME DEFAULT NOW()        -- 기본값 현재 시간
);

주요 데이터 타입

INT              -- 정수 (1, 100, -5)
VARCHAR(n)       -- 가변 문자열 최대 n자 ("홍길동")
TEXT             -- 긴 문자열 (게시글 본문)
DATETIME         -- 날짜+시간 (2024-01-15 09:30:00)
DATE             -- 날짜만 (2024-01-15)
BOOLEAN          -- true / false
DECIMAL(10, 2)   -- 소수점 (돈 계산할 때: 99999999.99)

ALTER — 테이블 수정

ALTER TABLE users ADD COLUMN phone VARCHAR(20);     -- 컬럼 추가
ALTER TABLE users DROP COLUMN phone;                -- 컬럼 삭제
ALTER TABLE users MODIFY COLUMN name VARCHAR(200);  -- 컬럼 수정

DROP — 테이블 삭제

DROP TABLE users;           -- 테이블 완전 삭제 (복구 불가 ⚠️)
TRUNCATE TABLE users;       -- 데이터만 전부 삭제, 구조는 유지

3. DML — 데이터 조작

Data Manipulation Language — 실제 데이터를 다루는 것

INSERT — 데이터 삽입

-- 한 줄 삽입
INSERT INTO users (name, age, email)
VALUES ('김철수', 25, 'chul@gmail.com');

-- 여러 줄 한번에
INSERT INTO users (name, age, email) VALUES
    ('이영희', 30, 'young@gmail.com'),
    ('박민수', 22, 'min@gmail.com'),
    ('최지훈', 28, 'ji@gmail.com');

SELECT — 데이터 조회 ⭐ 가장 중요

-- 전체 조회
SELECT * FROM users;

-- 특정 컬럼만
SELECT name, email FROM users;

-- 조건 (WHERE)
SELECT * FROM users WHERE age >= 25;
SELECT * FROM users WHERE name = '김철수';
SELECT * FROM users WHERE age BETWEEN 20 AND 30;
SELECT * FROM users WHERE name LIKE '김%';   -- '김'으로 시작하는 이름
SELECT * FROM users WHERE email IS NULL;     -- 이메일 없는 유저

-- 정렬 (ORDER BY)
SELECT * FROM users ORDER BY age ASC;   -- 나이 오름차순
SELECT * FROM users ORDER BY age DESC;  -- 나이 내림차순

-- 개수 제한 (LIMIT)
SELECT * FROM users ORDER BY id DESC LIMIT 10;  -- 최신 10명만

-- 중복 제거 (DISTINCT)
SELECT DISTINCT age FROM users;

UPDATE — 데이터 수정

-- WHERE 없으면 전체 수정 ⚠️ 항상 WHERE 확인!
UPDATE users
SET age = 26, email = 'new@gmail.com'
WHERE id = 1;

DELETE — 데이터 삭제

-- WHERE 없으면 전체 삭제 ⚠️
DELETE FROM users WHERE id = 1;
DELETE FROM users WHERE age < 20;  -- 20살 미만 전부 삭제

4. 집계 함수 — 통계 내기

SELECT COUNT(*)       FROM users;              -- 총 유저 수
SELECT AVG(age)       FROM users;              -- 평균 나이
SELECT MAX(age)       FROM users;              -- 최고 나이
SELECT MIN(age)       FROM users;              -- 최저 나이
SELECT SUM(age)       FROM users;              -- 나이 합계

GROUP BY — 그룹으로 묶어서 집계

-- 나이대별 유저 수
SELECT age, COUNT(*) as user_count
FROM users
GROUP BY age
ORDER BY age;

-- 결과:
-- age | user_count
-- 22  | 3
-- 25  | 5
-- 30  | 2

HAVING — GROUP BY 결과에 조건

-- 유저가 2명 이상인 나이대만
SELECT age, COUNT(*) as cnt
FROM users
GROUP BY age
HAVING cnt >= 2;

-- WHERE vs HAVING
-- WHERE  : 그룹화 전에 필터링 (개별 행)
-- HAVING : 그룹화 후에 필터링 (그룹 결과)

5. JOIN — 테이블 합치기 ⭐

두 테이블이 있다고 가정:

users 테이블          orders 테이블
id | name            id | user_id | product
1  | 김철수           1  |    1    | 노트북
2  | 이영희           2  |    1    | 마우스
3  | 박민수           3  |    2    | 키보드
                     4  |    99   | 모니터  ← user_id 99는 없음

INNER JOIN — 양쪽 다 있는 것만

SELECT users.name, orders.product
FROM users
INNER JOIN orders ON users.id = orders.user_id;

-- 결과:
-- name   | product
-- 김철수 | 노트북
-- 김철수 | 마우스
-- 이영희 | 키보드
-- (박민수는 주문 없어서 제외, user_id=99도 제외)

LEFT JOIN — 왼쪽 테이블 전부 + 오른쪽은 있으면

SELECT users.name, orders.product
FROM users
LEFT JOIN orders ON users.id = orders.user_id;

-- 결과:
-- name   | product
-- 김철수 | 노트북
-- 김철수 | 마우스
-- 이영희 | 키보드
-- 박민수 | NULL    ← 주문 없어도 유저는 나옴

여러 테이블 JOIN

SELECT u.name, o.product, p.price
FROM users u
JOIN orders o ON u.id = o.user_id
JOIN products p ON o.product_id = p.id
WHERE u.age >= 25;

6. 서브쿼리 — 쿼리 안에 쿼리

-- 평균 나이보다 많은 유저
SELECT name, age
FROM users
WHERE age > (SELECT AVG(age) FROM users);

-- 주문한 적 있는 유저만 조회
SELECT name FROM users
WHERE id IN (SELECT DISTINCT user_id FROM orders);

-- 주문한 적 없는 유저 조회
SELECT name FROM users
WHERE id NOT IN (SELECT DISTINCT user_id FROM orders);

7. 인덱스 — 검색 속도 향상

-- 인덱스 없으면: 100만 건을 처음부터 끝까지 스캔 🐢
-- 인덱스 있으면: 바로 위치로 점프 ⚡

CREATE INDEX idx_email ON users(email);        -- 단일 인덱스
CREATE INDEX idx_name_age ON users(name, age); -- 복합 인덱스

-- 인덱스 확인
SHOW INDEX FROM users;

-- 인덱스 삭제
DROP INDEX idx_email ON users;

언제 인덱스 쓸까? WHERE, JOIN, ORDER BY에 자주 쓰이는 컬럼에 걸기. 단, 인덱스가 너무 많으면 INSERT/UPDATE가 느려짐.


8. 트랜잭션 — 묶음 처리

-- 은행 송금 예시
-- A가 B에게 10만원 송금할 때 중간에 오류나면?
-- → 둘 다 취소되어야 함

START TRANSACTION;

UPDATE accounts SET balance = balance - 100000 WHERE id = 'A';
UPDATE accounts SET balance = balance + 100000 WHERE id = 'B';

-- 둘 다 성공하면
COMMIT;

-- 하나라도 실패하면
ROLLBACK;  -- 전부 원래대로 되돌림

9. 실행 순서 — 헷갈리는 부분

SQL은 작성 순서실행 순서가 달라요:

-- 작성 순서
SELECT name, COUNT(*)   -- 5. 조회할 컬럼
FROM users              -- 1. 테이블 선택
JOIN orders ON ...      -- 2. 조인
WHERE age >= 20         -- 3. 필터링
GROUP BY name           -- 4. 그룹화
HAVING COUNT(*) >= 2    -- 6. 그룹 필터링
ORDER BY name           -- 7. 정렬
LIMIT 10;               -- 8. 개수 제한

-- 실행 순서: FROM → JOIN → WHERE → GROUP BY → SELECT → HAVING → ORDER BY → LIMIT

10. 자주 쓰는 실전 패턴

-- 페이지네이션 (2페이지, 한 페이지 10개)
SELECT * FROM users ORDER BY id DESC LIMIT 10 OFFSET 10;

-- 없으면 INSERT, 있으면 UPDATE
INSERT INTO users (id, name, email)
VALUES (1, '김철수', 'new@gmail.com')
ON DUPLICATE KEY UPDATE email = 'new@gmail.com';

-- NULL 처리
SELECT name, COALESCE(phone, '번호없음') as phone FROM users;

-- 날짜 필터
SELECT * FROM users
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY); -- 최근 7일

📌 학습 순서 추천

1단계: SELECT, WHERE, ORDER BY, LIMIT     (조회 기본)
2단계: INSERT, UPDATE, DELETE              (데이터 수정)
3단계: GROUP BY, HAVING, 집계함수          (통계)
4단계: JOIN                               (핵심 ⭐)
5단계: 서브쿼리, 인덱스, 트랜잭션           (심화)

궁금한 부분 있으면 더 파고들어 드릴게요! 🚀

profile
개발언어를 배우는 과정 기록

0개의 댓글