데이터베이스는 어떻게 생겼나

SQL이 처음이라면 이 레슨부터 보세요. 테이블이 어떻게 데이터를 담는지, 쿼리 결과를 어떻게 읽는지부터 예제로 확인합니다.

먼저 열어보기

아래 예제의 버튼을 누르면 새 탭에서 Planche가 열립니다. 쇼핑몰 샘플 데이터베이스와 쿼리가 준비돼 있어 설치나 가입 없이 실행할 수 있습니다. 데이터는 브라우저 안에서만 다뤄집니다. 쿼리를 바꿔 실행해도 되고, 처음 상태로 돌아가고 싶다면 환영 화면에서 샘플을 다시 불러오면 됩니다.

테이블은 표입니다

먼저 이 쿼리를 실행해 보세요. categories 테이블의 행과 컬럼을 모두 보여 줍니다.

1

SELECT * FROM categories;
Planche에서 실행

결과 — 33행 중 처음 5행

idnamedescriptionparent_idsort_orderis_active
1ElectronicsElectronics and related productsNULL01
2LaptopsLaptops in Electronics111
3PhonesPhones in Electronics121
4TabletsTablets in Electronics131
5AudioAudio in Electronics141

브라우저의 새 탭에서 Planche가 열리고, 샘플 데이터베이스가 로드된 채로 이 쿼리가 들어갑니다. 이 페이지의 다른 예제도 같은 탭을 다시 씁니다. F9를 누르기 전까지는 아무것도 실행되지 않습니다.

쿼리 결과로 보이는 표가 테이블입니다. 먼저 세 가지 용어를 알아두면 됩니다.

  • 컬럼은 표 위쪽의 항목 이름입니다. id, name, description이 여기에 해당합니다. 이 테이블에는 여섯 개의 컬럼이 있고, 각 행은 같은 컬럼 구성을 가집니다.
  • 행은 표의 가로 한 줄입니다. 여기서는 행 하나가 카테고리 하나를 뜻합니다. 33행이 있으니 카테고리도 33개입니다.
  • 셀은 행과 컬럼이 만나는 칸입니다. 셀 하나에는 이름이나 번호처럼 값 하나가 들어갑니다.

다른 테이블도 원리는 같습니다. products에는 상품마다 한 행, orders에는 주문마다 한 행, customers에는 고객마다 한 행이 있습니다. 다루는 대상에 따라 컬럼만 달라집니다.

빈 칸의 이름은 NULL입니다

2

SELECT id, name, parent_id
FROM categories
LIMIT 8;
Planche에서 실행

결과 — 8행 중 처음 5행

idnameparent_id
1ElectronicsNULL
2Laptops1
3Phones1
4Tablets1
5Audio1

parent_id에는 숫자가 있는 행도 있고 NULL인 행도 있습니다. 이 컬럼은 카테고리가 어느 상위 카테고리에 속하는지 기록합니다. 예를 들어 Laptops는 Electronics에 속하므로 Electronics의 id인 1이 들어갑니다. 최상위 카테고리에는 상위 카테고리가 없어서 NULL입니다.

NULL은 값이 없다는 표시입니다. 0과는 다른 값으로 다뤄집니다.

  • 0은 값이 0이라는 뜻이고, NULL은 값을 알 수 없거나 아직 기록하지 않았다는 뜻입니다.
  • 빈 문자열과도 다릅니다. 이름을 빈칸으로 저장한 경우와 이름을 아예 기록하지 않은 경우는 구별할 수 있습니다.

NULL은 비교할 때 일반적인 값과 다른 규칙을 따릅니다. 자세한 내용은 세 번째 레슨에서 다룹니다. 여기서는 NULL이 단순한 빈 칸이 아니라는 점만 알아두세요.

행마다 고유한 번호가 있습니다

첫 컬럼인 id는 각 행을 구분하는 번호입니다. 같은 번호가 두 행에 붙지 않으며, 다른 테이블에서 이 행을 참조할 때도 이 번호를 씁니다. 이런 컬럼을 기본 키라고 합니다.

기본 키는 보통 id라는 이름을 쓰지만, 꼭 그럴 필요는 없습니다.

왜 테이블이 하나가 아니라 23개인가

쇼핑몰 정보를 큰 표 하나에 모두 넣을 수도 있습니다. 하지만 주문마다 고객 이름과 주소를 함께 저장하면, 고객이 이사할 때 과거 주문까지 모두 수정해야 합니다. 일부만 바뀌면 같은 고객의 주소가 주문마다 달라질 수 있습니다.

그래서 고객, 상품, 주문처럼 성격이 다른 데이터는 테이블을 나눠 저장하고, 필요한 곳에서 기본 키로 연결합니다. products.category_id에는 categories.id 값이, orders.customer_id에는 customers.id 값이 들어갑니다. 다른 테이블의 행을 가리키는 컬럼을 외래 키라고 합니다. 이 연결을 이용해 데이터를 함께 조회하는 방법이 조인입니다.

테이블과 컬럼을 찾을 때는 샘플 데이터베이스 페이지를 참고하세요. 테이블별 컬럼과 연결 관계를 확인할 수 있습니다. SQL을 작성할 때 스키마를 함께 보는 일은 흔합니다.

쿼리는 질문이고, 답도 테이블입니다

3

SELECT COUNT(*) AS how_many FROM products;
Planche에서 실행

결과 — 1행

how_many
400

결과는 한 행, 한 컬럼으로 된 숫자 하나입니다. 크기는 작아도 이것 역시 테이블입니다. SQL 쿼리 결과는 행이 하나든 여러 개든 표 형태로 반환됩니다.

여기서 400은 미리 저장해 둔 숫자가 아닙니다. 쿼리를 실행하는 순간 데이터베이스가 상품 행을 세어 만든 결과입니다. SQL은 저장된 데이터를 읽는 일뿐 아니라, 그 데이터를 바탕으로 값을 계산하는 데도 쓰입니다.

직접 실행해보기

에디터에 쿼리를 입력하고 F9를 누르면 실행합니다. Ctrl / ⌘ + Enter를 누르면 커서가 있는 문장만 실행합니다. 결과는 아래 그리드에 표시되며 행 수는 화면 아래에서 확인할 수 있습니다.

왼쪽 패널에서 main과 테이블을 차례로 펼친 뒤 테이블을 더블클릭해도 내용을 볼 수 있습니다. 쿼리를 쓰기 전에 컬럼과 데이터 모양을 확인하기 좋습니다.

이 페이지의 예제는 각각 별도 탭으로 열립니다. 한 예제를 수정해도 다른 예제에는 영향을 주지 않습니다.

잘 안 될 때

처음에는 오타나 컬럼 이름 때문에 오류를 자주 만나게 됩니다. 예를 들어 컬럼 이름을 잘못 쓰면 이런 메시지가 나옵니다.

no such column: naem

메시지에 데이터베이스가 찾지 못한 이름이 표시됩니다. 흔한 원인은 컬럼 이름 오타, 다른 테이블의 컬럼을 쓴 경우, 문자열의 따옴표를 빠뜨린 경우입니다. SQL에서 문자열은 'paid'처럼 작은따옴표로 감쌉니다.

문법 오류가 난 쿼리는 실행되지 않습니다. 실패한 문장이 데이터를 바꾸지는 않으므로 고친 뒤 다시 실행하면 됩니다.

다음은

이제 테이블, 행, 컬럼, NULL을 구분하고 쿼리 결과를 읽을 수 있습니다. 다음 레슨에서는 SELECT, WHERE, ORDER BY, LIMIT으로 원하는 행을 조회합니다.

직접 해보기

  1. 이 쇼핑몰에는 고객이 몇 명인가요? 이 쿼리의 모양은 페이지 마지막 예제에서 봤습니다.

    정답 보기

    정답 보기

    SELECT COUNT(*) AS how_many FROM customers;
    Planche에서 실행

    결과 — 1행

    how_many
    1500

    COUNT(*)는 행을 세고, AS how_many는 답이 담긴 컬럼에 읽기 좋은 이름을 붙일 뿐입니다. customers 자리에 다른 테이블 이름을 넣으면 그 테이블을 셉니다.