SQL(Structured Qery Language) 은 관계 데이터베이스를 위한 표준 질의어로 많이 사용되는 언어입니다. SQL은 사용자가 처리를 원하는 데이터가 무엇인지만 제시하고, 데이터를 어떻게 처리해야 하는지를 언급할 필요가 없어서 비절차적 데이터 언어의 특징을 띄고 있습니다.
SQL은 데이터베이스 관리 시스템에 직접 접근하여 대화식으로 질의를 작성해 사용할 수도 있고, C나 C++ 또는 Java 같은 언어로 작성한 응용 프로그램에 삽입하여 사용할 수도 있습니다.
SQL은 아래의 그림과 같이, 기능에 따라 데이터 정의어(DDL), 데이터 조작어(DML), 데이터 제어어(DCL)로 나눈다. 이번 장에서는 데이터 정의어와 데이터 조작어를 중심으로 공부해보겠습니다.
SQL의 데이터 정의 기능은 테이블 생성, 생성된 테이블 구조의 변경, 테이블 삭제로 분류할 수 있습니다.
새로운 테이블을 생성하려면 먼저 테이블의 이름과 테이블을 구성하는 속성의 이름을 의미있게 정해야 합니다. 그런 다음 각 속성의 특성에 맞게 데이터 타입을 결정합니다.
테이블을 생성하는 SQL 명령어는 CREATE TABLE 입니다.
CREATE TABLE 문의 기본 형식은 다음과 같습니다.
CREATE TABLE 테이블_이름 (
1. 속성_이름 데이터_타입 [NOT NULL] [DEFAULT 기본_값]
2. [PRIMARY KEY]
3. [UNIQUE]
4. [FOREIGN KEY (속성_리스트) REFERENCES 테이블_이름(속성_리스트)]
5. [CONSTRAINT 이름] [CHECK(조건)]
);
속성의 데이터 타입
데이터 타입 | 의미 |
---|---|
INT or INTEGER | 정수 |
SMALLINT | INT 보다 작은 정수 |
CHAR(n) or CHARACTER(n) | 길이가 n인 고정 길이의 문자열 |
VARCHAR(n) | 최대 길이가 n인 가변 길이의 문자열 |
NUMERIC(p, s) or DECIMAL(p, s) | 고정 소수점 실수, p는 소수점을 제외한 전체 숫자의 길이, s는 소수점 이하 숫자의 길이 |
FLOAT(n) | 길이가 n인 부동 소수점 실수 |
REAL | 부동 소수점 실수 |
DATE | 연, 월, 일로 표현되는 날짜 |
TIME | 시, 분, 초로 표현되는 시간 |
DATETIME | 날짜와 시간 |
PK가 아니더라도 값을 꼭 입력해야 된다고 판단되는 속성은 NOT NULL 키워드를 표기합니다. (회원 가입을 할 때 필수 입력 사항으로 분류된 항목이, 회원 데이터를 저장하고 있는 테이블에서 NOT NULL로 지정된 속성입니다.
고객아이디 VARCHAR(20) NOT NULL
속성에 기본값을 지정해두지 않으면 사용자가 속성에 값을 입력하지 않았을 때 해당 속성에 NULL 값이 기본으로 저장됩니다. 하지만 DEFAULT 키워드를 사용해 기본 값을 명확히 지정해두면 이 기본값이 저장됩니다.
적립금 INT DEFAULT 0
키의 정의
CREATE TABLE 문으로 테이블을 정의할 때는 기본키, 대체키, 외래키를 지정할 수 있습니다.
데이터 무결성 제약조건의 정의
CHECK (재고량 >= 0 AND 재고량 <= 10000)
테이블은 ALTER TABLE 문으로 변경할 수 있습니다. ALTER TABLE 문을 이용해서 새로운 속성 추가, 기존 속성 삭제, 새로운 제약조건 추가, 기존 제약조건 삭제 등이 가능합니다.
새로운 속성의 추가
ALTER TABLE 테이블_이름
ADD 속성_이름 데이터_타입 [NOT NULL] [DEFAULT 기본_값];
기존 속성의 삭제
ALTER TABLE 테이블_이름 DROP COLUMN 속성_이름;
만약 삭제할 속성과 관련된 제약조건이 존재하거나 이 속성을 참조하는 다른 속성이 존재하는 경우에는 속성을 삭제할 수 없습니다. 관련된 제약조건이나 참조하는 다른 속성을 먼저 삭제한 후 해당 속성을 삭제해야 합니다.
새로운 제약조건의 추가
ALTER TABLE 테이블_이름 ADD CONSTRAINT 제약조건_이름 제약조건_내용;
예시 : 고객 테이블에 20세 이상의 고객만 가입할 수 있다는 데이터 무결성 제약조건을 추가
ALTER TABLE 고객 ADD CONSTRAINT CHK_AGE CHECK(나이 >= 20);
기존 제약조건의 삭제
DROP TABLE 테이블_이름;
삭제할 테이블을 참조하는 테이블이 있다면 삭제가 수행되지 않습니다. 따라서 삭제하고자 하는 테이블을 참조하는 외래키 제약조건을 먼저 삭제해야 합니다.
SQL 데이터 조작 기능은 원하는 데이터 검색, 새로운 데이터 삽입, 데이터 수정, 데이터 삭제로 분류할 수 있습니다. 이 네 가지 데이터 조작 기능을 위한 SQL 문의 작성 규칙을 차례로 알아보도록 하겠습니다.
테이블에서 원하는 데이터를 검색하기 위해 필요한 SQL문은 SELECT 입니다.
SELECT 문은 다양한 검색 유형을 지원하며, 일반 사용자들이 가장 많이 사용합니다.
SELECT 문의 기본 형식은 다음과 같습니다.
SELECT 속성_리스트
FROM 테이블_리스트;
SELECT ALL 속성_리스트
FROM 테이블_리스트;
SELECT DISTINCT 속성_리스트
FROM 테이블_리스트;
산술식을 이용한 검색
SELECT 키워드와 함께 산술식을 제시할 수 있습니다.
산술식은 속성의 이름과 +,-, *, / 등의 산술연산자, 상수로 구성합니다.
SELECT 제품명, 단가 + 500 AS "조정 단가"
FROM 제품;
조건 검색
조건을 만족하는 데이터만 검색하는 SELECT 문의 기본 형식은 다음과 같습니다.
SELECT 속성_리스트
FROM 테이블_리스트
WHERE 조건;
조건에는 비교 연산자와 논리 연산자가 들어올 수 있습니다.
LIKE를 이용한 검색
검색 조건을 부분적으로만 알고 있다면 LIKE 키워드를 이용해 검색할 수 있습니다.
검색조건을 정확히 알면 = 연산자로 조건을 표현하면 되지만, 부분적으로만 알고 있다면 LIKE 키워드를 사용합니다.
NULL을 이용한 검색
검색 조건에서 특정 속성의 값이 널 값인지를 비교하려면 IS NULL 키워드를 사용합니다.
반대로 널 값이 아닌지를 비교하려면 IS NOT NULL 키워드를 사용합니다.
정렬 검색
SELECT 문의 검색 결과 테이블은 일반적으로 DBMS가 정한 순서로 출력됩니다. 결과 테비을의 내용을 사용자가 원하는 순서로 출력하려면 ORDER BY 키워드를 사용해야 합니다.
SELECT 속성_리스트
FROM 테이블_리스트
ORDER BY 속성_리스트 [ASC | DESC]
오름차순 정렬이면 ASC, 내림차순 정렬이면 DESC로 표현합니다.
특별히 지정하지 않으면 오름차순으로 기본 정렬합니다.
집계 함수를 이용한 검색
특정 속성 값을 통계적으로 계산한 결과를 검색하기 위해 집계함수를 이용할 수 있습니다.
개수, 합계, 평균, 최댓값, 최솟값의 계산 기능을 제공합니다.
SELECT 문과 함께 자주 사용하는 다섯 가지 집계 함수는 다음과 같습니다.
그룹별 검색
테이블에서 특정 속성의 값이 같은 투플을 모아 그룹을 만들고, 그룹별로 검색을 하기 위해 GROUP BY 키워드를 사용합니다.
그룹에 대한 조건을 추가하려면 GROUP BY 키워드를 HAVING 키워드와 함께 사용하면 됩니다.
그룹별로 검색하는 SELECT 문의 기본 형식은 다음과 같습니다.
SELECT 속성_리스트
FROM 테이블_리스트
WHERE 조건
GROUP BY 속성_리스트[HAVING 조건]
ORDER BY 속성_리스트
여러 테이블에 대한 조인 검색
여러개의 테이블을 연결하여 데이터를 검색하는 것을 조인 검색이라고 합니다.
조인 검색을 하려면 테이블을 연결해주는 속성이 필요하고, 이 속성을 조인 속성이라고 합니다.
SELECT 제품.제품명
FROM 제품, 주문
WHERE 주문.주문고객='banana' AND 제품.제품번호 = 주문.주문제품;
부속 질의문을 이용한 검색
SELECT 문 안에 또 다른 SELECT 문을 포함할 수도 있습니다.
다른 SELECT 문 안에 들어 있는 (nested) SELECT 문을 부속 질의문 또는 서브 질의문(sub query)이라고 합니다.
SELECT 제품명, 단가
FROM 제품
WHERE 제조업체 = (SELECT 제조업체 FROM 제품 WHERE 제품명 = '달콤비스킷');
다중 행 부속 질의문에 사용 가능한 연산자 예시 :
판매 데이터베이스에서 대한 식품이 제조한 모든 제품의 단가보다 비싼 제품의 제품명, 단가, 제조업체 검색
SELECT 제품명, 단가, 제조업체
FROM 제품
WHERE 단가 > ALL (SELECT 단가 FROM 제품 WHERE 제조업체 = '대한식품');
테이블에 새로운 투플을 삽입하기 위해 필요한 SQL문은 INSERT입니다.
INSERT 문을 이용해 투플을 삽입하는 방법은 다음과 같습니다.
데이터 직접 삽입
테이블에 투플을 직접 삽입하는 INSERT 문의 기본 형식은 다음과 같습니다.
INSERT
INTO 테이블_이름 (속성_리스트)
VALUES (속성값_리스트)
INTO 키워드와 함께 투플을 삽입할 테이블의 이름을 제시한 후, 속성의 이름을 나열하는데, 이 나열 순서대로 VALUES 키워드 다음의 속성 값들이 차례로 삽입됩니다.
INTO 절의 속성 이름과 VALUES 절의 속성 값은 순서대로 일대일 대응되고, 순서도 같아야 합니다.
VALUES 절에 나열되는 속성 값은 문자나 날짜 타입의 데이터인 경우에는 작은 따옴표로 묶어야 합니다.
예시
판매 데이터베이스의 고객 테이블에 고객 아이디가 birdie, 고객 이름이 버디, 나이가 27세, 등급이 vip, 직업이 백엔드 개발자, 적립금이 1000원인 새로운 고객의 정보를 삽입해보자.INSERT INTO 고객(고객아이디, 고객이름, 나이, 등급, 직업, 적립금) VALUES ('birdie', '버디', 27, 'vip', '백엔드 개발자', 1000);
부속 질의문을 이용한 데이터 삽입
부속 질의문인 SELECT 문을 이용해 다른 테이블에서 검색한 데이터를 투플로 삽입하는 INSERT 문의 기본 형식은 다음과 같습니다.
INSERT INTO 테이블_이름(속성_리스트)
SELECT 문;
예시
판매 데이터베이스에서 제시한 3개의 테이블 외에 제품명, 재고량, 단가 속성으로 구성된 한빛 제품 테이블이 존재한다고 가정하고, 부속 질의문을 이용한 INSERT 문의 예를 살펴보자.INSERT INTO 한빛제품(제품명, 재고량, 단가) SELECT 제품명, 재고량, 단가 FROM 제품 WHERE 제조업체 = '한빛제과';
테이블에 저장된 데이터를 수정하기 위해 필요한 SQL 명령어는 UPDATE입니다. UPDATE문의 기본 형식은 다음과 같습니다.
UPDATE 테이블_이름
SET 속성_이름1 = 값1, 속성_이름2 = 값2 ...
WHERE 조건;
예시
제품 테이블에서 제품번호가 p03인 제품의 제품명을 통큰파이로 수정해보자.UPDATE 제품 SET 제품명 = '통큰파이' WHERE 제품번호 = 'p03';
테이블에 저장된 데이터를 삭제하기 위해 필요한 SQL 명령어는 DELETE 입니다.
DELETE 문의 기본 형식은 다음과 같습니다.
DELETE FROM 테이블_이름
WHERE 조건;
DELETE 문은 WHERE 절에 제시한 조건을 만족하는 투플만 삭제합니다. WHERE 절을 생략하면 테이블에 존재하는 모든 투플을 삭제하여 빈 테이블이 됩니다.
예시
주문 테이블에서 주문 일자가 2023년 5월 7일인 주문 내역을 삭제해보자.DELETE FROM 주문 WHERE 주문일자 = '2023-05-07';
뷰(view)는 다른 테이블을 기반으로 만들어진 가상 테이블 입니다.
뷰를 가상 테이블이라고 하는 이유는 일반 테이블과 달리 데이터를 실제로 저장하고 있지 않기 때문입니다.
물리적으로는 존재하면서 실제로 데이터를 저장하는 일반 테이블과 달리, 뷰는 논리적으로만 존재하면서도 일반 테이블과 동일한 방법으로 사용할 수 있어, 사용자는 그 차이를 느끼기 어렵습니다.
뷰를 만드는 데 기반이 되는 물리적인 테이블을 기본 테이블이라 하는데, CREATE TABLE 문으로 정의한 테이블이 기본 테이블로 사용됩니다.
뷰는 기본 테이블을 들여다볼 수 있는 창 역할을 합니다. 창을 통해 바깥 풍경을 보듯이, 뷰를 통해 기본 테이블을 들여다볼 수 있습니다.
뷰의 생성과 삭제도 SQL의 데이터 정의 기능에 해당합니다.
뷰를 생성하기 위해 필요한 SQL 명령어는 CREATE VIEW입니다. CREATE VIEW 문의 기본 형식은 다음과 같습니다.
CREATE VIEW 뷰_이름(속성_리스트)
AS SELECT 문
[WITH CHECK OPTION];
SELECT 문은 생성하고자 하는 뷰의 정의를 담고 있는데, ORDER BY를 사용할 수 없다는 점만 제외하면 일반 SELECT 문과 동일합니다.
WITH CHECK OPTION 은 생성한 뷰에 삽입이나 수정 연산을 할 때 SELECT 문에서 WHERE 키워드와 함께 제시한 뷰의 정의 조건을 위반하면 수행되지 않도록 하는 제약조건을 의미합니다.
예시
고객 테이블에서 등급이 vip 인 고객의 고객아이디, 고객이름, 나이, 등급으로 구성된 뷰를 우수고객이라는 이름으로 생성해보자.CREATE VIEW 우수고객(고객아이디, 고객이름, 나이, 등급) AS SELECT 고객아이디, 고객이름, 나이, 등급 FROM 고객 WHERE 등급 = 'vip' WITH CHECK OPTION;
CREATE VIEW 문으로 생성된 뷰에서도 일반 테이블처럼 원하는 데이터를 검색할 수 있습니다.
예시
우수고객 뷰에서 나이가 20세 이상인 고객에 대한 모든 내용을 검색해보자SELECT * FROM
뷰가 데이터를 실제로 저장하고 있지 않는 가상 테이블임에도 SELECT 문을 이용해서 데이터를 검색할 수 있는 이유는, 뷰에 대한 SELECT 문이 내부적으로는 기본 테이블에 대한 SELECT 문으로 변환되어서 수행되기 때문입니다.
INSERT, UPDATE, DELETE 문도 뷰를 대상으로 수행할 수 있습니다. 물론 뷰에 대한 삽입, 수정, 삭제 연산도 기본 테이블에 수행되기 때문에 결과적으로는 기본 테이블이 변하게 됩니다.
그러나 삽입, 수정, 삭제 연산이 모든 뷰에 허용되는 것은 아닙니다.
뷰에 대한 연산이 성공적으로 수행되려면 연산에서는 기본키 속성을 포함하고 있어야 합니다.
기본키 속성이 없다면, 어떤 투플에 대한 연산인지 알 수 없기 때문입니다.
그럼 뷰에 대한 검색, 삽입, 수정, 삭제 연산이 결과적으로는 기본 테이블에 대한 연산으로 변환되어 수행되는데 왜 굳이 번거롭게 뷰를 정의하여 사용할까요?
뷰의 대표적인 장점으로는 다음과 같습니다.
뷰를 삭제하기 위해 필요한 SQL 명령어는 DROP VIEW 입니다.
DRIP VIEW 뷰_이름;
뷰를 삭제하더라도 기본 테이블은 영향받지 않습니다.
여기서는 데이터베이스 설계 과정의 각 단계에서 수행하는 주요 작업을 간단히 알아보겠습니다.
요구 사항 분석
개념적 설계
논리적 설계
물리적 설계
구현
데이터베이스 설계의 시작인 요구 사항 분석 단계에서는 사용자들이 데이터베이스에 원하는 것이 무엇인지를 분석합니다. 즉 데이터베이스에 대한 사용자들의 요구사항을 수집하고 분석하여, 개발할 데이터베이스의 용도를 명확히 파악하는 것이 목적입니다.
요구사항 분석 단계는 사용자가 요구하는 데이터베이스의 용도가 결정되는 단계이기 때문에 품질 좋은 데이터베이스를 개발하기 위해서 중요합니다.
개념적 설계에서는 요구사항 분석 단계의 결과물을 개념적 데이터 모델을 이용하여 표현합니다.
일반적으로 개념적 데이터 모델은 E-R 다이어그램으로 표현합니다.
개념적 설계 단계에서 가장 먼저 수행해야 하는 기본 작업은 요구 사항 분석 단계의 결과물에서 개체를 추출하는 일입니다. 개체부터 결정해야 속성과 관계도 결정할 수 있습니다.
그럼 개체를 어떤 방법으로 추출할까요? 초보자들에게 좋은 방법은 제시된 요구 사항의 문장들에서 명사부터 찾아야 합니다. 이 중에서 개체가 아닌 속성으로 분류되는 단어도 존재하기 때문에, 명사를 추출할 땐 주의를 기울여야 합니다.
문장을 읽은 후 개체와 속성을 추출하면 E-R 다이어그램으로 표현하여야 합니다.
개체와 속성을 추출하고 나면 개체 간의 관계를 결정할 수 있습니다. 관계는 개체 간의 의미 있는 연관성입니다. 일반적으로 관계는 요구 사항을 표현한ㄴ 문장에서 동사로 표현됩니다. 그러므로 개체 간의 관계를 결정할 때는 요구 사항 문장에서 동사부터 찾아야 합니다.
개념적 설계 단계의 결과물인 개념적 스키마
논리적 설계 단계에서는 DBMS에 적합한 논리적 데이터 모델을 이용해서, 개념적 설계 단계에서 생성한 개념적 스키마를 기반으로 논리적 스키마를 설계합니다. 즉 DBMS에 독립적인 개념적 스키마를 기반으로 하여 개발에 사용할 DBMS가 처리할 수 있는 데이터베이스의 논리적 구조를 설계하는 것이 논리적 설계 단계의 목표입니다.
일대일 관계를 외래키로 표현한다.
- 4-1 : 일반적인 일대일 관계는 외래키를 서로 주고받는다.
일반적인 일대일 관계는 릴레이션으로 변환하지 않고 외래키로만 표현한다.
![](https://velog.velcdn.com/images/flaehdan/post/89d54bf0-156a-4d8f-b6ec-9c0b69d49c43/image.png)
논리적 설계 단계에서 릴레이션 스키마의 설계를 완료하면, 물리적 설계 단계에서는 하드웨어나 운영체제의 특성을 고려하여 필요한 인덱스의 구조나 내부 저장 구조, 접근 경로 등에 대한 물리적인 구조를 설계한다.