표준 SQL 및 데이터베이스 입문
표준 SQL과 데이터 설계를 기반으로 SQL과 데이터베이스에 대한 기본 지식을 배우는 입문 강좌입니다.
"SQL로 어떤 일을 할 수 있을까?"
"어떤 경우에 SQL을 알면 편리한가?"
"왜 그런 데이터구조가 되어 있는가?"
이 강좌의 특징은 표준SQL 기준으로 문법의 배경에 있는 데이터설계를 설명합니다. 필자가 몇년전에 프로그래밍 경험이 없는 학생들들을 가르칠 때 사용했던 자체적으로 만들었던 교재로 SQL을 가르치기위해 사용했던 것으로 2년정도 지난 시점에서 대폭 업그레이드해서 SQL을 공부할 때 생각대로 조작할 수 없었던 학생들을 생각해서 표준 SQL과 데이터 설계에 대한 밑바탕을 조금이라도 이해할 수 있도록 설명한 자료를 공개합니다.
동작확인한 환경은 다양한 독자를 고려하여 학습에 접근하기 쉬운 PostgreSQL, MariaDB, MySQL로 무료로 사용할 수 있는 제품을 기준으로 작성했습니다.
MySQL 8.0.36 이상
MariaDB 11.3.0 이상
PostgreSQL 16.5.0 이상
샘플 데이터베이스 및 테스트용 사용자를 작성하는 방법은 따로 설명합니다.
testdb.sql: 1장용 샘플데이터(학생데이터, 선택한 과목)
examdb.sql: 2-7장용 샘플데이터 (학원 데이터 등)
examdb2.sql: 7장용 샘플데이터 (학원 데이터 등)
관련 리파지토리 URL: https://github.com/zer0cero/DB-study
가상의 길동학원의 시스템을 재검토한다는 가정하에 스토리를 기준으로 강좌를 진행해 봅니다.
길동학원에서 이전 시스템 개발을 맡긴 개발사이트에 다시 재검토해달라고 요청이 왔습니다. 현재 학생출석관리는 전용 출석관리 시스템을 도입해서 운영중인데 성적 관리등 다른 여러 시스템들이 따로따로 되어 있어서 우선 그 데이터를 통합해서 관리하고 싶어한다는 것을 알게 되었습니다. 이런 경우 보통 발주사가 처음에는 수작업으로도 가능했지만, 데이터가 점점 늘어나면서 관리하기 어려워졌을 것입니다.
그래서 데이터베이스(Database)를 사용하면 해결될 것 같다라는 결론이 도출되었고, 데이터를 제대로 관리하려면 데이터베이스가 필수라는 것을 밝히고 개발사이트가 그런 분야에서는 전문이라고 소개하였습니다.
학원 시스템 담당자가 한가지 질문을 했습니다.
시스템담당자: "데이터베이스에 대해 공부해보려고 하는데 어디서부터 해야할지 감이 안오더군요. 데이터를 표형식으로 관리한다고 해서 엑셀같은 거라고 생각했는데 막상 SQL이라는 용어가 나오는데 이 SQL이 뭘까요?"
Zer0: "SQL은 Structured Query Language의 약어로 데이터베이스를 생성, 수정, 조회, 삭제하는 등 다양한 조작을 수행할 수 있도록 도와주는 언어이다"
시스템담당자: "데이터베이스 전용 언어라? 그럼 프로그래밍 언어와는 다른 것인가? 고등학교 때 JavaScript를 배우고 엑셀 VBA정도를 써봤는데?"
Zer0: "그건 조금 다른 것입니다. 우선 SQL이 어떤 것이지 한번 알아볼까요?"
실제로 예제를 보면서 이해하면 빠르기에 학생의 기본정보를 저장할 용도로 "학생 마스터"라는 테이블을 만들어 보았습니다. 아래 그림처럼 '학생번호', '이름'을 포함했고, 학원 지점은 서초구, 종로구, 강남구 지점이 있으니까 '캠퍼스'항목도 추가합니다.
테이블
학생마스터에는 학생번호, 성명, 캠퍼스 정보를 입력하여 관리하는 것입니다. 참고로 캠퍼스가 더 늘어날수도 있다는 것입니다. 이런 경우, 데이터가 늘어나고 있기 때문에 데이터베이스는 큰 도움이 될 것입니다. 이해가 쉽도록 몇개의 데이터를 등록해두고 이 데이터를 바탕으로 SQL을 작성해 봅시다. 앞으로 작성할 SQL문은 가장 기본이 되는 'SELECT문'이라고 말합니다.
SQL로 '학생마스터' 테이블에서 데이터를 조회하려면 아래와 같이 작성합니다. 아래 ① 예제는 '학생마스터' 중 서초구 캠퍼스에 다니고 있는 학생의 학생번호와 이름을 조회하기 위한 SQL문입니다. 아래 SELECT문은 샘플데이터인 testdb에서 실행할 수 있습니다.
① 예제
② 예제는 '학생마스터' 테이블의 모든 행과 모든 항목을 조회하기 위한 SQL문입니다.
② 예제
① 예제의 문장을 읽어보면, '학생마스터'이 테이블명이고, '학생번호', '이름'이 항목입니다. 이는 SELECT 뒤에 원하는 항목명을 쓰고, FROM 뒤에 테이블명을 쓰게 됩니다. '학생마스터'는 학생의 기본정보를 저장하는 테이블입니다. 마스터에는 목록이나 원장이라는 의미가 있어서 이런 데이터를 'XX마스터'라고 부르는 경우가 많은데 이름은 기본적으로 자유롭게 정할 수 있습니다.
WHERE 뒤에 "캠퍼스 = '서초구''라는 것은 여기서 조건을 지정하는 것입니다. 캠퍼스가 서초구와 일치하는 것을 지정했기 때문에 이 쿼리는 서초구 캠퍼스 학생의 학생번화와 이름을 표시하게 됩니다.
②은 무엇인가 짧게 작성되어 있습니다. 우선 SELECT 뒤에 '*' 한글자만 있는데 이것은 모든 열을 지정한다는 것으로 WHERE절도 없습니다. 결과는 학생마스터의 모든 데이터가 표시되기 떄문에 결과를 한번 실제 실행해 보시기 바랍니다.
①번과 ②번을 실행하면 각각 아래와 같은 결과가 나오게 됩니다.
다음은 "선택과목"이라는 테이블을 만듭니다. 그런데 이번에는 마스터 테이블이 아니죠?
이 테이블은 어떤 학생이 어떤 과목을 선택했는지 데이터를 등록하기 위한 테이블이라 "선택과목"이라는 이름을 사용합니다. 일단 "국어", "수학", "영어"의 3종류 과목을 자유롭게 선택할 수 있습니다. 어떤 학생은 한과목만듣고, 어떤 학생은 3과목 모두 듣기도 합니다. 또한 실제로는 각 과목별 난이도에 따라 다른 과목이 있을 수 있습니다. 지금은 간단하게 3종류만 다룹시다. 나중에 과목을 추가할 수 있습니다.
그리고 "선택과목" 테이블의 전체 데이터를 조회하고 싶다면, "SELECT * FROM 선택과목"이라고 작성해서 실행하면 됩니다.
아래에서는 "선택과목" 테이블의 모든 데이터를 조회하는 SELECT문ㅇ의 실행결과를 살펴봅시다.
그런데, 이번에는 학생번호와 과목만 나오네요. 학생 이름은 표시가 안됩니다. 여기서 중요한 포인트로서 학생 이름은 '학생마스터' 테이블에 저장되어 있기 때문에 '선택과목'테이블은 이대로 나오는 것뿐입니다. SQL에서는 이런 경우 여러 테이블을 결합하여 데이터를 표시하는 것입니다. 우선 SELECT문을 작성해 봅시다.
실행결과는 아래와 같이 나옵니다. 테이블에 저장된 데이터는 2차원 표형식으로 표현할 수 있지만, 여러개의 테이블을 결합한 결과 역시 2차원 표형태로 나타납니다.
작성해야할 내용이 갑자기 늘어난 형태입니다. 우선 SELECT에서 지정하는 열은 처음 본 SELECT문에서는 '학생번호'라고 지정되어 있었는데, 이번에는 '선택과목.학생번호'로 바뀌었습니다. 다음은 '이름'은 학생마스터에 있는 열명이고, '과목'은 선택과목에 있는 열명입니다. 그리고 FROM절 뒤에는 '선택과목'으로 지정되어 있고, JOIN뒤에는 이름을 가져오기 위해 학생마스터를 참조하는 것입니다.
학상번호는 선택과목과 학생마스터 두 테이블 모두에 들어있기 때문에, SELECT에서 '선택과목 테이블의 학생번호가 필요하다' 는 의미로 '선택과목.학생번호'라고 지정한 것입니다. 단, ON절 다음에 '선택과목.학생번호 = 학생마스터.학생번호'로 선택과목의 학생번호와 학생마스터의 학생번호를 일치시키라는 조건을 명시하고 있으므로, SELECT에서 '학생마스터.학생번호'라고 지정해도 결과는 동일합니다. '이름'은 학생마스터에만 '과목'은 선택과목'에만 있으므로 테이블명을 따로 지정하지 않았습니다.
ON 이후 '학생번호가 일치하는 것'이라는 조건을 지정하고 있는 것입니다. 엑셀의 VLOOKUP함수와 비슷한 작업을 하는 것일까요? 엑셀에서는 같은 작업을 하려면 VLOOKUP이나 XLOOKUP함수를 사용하게 됩니다. 하지만, SQL에서는 한건씩 찾아보는(lookup) 것이 아니라, 두 테이블을 결합하여 만든 표를 조회하는 작업이 되는 것입니다. 이런 작업을 JOIN(결합)이라고 부르는 것입니다. 이렇게 해서 학생번호와 이름, 과목을 표시할 수 있게 되는 것입니다.
이전 선택과목 목록은 동일한 학생번호가 여러 번 표시되어서 보기가 좀 애매했습니다. 국어, 영어, 수학이라는 열 기준으로 한줄에 표시되게 만들고 싶지 않습니까?
그렇게 되면 목록이 더 보기 편할 수 있을 것 같습니다. 그러면 아까 설명했던 '학생마스터'와 '선택과목'을 이용해서 필자가 말한 기준으로 과목을 가로로 나열한 표를 만들어 봅시다. 이런 SELECT문 작성방식은 나중에 자세히 설명하겠지만 우선 맛배기로 알아둡시다.
이전에는 '학생마스터'와 '선택과목' 테이블을 사용하여 아래 표를 만드는 것도 가능합니다. 여기에서는 각 학생이 선택한 과목의 열에 '선택'이라는 문자열을 표시해 봅시다.
이 표스를 생성하는 SELECT문은 아래와 같습니다. SQL에서는 이번 데이터의 경우, 분기를 처리하기 위해 사용한 CASE식 외에도, 집계나 정렬등 다양한 작업을 수행할 수 있도록 되어 있습니다. 이에 대해서는 나중에 따로 깊게 다룹니다.
SELECT 뒤 '학생번호'와 '이름'까지는 이전과 동일하고 이후 국어 열을 만드는 부분이 두번쨰 줄부터 시작됩니다. 여기부터는 여러가지 방법이 있지만, 이 방식으로 작성하면 CASE문을 보면 대략적으로 파악할 수 있습니다.
그러면 2행의 CASE부터 3줄을 살펴봅시다. 괄호 안의 SELECT문은 지금까지 본 SELECT문과 동일합니다. 여기서는 '학생번호'를 조회하며, '선택과목'테이블에서 과목가 '국어'와 일치하는 데이터를지정합니다. 그러면 괄호 안에는 '국어를 선택한 학생들의 학생번호 목록에 포함되어 있으며, '국어'열에 '선택'이라는 문자열을 표시하는 작업이 실행됩니다. 영어와 수학도 동일한 작업이 진행되고 있습니다.
살짝만 이해해도 상관없으며, 우선은 이런 식으로 표도 만들 수 있다는 것만 이해하고 있으면 됩니다. 즉 SQL을 사용하면 이렇게 원하는 데이터를 여러 가지 형태로 조회할 수 있습니다. 그래서 '어떤 데이터를 관리할 것인가'와 '어떻게 데이터를 표시할 것인가'를 따로 고려할 수 있다는 것입니다.
SQL에서는 이번 데이터의 경우, 분기를 처리하기 위해 사용한 CASE식외에도, 집계나 정렬등의 여러가지 작업을 수행할 수 있습니다.
그런데 혹시 "학생번호와 이름은 한세트인데 '선택과목' 테이블에도 넣어두면 좋을 것같은데, 그렇게하면 문제가 있을까"라고 생각하지 않았습니까? 보통 모든 데이터에 이름을 넣어두면 좋지 않을까라고 생각하며, 등록할 때 복사해서 넣으면 될거라고 생각합니다. 그런데 등록시 변경사항이 생기면 어떻게 될까요? 예를 들어 이름이 바뀌면 모든 데이터를 일일이 수정해야 되지 않을까요? 상당히 번거롭게 되겠지요. 만약, 변경 누락이나 입력 실수로 '이철순' 중 한건만 '이칠순'이라고 잘못 기록하면 어떻게 될까요? 동일한 내용이 여기저기 저장되어 있어서 그때마다 모두 확인해야 하는 상황이 나오게 될 것입니다.
전체 데이터 건수가 적다면 매번 확인해도 무난하지만, 그래도 이건 불필요한 번거로움입니다. 데이터를 신뢰할 수 있는 상태로 유지하려면 '한가지 사실은 한번만 기록'하는 것이 중요하다는 것입니다. SQL은 언제든지 여러개의 테이블을 결합하여 원하는 데이터를 표시할 수 있기 때문에 꼭 필요한 정보는 한번만 기록하는 것이 중요합니다.
관계형 데이터베이스에서는 '학생마스터'와 '선택과목'처럼 데이터를 여러 테이블로 분할하여 저장하고 관리합니다. 그리고 '학생마스터'에 등록되는 학생번호는 중복되면 안되고, 또는 '선택과목' 테이블에 등록된 학생번호는 반드시 '학생마스터'에 등록되어 있어야 한다는 규칙을 설정합니다. 이렇게 하여, 데이터를 올바른 상태로 유지하기 쉬울뿐만 아니라, 유연하게 데이터를 조회할 수 있게 됩니다.
"한가지 사실은 한번만 기록"
이해가 되셨는지요? 이름을 가져오는 것은 간단했기 때문에 별도의 테이블에 저장해도 괜찮습니다. 그런데, 선택과목 테이블이 학생번호 하나와 과목 하나의 조합으로 되어 있는 경우라면 어떨까요? 과목이 가로로 나열되어 있으면 보기 편하고, 보통 그렇게 보는 경우가 많아서 처음부터 그렇게 구성해도 좋지 않을까요?
그러나, 관계형 데이터베이스에 대해 이해를 하고 있다면 좀더 이해가 쉬울 것 같습니다. 데이터베이스에서는 여러 종류가 있는데 SQL은 관계형 데이터베이스라는 종류의 데이터베이스를 위한 언어로서 이 부분을 좀더 자세히 알아봅시다.
©2024-2025 GAEBAL AI, Hand-crafted & made with Damon JW Kim.
GAEBAL AI 개발사: https://gaebalai.com
AI 강의 및 개발, 컨설팅 문의: https://talk.naver.com/ct/w5umt5