주제 1 / 7
혼자 쓸 땐 문제없었다
토요일 밤
토요일 밤, 민지는 스터디원 넷이 같이 쓸 할 일 보드가 필요했어요. 코딩은 거의 몰라서 AI 코딩 도구를 열고 이렇게만 적었어요.
10분쯤 지나 앱이 나왔어요. 할 일을 적으면 목록에 붙고, 체크하면 줄이 그어지고, 새로고침해도 그대로였어요. 아래가 민지가 받은 앱이에요. 한번 써 보세요.
그 뒤 며칠 동안
민지는 링크를 단톡방에 올려 두고 잤어요. 그 뒤로 며칠 동안 이런 메시지가 왔어요.
민지가 혼자 써 볼 때는 문제가 하나도 없었어요. 문제는 전부 다른 사람이 들어오거나 하루가 지난 뒤에 생겼어요. 혼자 하는 테스트로는 찾기 어려운 문제들이에요.
주제 2 / 7
화면은 창문이에요
"나는 다 보이는데"
민지는 이해가 안 됐어요. 자기 화면에는 할 일이 그대로 있었거든요.
앱 화면과 데이터는 따로 있어요. 화면은 창문이고, 데이터는 창문 너머 어딘가에 있는 집에 살아요. 앱을 열면 창문 너머 그 집 안이 보이는 거예요.
민지와 준호는 똑같이 생긴 창문을 보고 있었지만, 각자 다른 집을 들여다보고 있었어요. 그래서 보이는 게 달랐어요.
같은 앱을 열었다고 같은 데이터를 보는 건 아니에요. 같은 집을 봐야 같은 데이터가 보여요.
데이터가 사는 세 곳
AI가 만든 앱에서 데이터가 사는 곳은 대개 셋 중 하나예요. 위쪽 탭으로 바꿔 가면서 버튼을 눌러 보세요. 처음이라면 "처음부터 보기"를 누르면 순서대로 보여 줘요.
- 휴대폰 서랍(localStorage): 각자 휴대폰 안에 있어요. 준호는 민지의 서랍을 열 수 없어요. 준호 화면이 비어 있던 이유예요.
- 서버 화이트보드(서버 메모리): 모두 같은 보드를 보지만, 서버가 다시 켜지면 지워져요. 서버는 배포할 때마다 다시 켜지고요. 서연이 쓴 게 사라진 이유예요.
- 창고(데이터베이스): 서버 밖에 따로 있어요. 서버가 몇 번을 다시 켜져도 남아 있고, 모두가 같은 창고를 봐요.
AI는 왜 서랍을 골랐을까
AI가 잘못한 걸까요? 민지가 보낸 요청을 다시 보면 조금 다르게 보여요.
데이터를 어디에 둘지, 누가 볼지, 둘이 동시에 쓰면 어떻게 할지는 요청에 없어요. 요청에 없는 부분은 AI가 정해요. 그리고 보통 가장 간단한 쪽을 골라요. 가장 간단한 쪽은 대개 혼자 쓸 때 잘 되는 방법이에요.
| 요청에 없던 것 | AI가 정한 것 | 그 결과 |
|---|---|---|
| 데이터를 어디에 둘지 | 각자 휴대폰 서랍 | "아무것도 안 뜨는데?" |
| 서버가 다시 켜지면 | 정하지 않음 | "어제 적은 거 다 없어졌어" |
| 둘이 동시에 쓰면 | 정하지 않음 | "서연 것만 남음" |
| 누구 것인지 | 정하지 않음 | "내 거만 볼 수 있음?" |
| 누가 지울 수 있는지 | 정하지 않음 | "준호 거 지워짐" |
결과가 이상할 때는 AI가 대신 정한 부분부터 찾아보세요. 이 강의는 그 부분을 하나씩 짚어 가요.
주제 3 / 7
저장만 하면 될까
"파일에 적어 두면 되잖아"
데이터를 서버 밖에 오래 둬야 한다는 건 알았어요. 민지는 파일에 저장하면 되지 않을까 생각했어요. AI가 만든 코드는 이런 식이었어요.
const todos = readFile('todos.json'); // 파일을 전부 읽고
todos.push(newTodo); // 하나 붙이고
writeFile('todos.json', todos); // 전부 다시 쓴다혼자 쓸 때는 잘 돼요. 두 사람이 거의 같은 때 추가하면 어떻게 되는지 다음 절에서 볼게요.
같은 순간, 두 사람
시간 순서대로 재생돼요. 빠르면 "한 단계씩"으로 넘겨 보세요. 서연이 파일을 읽은 때와 저장한 때 사이를 잘 보세요.
서연은 준호가 저장하기 전에 읽은 목록을 들고 있었어요. 그 목록으로 파일을 덮어쓰면서 준호가 추가한 게 지워졌어요.
창고로 바꿔서 다시 재생해 보면, 두 사람 다 목록 전체를 다루지 않아요. 추가할 한 줄만 보내요. 그래서 겹쳐도 둘 다 남아요.
이런 문제는 사용자가 많아질수록 자주 생기고, 혼자서는 다시 일으키기도 어려워요.
관리인이 있는 창고
지금까지 본 걸 정리해 볼게요. 서랍도, 화이트보드도, 파일도 저장은 돼요. 문제는 여럿이 오래 같이 쓸 때 생겼어요.
데이터베이스는 이 부분을 맡아 주는 프로그램이에요. 창고에 비유하면, 물건만 쌓아 두는 곳이 아니라 관리인이 있는 창고예요. 관리인은 이런 걸 챙겨 줘요.
- 모두에게 같은 내용민지와 준호가 같은 할 일을 봐요.
- 꺼져도 그대로서버를 다시 켜도 어제 것이 남아 있어요.
- 동시에 써도 안전거의 같은 때 추가해도 둘 다 남아요.
- 많아져도 빠르게할 일이 수천 개여도 "내 것만"을 금방 찾아요.
- 정해진 사람만남의 할 일은 고치거나 지울 수 없게 막아요.
이런 관리를 직접 만들려면 손이 아주 많이 가요. 그래서 오래 쓰여 온 데이터베이스를 가져다 써요. PostgreSQL, MySQL, SQLite가 대표적이고, 바이브코딩에서 많이 쓰는 Supabase는 PostgreSQL을 쓰기 쉽게 만든 서비스예요.
그렇지 않아요. 다크 모드 설정처럼 나만 쓰고, 없어져도 괜찮은 정보에는 잘 맞아요. 여럿이 같이 보거나 잃어버리면 안 되는 데이터라면 데이터베이스에 두세요.
주제 4 / 7
창고 안은 표예요
할 일 한 줄은 표의 한 줄
창고 안에서 데이터는 표로 정리돼 있어요. 이 표를 테이블이라고 불러요. 왼쪽 앱과 오른쪽 표를 같이 보세요.
앱의 할 일 하나가 표의 한 줄(행)이고, 번호·담당자·제목·완료 여부가 각각 한 칸(열)이에요. 체크박스를 누르면 그 줄의 done 칸만 바뀌어요.
표 머리에 적힌 int8, text, bool은 그 칸에 들어갈 값의 종류(타입)예요. done 칸에는 true나 false만 들어가요. 엑셀처럼 아무 글자나 넣을 수는 없어요.
이름이 같은 할 일 두 개
보드에 "자료 조사하기"가 두 개 있어요. 하나는 1주차에 끝낸 것, 하나는 2주차에 할 것이에요. 민지가 2주차 것을 지우려고 해요.
앱이 "제목이 자료 조사하기인 걸 지워 줘"라고 요청하면 어떻게 되는지 해 보세요.
그래서 줄마다 겹치지 않는 번호를 붙여 둬요. 이 칸을 기본 키라고 하고, 보통 id라는 이름을 써요. 새 줄이 생길 때마다 데이터베이스가 번호를 알아서 붙여요.
AI가 만든 코드가 이름이나 제목으로 데이터를 찾아서 고치거나 지우고 있다면 한번 확인해 보세요.
이건 누구 거예요?
준호가 자기 할 일만 보고 싶다고 했어요. 그러려면 할 일마다 누구 것인지가 적혀 있어야 해요.
할 일마다 "준호"라고 이름을 적어도 되지만, 준호가 이름을 바꾸면 할 일을 전부 고쳐야 해요. 그래서 사람 정보는 users 표에 따로 두고, 할 일에는 사람 번호만 적어요. 그 칸이 user_id예요. 이렇게 다른 표의 번호를 가리키는 칸을 외래 키라고 해요.
"내 할 일만 보기"는 결국 WHERE user_id = 내 번호라는 조건 하나예요.
주제 5 / 7
버튼 하나에 문장 하나
버튼 뒤에서 오가는 문장
앱에서 버튼을 누를 때마다 앱은 데이터베이스에 짧은 문장을 보내요. 이 문장을 쓰는 언어가 SQL이에요.
아래 앱을 써 보면 오른쪽 로그에 실제로 보내는 문장이 쌓여요. 다 써 봤으면 아래 스위치를 켜고 "완료한 일 비우기"를 눌러 보세요. AI가 조건을 빼먹었을 때의 모습이에요.
| 앱에서 | 보내는 문장 |
|---|---|
| 할 일 추가 | INSERT 새 줄을 넣어요 |
| 보드 열기 | SELECT 줄을 읽어 와요 |
| 체크하기 | UPDATE 줄의 칸을 바꿔요 |
| 지우기 | DELETE 줄을 지워요 |
SQL을 직접 쓸 일은 많지 않아도, 읽을 수 있으면 AI가 만든 코드를 검토할 수 있어요. UPDATE나 DELETE가 보이면 WHERE가 붙어 있는지 먼저 보세요.
주제 6 / 7
열쇠는 서버에
브라우저 코드는 모두에게 보여요
서연이 준호의 할 일을 지울 수 있었던 이유가 남았어요.
데이터베이스에 접속하려면 주소와 비밀번호가 필요해요. AI가 이걸 어디에 넣어 뒀는지 준호의 브라우저에서 열어 볼게요.
브라우저에서 돌아가는 코드는 앱을 연 사람 모두에게 그대로 전달돼요. 그래서 비밀번호는 서버의 .env 파일에 두고, 브라우저는 서버를 거쳐서만 데이터를 받게 해요.
공개 키를 쓴다면 규칙부터
Supabase처럼 브라우저에서 데이터베이스를 바로 부르는 경우도 있어요. 이때 쓰는 공개 키(anon key)는 노출돼도 괜찮게 만들어져 있어요.
대신 누가 어떤 줄을 볼 수 있는지 규칙을 정해 둬야 해요. 이 규칙을 행 수준 보안(RLS)이라고 해요.
Supabase 대시보드에서 테이블마다 RLS가 켜져 있는지 보세요. 테이블을 만든 방법에 따라 꺼져 있을 수 있어요.
주제 7 / 7
다시 AI에게
비어 있던 자리를 채운 요청
처음 요청에서 비어 있던 자리를 이제 채울 수 있어요. 넣을 내용을 고르고 보내 보세요. 아무것도 고르지 않았을 때와 AI의 답이 어떻게 다른지 보세요.
다시, 단톡방
일주일 뒤 민지는 앱을 다시 만들었어요.
정리
- 혼자 써 볼 때 문제가 없다고 해서 다른 사람이 써도 괜찮은 건 아니에요.
- 화면은 데이터를 보여 주는 창문이고, 데이터는 다른 곳에 있어요.
- 요청에 없는 부분은 AI가 정해요. 보통 가장 간단한 방법으로요.
- 데이터베이스는 여럿이 오래 같이 써도 데이터가 망가지지 않게 관리해 줘요.
- SQL을 읽을 수 있으면 AI가 만든 코드를 검토할 수 있어요.
다음 강의에서는 남은 질문을 다뤄요. 서버는 요청을 보낸 사람이 준호라는 걸 어떻게 알까요? 쿠키와 세션 이야기예요.
Quiz
데이터베이스 확인 문제
준호도 볼 수 있고, 서버를 다시 배포해도 할 일이 남는 곳은?
답을 고르고 확인을 눌러 주세요.
준호와 서연이 거의 같은 때 파일에 할 일을 추가했는데 서연 것만 남았다. 왜 그럴까?
답을 고르고 확인을 눌러 주세요.
제목이 같은 할 일 두 개 중 하나만 정확히 지우려면 무엇으로 찾아야 할까?
답을 고르고 확인을 눌러 주세요.
로그인한 준호(users의 id가 2)의 할 일만 보여 주는 조건은?
답을 고르고 확인을 눌러 주세요.
"완료한 일 비우기" 버튼이 DELETE FROM todos;를 보낸다면?
답을 고르고 확인을 눌러 주세요.
데이터베이스 비밀번호를 브라우저에서 실행되는 코드에 넣어도 괜찮다.
답을 고르고 확인을 눌러 주세요.