강좌 안내

SQL이 실행됐다면, 답도 맞을까? PolyU DSAI2202 데이터베이스 원리 수업으로

순조롭게 생성된 명단이 정작 가장 먼저 보여야 할 사람을 빠뜨릴 수 있다. 테이블 사이의 관계에서부터 데이터를 수정할 때의 경계까지, DSAI2202는 SQL을 이해하고 검증하는 학습 경로를 제시하며 "AI에게 쿼리 작성을 부탁한다"는 일에 한 단계 더 깊은 질문을 덧붙이게 한다.

EvoClass 읽는 시간 8분
개념 일러스트: 학습자가 선으로 연결된 두 장의 학생 기록표를 대조하며, 결과에서 빠진 한 행을 빨간 펜으로 동그라미 치고, 옆에는 매칭되지 않은 학생 카드가 놓여 있다.

수업 장면을 하나 상상해 보자. 아직 과제를 제출하지 않은 학생을 찾고 싶어서 AI에게 부탁해 SQL 한 줄을 받았다. 프로그램은 순조롭게 실행됐고, 화면에는 가지런한 명단이 나타났다.

오류도 없었고 컬럼 이름도 맞았다. 그런데 알림을 보내려는 순간, 제출 기록이 아예 없는 한 학생이 결과에 보이지 않는다는 것을 발견한다.

문제는 조인 방식에 숨어 있을 수 있다. 이 쿼리는 두 테이블에서 서로 일치하는 레코드만 남겼고, "아직 기록이 없는 사람"은 처음부터 제외된 것이다.

이런 오류는 조용하다. 데이터베이스는 당신이 적은 대로 동작을 끝냈다. 정말로 점검해야 할 것은, 그 동작이 당신이 원래 의도한 뜻을 담고 있는가이다.

홍콩이공대학(PolyU) DSAI2202 《Database Principles》(데이터베이스 원리)는 데이터 모델링, SQL, 트랜잭션 관리, 데이터베이스 보안 등을 다룬다. "결과에서 왜 한 사람이 빠졌을까"라는 질문을 안고 수업에 들어가면, 추상적인 개념에도 추적해 볼 단서가 생긴다. PolyU 공식 강의 설명

명단에 그가 없는 건, 기록이 없어서인가, 사람이 없어서인가?

먼저 서두의 예시를 더 작게 줄여 보자.

학생 테이블에는 세 사람이 있다. 아밍, 샤오신, 아지에다. 제출 테이블에는 아밍과 샤오신의 기록만 있고, 아지에는 아직 제출하지 않았다.

먼저 내부 조인으로 두 테이블을 이어 붙인 다음 "제출하지 않은" 학생을 찾는다면, 아지에는 이미 중간 결과에 없다. 이후의 필터링이 아무리 꼼꼼해도, 앞서 배제된 사람을 되찾아올 수는 없다.

한 가지 접근은 완전한 학생 명단에서 출발해 모든 학생을 남겨 두고, 대응하는 제출 기록이 존재하는지 확인하는 것이다. 왼쪽 조인은 이런 관계를 표현하는 데 도움을 주지만, 과제 범위와 매칭 필드, 이후의 필터 조건까지 계속 확인해야 한다. 조인 키워드를 바꾼다고 해서 정답이 자동으로 보장되지는 않는다. PostgreSQL 공식 조인 튜토리얼

EvoClass의 Lab 7: 관계 간 추론에서는 학습자가 학생 등록 명단과 학습 플랫폼 명단을 대조하며, 서로 다른 조인 방식이 레코드를 어떻게 남기고 배제하는지 관찰한다.

여기서 연습할 만한 것은 쿼리를 쓰기 전에 먼저 분명히 말해 보는 일이다. 결과의 한 행은 누구를 나타내는가? 누구는 반드시 남아 있어야 하는가? 일치하는 기록을 찾지 못했을 때 그것은 무엇을 의미하는가?

이 몇 문장이 있어야 SQL에도 대조해 볼 목표가 생긴다.

쿼리 이전에, 세계를 어떻게 기록할지 먼저 정한다

이 명단을 계속 들여다보자. 한 학생이 여러 과목을 수강할 수 있고, 한 과목에 여러 번의 과제가 있을 수 있으며, 각 과제는 여러 번의 제출을 허용할 수도 있다.

이 모든 것을 하나의 큰 테이블에 밀어 넣으면 이름, 과목명, 교수 정보가 반복해서 나타날 수 있다. 한 곳을 고쳐도 다른 곳에는 옛 값이 남아 있고, 학생 수를 셀 때 같은 사람이 여러 번 집계될 수도 있다.

이때 문제는 이미 쿼리 이전에 발생한 것이다. 테이블의 각 행은 도대체 무엇을 기록하고 있는가?

Lab 2: 현실 세계에서 PostgreSQL 데이터 테이블로는 평면 테이블의 중복과 갱신 문제에서 출발해 관계형 데이터베이스 설계로 들어가고, Lab 9: 신청서 정규화는 정규화로 한 걸음 더 나아간다.

종이와 펜으로 작은 연습을 해 볼 수 있다. "학생", "과목", "수강 관계"를 각각 세 장의 종이에 적고, 그것들이 어떻게 연결되는지 설명해 보자. 한 학생이 전공을 바꾸면 어디를 고쳐야 하는가? 아무도 선택하지 않은 새 과목도 먼저 기록해 둘 수 있는가?

이런 질문들이 데이터 구조를 일상적인 변화 앞에서 시험하게 만든다. 테이블을 나눈 것이 적절한지는 관계를 명확히 표현하고, 수정할 때 일관성을 유지할 수 있는지로 판가름된다.

서두의 쿼리로 돌아오면 판단도 더 쉬워진다. 눈앞에 늘어난 몇 개의 행은 서로 다른 몇 명의 학생인가, 아니면 같은 학생의 여러 번의 제출인가?

한 문장이 맞아도, 전체 작업은 절반만 끝날 수 있다

결과를 조회한 뒤에는 시스템이 데이터를 수정해야 하는 경우가 많다.

예를 들어 한 학생이 반 변경을 신청해 원래 반에서 빠지고 새 반에 들어가야 한다고 하자. 첫 단계는 이미 저장됐는데 두 번째 단계가 어떤 이유로 실패하면, 그 학생은 잠시 어느 반에도 속하지 않게 될 수 있다. 두 문장을 따로 보면 둘 다 올바르게 작성됐을 수 있다. 그러나 합쳐서 보면 시스템에는 불완전한 상태가 남는다.

트랜잭션은 이런 문제에 기본 도구를 제공한다. 함께 완료되어야 하는 단계들을 묶어 하나의 전체로 커밋하거나, 실패하면 되돌리게 한다. 이 "전체"를 어떻게 정할지는 여전히 구체적인 작업을 이해해야 한다. PostgreSQL 공식 트랜잭션 튜토리얼

Lab 10의 트랜잭션과 동시성 실험은 주제를 트랜잭션 경계와 동시성 제어로 확장한다. 수강 신청 데스크의 정원 처리 상황을 배경으로, 두 세션이 동시에 조작할 때 무슨 일이 일어나는지 관찰한다.

연습할 때는 두 단계 작업 사이에 일부러 한 번 실패를 만들어 보고, 데이터베이스에 실제로 무엇이 남았는지 확인할 수 있다. 이어서 두 세션이 같은 데이터를 동시에 조작하게 하고, 원래 순조롭던 단계가 여전히 성립하는지 관찰해 보자.

하나의 실험에 이렇게 한 겹의 의미가 더해진다. 일이 어떻게 성공하는지만 보는 것이 아니라, 그것이 어떻게 실패하는지도 알아야 한다.

AI에게 SQL을 부탁한 뒤, 내가 책임져야 할 검증은 무엇인가?

앞선 경험을 거치고 나면 AI가 준 쿼리를 볼 때 관심의 초점이 달라진다.

서두에서 사람을 빠뜨린 명단은 가상의 학생 레코드 세 개로 점검해 볼 수 있다. 중복 집계 문제는 제출이 두 번 있는 학생을 추가해 다시 점검할 수 있고, 반 변경 작업은 중간에 실패했을 때의 데이터 상태를 점검할 수 있다.

이런 작은 예시들이 판단의 근거가 된다. 매끄러운 설명이 결과 확인을 대신할 수는 없다.

Lab 12: AI가 생성한 SQL 검증하기는 검토를 연습에 포함한다. 실행되는가? 질문에 답했는가? 무엇을 망가뜨릴 수 있는가? 누가 이것을 실행할 권한이 있는가?

학습자는 하나의 구체적인 작업을 따라 단계적으로 질문해 나갈 수 있다. 이 쿼리는 어떤 레코드를 남기는가? 수정은 몇 개의 행에 영향을 주는가? 한 사람만 바꿀 것으로 예상했다면, 실행 전에 범위를 잘못 적은 것을 어떻게 발견할 수 있는가? 도구에 수정 권한이 있다는 것이 현재 작업에 그렇게 해도 된다는 뜻인가?

관계형 데이터베이스를 이제 막 접하고 있거나, 이미 AI의 도움을 받아 쿼리를 쓰기 시작한 사람에게 EvoClass의 DSAI2202 강좌 입구는 기초 조작에서 더 깊이 들어가는 경로를 제공한다. 먼저 직접 손으로 확인할 수 있는 작은 데이터 묶음을 준비하고, 예상 결과를 가지고 연습에 들어가면 좋다.

다음번에 화면에 가지런한 명단이 나타나면, 가장 쉽게 빠질 수 있는 그 사람을 먼저 찾아보자.

그가 왜 나타났고 왜 빠졌는지 설명할 수 있을 때, 비로소 이 답을 믿을 만한지 알기 시작한다.


강좌定位은 PolyU 공식 강의 설명을 근거로 하며, 실습 소개는 EvoClass의 현재 강의 자료를 근거로 한다. 본문의 차시 링크는 중국어 간체 학습 자료를 가리킨다. 명단, 과제 제출, 반 변경 상황은 모두 개념 이해를 돕기 위해 구성한 교육적 예시이며, 실제 학생 사례나 사용 효과 기록이 아니다.