본문 바로가기

비개발자의 개발 일지

현장 팀장에서 수출 ERP까지 — AI와 함께 시스템을 만든 기록

시리즈 보기
php

MySQL INSERT INTO — 데이터 삽입 완전 정리

by 왕진 2026. 7. 14.
반응형

 

 

Web Development · MySQL

MySQL INSERT INTO —
데이터 삽입 완전 정리

VALUES 순서 · NULL 처리 · 부모-자식 삽입 순서까지
시작 오늘 분석할 코드

usertbl(회원)과 buytbl(구매)에 실제 데이터를 넣는 INSERT INTO 구문이다. NULL 처리 방식과 두 테이블 삽입 순서가 핵심이다.

-- usertbl 데이터 삽입 INSERT INTO usertbl VALUES('LSG', '이승기', 1987, '서울', '011', '1111111', 182, '2008-8-8'); INSERT INTO usertbl VALUES('SSK', '성시경', 1979, '서울', NULL, NULL, 186, '2013-12-12'); -- 휴대폰 없는 회원은 mobile1, mobile2에 NULL -- buytbl 데이터 삽입 (num은 AUTO_INCREMENT → NULL 전달) INSERT INTO buytbl VALUES(NULL, 'KBS', '운동화', NULL, 30, 2); INSERT INTO buytbl VALUES(NULL, 'KBS', '노트북', '전자', 1000, 1); INSERT INTO buytbl VALUES(NULL, 'BBK', '모니터', '전자', 200, 5);
용어 용어 정리
INSERT INTO테이블에 새 행(row)을 추가하는 DML 명령
VALUES삽입할 값 목록. 컬럼 순서와 1:1 대응
NULL"값 없음" — 0이나 빈 문자열('')과 다름
DMLData Manipulation Language — INSERT/UPDATE/DELETE/SELECT

1 VALUES 순서 — 컬럼 정의 순서와 일치해야 한다

INSERT INTO usertbl VALUES(...)에서 괄호 안 값들은 CREATE TABLE 시 컬럼 정의 순서와 정확히 맞아야 한다. usertbl의 컬럼 순서는 userID → name → birthYear → addr → mobile1 → mobile2 → height → mDate이다.

-- 순서 맞춤 INSERT INTO usertbl VALUES( 'LSG', -- userID CHAR(8) '이승기', -- name VARCHAR(10) 1987, -- birthYear INT '서울', -- addr CHAR(2) '011', -- mobile1 CHAR(3) '1111111', -- mobile2 CHAR(8) 182, -- height SMALLINT '2008-8-8' -- mDate DATE );
※ 컬럼명을 직접 지정하면 순서에 관계없이 삽입 가능하다: INSERT INTO usertbl (name, userID, ...) VALUES ('이승기', 'LSG', ...). 이 방법이 실무에서는 더 안전하다.

2 NULL 전달 — 값이 없을 때

성시경(SSK)은 휴대폰이 없어서 mobile1, mobile2에 NULL을 넣었다. buytbl의 num(AUTO_INCREMENT)도 자동 생성이므로 NULL로 자리를 채운다.

위치 NULL의 의미
mobile1, mobile2 실제로 값이 없음 (휴대폰 없는 회원)
buytbl.num (AUTO_INCREMENT) DB가 자동 채워주므로 자리만 비워둠
buytbl.groupName 분류 없는 상품 (운동화 등)
※ NULL은 ''(빈 문자열)이나 0과 전혀 다르다. NULL인 컬럼을 WHERE mobile1 = NULL로 찾으면 결과가 없다. 반드시 WHERE mobile1 IS NULL을 써야 한다.

3 삽입 순서 — 부모 먼저, 자식 나중

buytbl의 userID는 usertbl의 userID를 외래키로 참조한다. 따라서 usertbl에 없는 userID를 buytbl에 삽입하면 오류가 난다. 반드시 usertbl 데이터를 모두 넣은 뒤 buytbl 데이터를 삽입해야 한다.

-- 올바른 순서 1. usertbl INSERT 완료 (KBS, BBK, ... 모두 삽입) 2. buytbl INSERT 시작 → KBS, BBK 등 참조 가능 -- 잘못된 순서 buytbl에 'ZZZ' userID INSERT → usertbl에 없는 ID → 오류!

 

반응형

 

4 컬럼 지정 INSERT — 안전한 방법
컬럼명을 명시하면 순서에 상관없이 삽입 가능

VALUES만 나열하는 방법은 컬럼 순서가 바뀌거나 컬럼이 추가되면 오류가 생길 수 있다. 컬럼명을 직접 지정하면 순서에 무관하고, 생략한 컬럼은 DEFAULT 값이나 NULL이 들어간다.

-- 컬럼 지정 방식 (권장) INSERT INTO usertbl (userID, name, birthYear, addr, height) VALUES ('LSG', '이승기', 1987, '서울', 182); -- mobile1, mobile2, mDate는 생략 → NULL 자동 저장
실무에서는 컬럼 지정 INSERT가 기본이다. 테이블 구조가 변해도 코드를 수정하지 않아도 되고, 어떤 컬럼에 어떤 값이 들어가는지 코드만 봐도 명확하다.

5 다중 행 INSERT — 한 번에 여러 레코드
VALUES (...), (...) — 여러 행을 한 번에 삽입

10명의 회원을 INSERT 10번 실행하는 것보다 VALUES 목록을 콤마로 연결하면 한 번의 SQL로 여러 행을 삽입할 수 있다. 서버와의 통신 횟수가 줄어 성능이 좋다.

INSERT INTO usertbl (userID, name, birthYear, addr, height) VALUES ('LSG', '이승기', 1987, '서울', 182), ('KBS', '김범수', 1979, '경남', 173), ('KKH', '김경호', 1971, '전남', 177); -- 3개 행이 한 번에 삽입됨

6 SELECT로 삽입된 데이터 확인

INSERT가 제대로 됐는지는 SELECT로 즉시 확인할 수 있다. 특히 NULL 컬럼, AUTO_INCREMENT 컬럼이 의도대로 저장됐는지 확인하는 습관을 들이자.

SELECT * FROM usertbl; -- 전체 회원 확인 SELECT * FROM buytbl; -- 구매 내역 확인 (num 자동 채워짐 확인) SELECT COUNT(*) FROM usertbl; -- 총 삽입된 행 수 확인
INSERT 후 SELECT COUNT(*)로 총 행 수를 확인하는 것은 데이터 정합성 체크의 기본 패턴이다. 예상한 숫자와 맞는지 비교해본다.

7 INSERT 이후 — UPDATE / DELETE 미리보기
삽입된 데이터를 수정하거나 삭제하는 다음 단계

INSERT로 데이터를 넣은 뒤, 수정은 UPDATE, 삭제는 DELETE를 사용한다. 두 명령 모두 WHERE 없이 실행하면 테이블 전체가 영향을 받으므로 반드시 WHERE로 대상 행을 지정해야 한다.

-- 수정: LSG의 키를 185로 변경 UPDATE usertbl SET height = 185 WHERE userID = 'LSG'; -- 삭제: BBK 회원 삭제 (자식 테이블 buytbl에 이 ID가 없어야 함) DELETE FROM usertbl WHERE userID = 'BBK';
UPDATE와 DELETE는 WHERE 없이 실행하면 테이블 전체가 바뀌거나 지워진다. WHERE를 먼저 SELECT로 테스트한 뒤 UPDATE/DELETE로 바꾸는 습관이 좋다.
명령 역할 주의사항
INSERT INTO 새 행 추가 컬럼 순서·타입·FK 확인
UPDATE ... SET 기존 행 수정 WHERE 없으면 전체 수정
DELETE FROM 행 삭제 WHERE 없으면 전체 삭제, FK 자식 먼저
SELECT 조회 (변경 없음) 수정 전 대상 확인 용도로 사용

8 usertbl + buytbl 완전한 데이터 세팅 스크립트
처음부터 끝까지 실행 가능한 전체 INSERT 모음

실습할 때 DB를 초기화하고 데이터를 한 번에 세팅하는 전체 스크립트다. 이 순서대로 실행하면 usertbl 10명 + buytbl 12건이 삽입된다.

USE sqldb; -- 1. usertbl 데이터 (부모 먼저) INSERT INTO usertbl VALUES ('LSG','이승기',1987,'서울','011','1111111',182,'2008-8-8'), ('KBS','김범수',1979,'경남','011','2222222',173,'2012-4-4'), ('KKH','김경호',1971,'전남','019','3333333',177,'2007-7-7'), ('BBK','바비킴',1973,'서울','010','0000000',176,'2013-5-5'), ('SSK','성시경',1979,'서울',NULL,NULL,186,'2013-12-12'); -- 2. buytbl 데이터 (자식 나중, num은 NULL → AUTO_INCREMENT) INSERT INTO buytbl VALUES (NULL,'KBS','운동화',NULL,30,2), (NULL,'KBS','노트북','전자',1000,1), (NULL,'BBK','모니터','전자',200,5), (NULL,'SSK','메모리','전자',80,10); -- 3. 확인 SELECT * FROM usertbl; SELECT * FROM buytbl;

9 INSERT INTO ... SELECT — 다른 테이블에서 복사
SELECT 결과를 바로 INSERT로 삽입

기존 테이블의 데이터를 다른 테이블로 복사할 때 INSERT INTO ... SELECT를 사용한다. VALUES 대신 SELECT 쿼리를 쓰는 방식으로, 대량 데이터 이전이나 백업 테이블 생성에 쓰인다.

-- usertbl에서 서울 회원만 seoul_members 테이블에 복사 INSERT INTO seoul_members (userID, name, height) SELECT userID, name, height FROM usertbl WHERE addr = '서울'; -- SELECT 결과가 INSERT 대상으로 직접 들어감
INSERT INTO ... SELECT는 대상 테이블(seoul_members)이 미리 만들어져 있어야 한다. 테이블 구조 복사만 할 때는 CREATE TABLE 새테이블 AS SELECT * FROM 원본테이블 패턴을 쓴다.

10 자주 하는 실수
실수 증상 해결
VALUES 값 개수가 컬럼 수와 다름 Column count doesn't match 오류 컬럼 수 == VALUES 개수 확인
문자열에 따옴표 생략 컬럼명으로 인식되어 오류 문자열은 항상 '값'
NOT NULL 컬럼에 NULL 삽입 Field 'name' doesn't have a default value NOT NULL 컬럼엔 반드시 값 제공
부모 없는 userID를 buytbl에 삽입 Cannot add or update a child row usertbl에 먼저 해당 회원 추가
CHAR(8)에 9글자 이상 삽입 Data too long 오류 타입 길이 이내로 값 조정

핵심 한 줄 요약

INSERT INTO ... VALUES컬럼 순서대로 값을 나열해 행 추가
NULL값 없음 — ''나 0과 다름, IS NULL로 비교
AUTO_INCREMENTNULL로 자리 넘기면 자동으로 +1 채워짐
삽입 순서부모(usertbl) 먼저 → 자식(buytbl) 나중
컬럼 지정 INSERTINSERT INTO tbl (col1, col2) VALUES (...) — 실무 권장
다중행 INSERTVALUES (...), (...) — 한 번에 여러 행, 성능 유리
INSERT 후 SELECTSELECT COUNT(*)로 삽입 확인 — 예상 행 수와 비교
UPDATE / DELETEWHERE 없으면 전체 영향 — 반드시 대상 WHERE 지정
INSERT INTO ... SELECTSELECT 결과를 직접 삽입 — 테이블 간 데이터 복사
완전한 boilerplateUSE sqldb → INSERT usertbl → INSERT buytbl → SELECT 확인
NULL vs 0 vs ''NULL=값 없음, 0=정수 0, ''=빈 문자열 — IS NULL로만 비교 가능
NOT NULL INSERT 생략NOT NULL 컬럼을 컬럼지정 INSERT에서 빠뜨리면 오류
다중행 INSERT 성능VALUES (a),(b),(c)는 서버와 1번 통신 → 개별 INSERT N번보다 빠름
Column count 오류컬럼 수 != VALUES 개수 → 즉시 오류 발생
Data too longCHAR(8)에 9글자 → Data too long 오류, 타입 범위 확인 필수
DML 4가지INSERT / SELECT / UPDATE / DELETE — Data Manipulation Language
INSERT 권장 패턴컬럼명 지정 + 다중행 VALUES — 명확하고 성능 유리
FK 자동 체크buytbl.userID가 usertbl에 없으면 INSERT 단계에서 DB가 자동 거절
INSERT INTO ... SELECTVALUES 대신 SELECT 결과를 삽입 — 테이블 간 데이터 복사
buytbl INSERT 흐름num=NULL → AUTO_INCREMENT 자동 채움, groupName=NULL → 허용
usertbl 먼저FK 참조 대상이 없으면 삽입 불가 → 부모 테이블 먼저 채워야
SELECT COUNT(*)총 삽입 건수 확인 — 예상 숫자와 대조하여 누락 체크
TRUNCATE테이블 전체 삭제(재시작) — DELETE * 보다 빠름, AUTO_INCREMENT 리셋
INSERT 실패 후 재시도INSERT 실패해도 AUTO_INCREMENT 번호는 소비됨 — 1,3,4 처럼 빈 번호 가능
LAST_INSERT_ID()INSERT 직후 SELECT LAST_INSERT_ID() → 방금 삽입된 AUTO_INCREMENT 값
실무 INSERT 순서① 트랜잭션 시작 ② INSERT ③ 검증 ④ COMMIT / 실패 시 ROLLBACK
SQL 문자열 이스케이프값 안에 작은따옴표 → \'로 이스케이프 또는 '' (두 번 쓰기)
INSERT 후 확인 패턴INSERT → SELECT COUNT(*) → 예상 행 수 비교 → SELECT * 샘플 확인
usertbl 회원 10명LSG/KBS/KKH/JYP/SSK/LJB/YJS/EJW/JKW/BBK — 실습 기준 데이터셋
buytbl 12건KBS 3건, BBK 3건, EJW 3건, JYP/SSK/KBS 각 1건 — FK usertbl 참조
VALUES(...) 콤마다중행 INSERT에서 마지막 괄호 다음에 콤마 없음 — ; 로 끝냄
NOT NULL 빈 문자열NOT NULL이어도 '' 빈 문자열은 허용됨 — ''와 NULL은 다름
INSERT 트랜잭션BEGIN → INSERT × N → COMMIT 패턴으로 원자성 보장 (나중에 배움)
DDL vs DMLCREATE/DROP=DDL(구조), INSERT/SELECT/UPDATE/DELETE=DML(데이터)

Tags

#MySQL #INSERT INTO #VALUES #NULL #데이터삽입 #AUTO_INCREMENT #외래키삽입 #SQL DML #웹개발 #티스토리
▼ 티스토리 태그 입력란 복사용
MySQL, INSERT INTO, VALUES, NULL, 데이터삽입, AUTO_INCREMENT, 외래키삽입, SQL DML, 웹개발, 티스토리
반응형

댓글