본문 바로가기

카테고리 없음

SQL 공부

데이터베이스 공부

 

SQL 첫걸음

왕초보를 위한 정말 쉬운 SQL 입문서를 만나보자!본격적인 빅데이터 시대에 접어들면서 기존 대비 더 효율적이고 폭넓은 데이터 분석을 위한 수요가 커질 것으로 기대되는 가운데, SQL 활용 범위 역시 더욱 확대될 전망이다. 그 과정에서 취업 준비생이나 일반 직장인을 중심으로 SQL을 처음 공부하려는 이들 역시 증가하고 있다. 이 책은 데이터베이스 관련...

www.yes24.com


DML(Data Manipulation Language)

  • 데이터베이스에 CURD 하는 것, 데이터를 조작할 때 사용

DDL(Data Definition Language)

  • '데이터 베이스 객체'를 만들거나 삭제하는 명령어

DCL(Data Control Language)

  • 트랜잭션, 접근권한 제어에 관한 것들

DATABASE

비 휘발성 저장장치에 저장되어 있는 데이터들

DESC table1; // 테이블 구조 보여준다
SELECT * FROM table1 WHERE a <> 0, b <> 0;
// AND가 우선순위가 높으므로 괄호를 붙이자
SELECT * FROM table1 WHERE (a = 1 OR a = 2) AND (b = 1 OR b = 2);
// %는 문자열(빈칸 허용), _는 한 글자이다.
SELECT * FROM table1 WHERE text LIKE '%SQL%';
//\를 통해 특수문자 사용
SELECT * FROM table1 WHERE text LIKE '%SQ\%L%';

 

정렬

SELECT * FROM table1 ORDER BY age DESC;
// 기본이 ASC(오름 차순)이나 명시적이면 좋다.
SELECT * FROM table1 ORDER BY age ASC;
// 복수 정렬 가능 NULL은 DB에 따라 다르나 MYSQL에서는 가장 작은 값으로 취급
SELECT * FROM table1 ORDER BY age ASC, name DESC

 

결과 행 제한 - LIMIT

SELECT * FROM table1 ORDER BY age LIMIT 3;
// 4행부터 3개 가져옴, OFFSET + 1이 시작 행이라고 생각하자
SELECT * FROM table1 LIMIT 3 OFFSET 3;

 

수치 연산

SELECT *, price * quantity as amount FROM table1;
// as는 ""로 WHERE 같은데는 ''로
SELECT *, price * quantity as "금액" FROM table1;
// WHERE -> SELECT 순 처리이므로 as의 amount 사용 불가 !!
SELECT , price * quantity as amount FROM table1 WHERE price * quantity >= 20
/ NULL은 +1, -1, /1 해도 NULL 이다 */

 

ORDER BY 연산

// WHERE -> SELECT -> ORDER BY 순이므로 amount 사용 가능!
SELECT *, price * quantity as amount FROM table1 ORDER BY amount DESC;

 

함수 사용 -> ROUND

SELECT ROUND(amount) FROM table1; // 반올림
SELECT ROUND(amount, 1) FROM table1; // 소수점 둘째 자리에서 반올림
SELECT ROUND(amount, -2) FROM table1; // 100 단위에서 반올림 (10 ^ 2)

 

문자열 연산

SELECT CONCAT(age, name) FROM table1 // MYSQL에서 문자 연산
SELECT age + name FROM table1 // SQL Server에서 문자 연산
SELECT age || name FROM table1; // Oracle, DB2 등에서 문자 연산
/*
JAVA substring이랑 다르니깐 주의 하자.
SUBSTRING('20140125001', 1, 4) -> '2014';
SUBSTRING('20140125001', 5, 2) -> '01';
*/

 

날짜 연산

SELECT CURRENT_TIMESTAMP;

 

CASE 문으로 데이터 변환

// 두개 모두 null이면 0 아니면 a
SELECT a, CASE WHEN a IS NULL THEN 0 ELSE a AND "a(null=0)" FROM table1;
SELECT a, COALESCE(a, 0) from table1;

//단순 CASE
SELECT a AS "코드", CASE a WHEN 1 THEN "남자"
WHEN 2 THEN "여자" ELSE "미지정" END AS "성별" FROM table1;

//검색 CASE
SELECT a AS "코드", CASE WHEN a = 1 THEN "남자"
WHEN a = 2 THEN "여자" ELSE "미지정" END AS "성별" FROM table1;

// 주의 사항
ELSE 생략시 NULL이 입력되므로 생략하지 말자
NULL 은 = 이 아닌 IS NULL 로 검산

데이터 추가, 삭제, 갱신

데이터 추가

INSERT INTO table1 VALUES(1, 1, 'asd');
INSERT INTO table1(num, d) VALUES(1, 'ad');

 

데이터 삭제

DELETE FROM table1 WHERE num = 3;

 

데이터 업데이트

UPDATE table1 SET num = num + 1, a = 3, hi = 'hi' WHERE num = 3;
UPDATE tablename SET num = num + 1, a = num;
UPDATE tablename SET a = num, num = num + 1;
MYSQL은 SET 구에서 식이 기술된 순서로 계산되기 때문에 두 식이 달라진다.
오라클은 SET 구의 식의 오른쪽의 값은 항상 갱신 이전의 값을 반환하므로 두식의 결과는 같다.

물리 삭제와 논리 삭제

물리 삭제

  • 말 그대로 DB 테이블에 행을 삭제하는 것

논리 삭제

  • 테이블에 삭제 플래그 열을 준비
  • 삭제 시 실제 데이터를 삭제하는 게 아닌 UPDATE를 날려 실제 플러그에 값을 설정하여 select시 제외되게 함
  • 단점
    • 저장공간의 문제
    • 검색 속도 감소
    • 실제론 delete이지만 update를 날려야 하므로 혼돈

예시

  • 물리 삭제: sns 서비스에서 회원이 탈퇴하면 더 이상 정보가 필요 없으니 물리 삭제
  • 논리 삭제: 쇼핑 사이트에서 주문을 취소했을 때 해당 정보는 필요할 수도 있으니 논리 삭제

집계와 서브 쿼리

대표 집계 함수

  • count(집합)
  • sum(집합)
  • avg(집합)
  • min(집합)
  • max(집합)

테이블 전체 행

SELECT count(*) FROM table1;
SELECT count(*) FROM table1 WHERE name = 'a';

 

ALL, DISTINCT

// all은 생략 가능
SELECT all name FROM table1;
// 중복 제거
SELECT DISTINCT name FROM table1;

// count -> distinct 순이므로 distinct 안에넣기!
SELECT count(all name), count(distinct name) FROM table1;

 

집계 연산 NULL

// 둘다 null이 무시되므로 null을 0으로 만들고 싶으면 case로 변경 후 avg 하자!
SELECT avg(quantity), sum(quantity) / count(quantity) FROM talbe1;

 

그룹화

SELECT * FROM table1 GROUP BY 열1, 열2

// name열만 출력되고 name열이 그룹화 되어 중복값이 제거된다.
SELECT * FROM table1 GROUP BY name;
/*
그룹화는 아래와 같이 집계함수를 사용하지 않으면 별 의미가 없다.
아래 코드는 예를들어 name: A, A, B, C 가 있다면 우선 이 name 별로
그룹화를 하고 그룹화된 name의 갯수, quantity의 합을 같이 반환한다.
name    COUNT(name)     SUM(quantity)
A           2                 3(name A 두개의 quantity 합)
B           10                4
C           7                 6
*/
SELECT name, COUNT(name), SUM(quantity) FROM sample51 GROUP BY name;

실 사용 예: 점포별 매출 데이터를 관리할 때 점포별, 일별, 월별로 조회할 때 그룹화하고 집계 함수를 같이 사용하면 실적 조회가 유용하다.

 

SELECT name, count(name) FROM tabel1 WHERE count(name) = 1 GROUP BY name;
// 에러 발생, WHERE -> GROUP BY -> SELECT -> ORDER BY 순으로 진행되기 떄문에 WHERE에서 집계함수 사용 불가하다.

//해결법 where 대신 having 사용
SELECT name, count(name) FROM table1 GROUP BY name HAVING count(name) = 1;

내부 처리 순서
WHERE ====> GROUP BY ====> HAVING ====> SELECT ====> ORDER BY

 

그룹화 에러

//name은 그룹화 되었으나 나머지는 그룹화가 되지 않아 어떤 값을 가져와야 할지 모르므로 에러발생
SELECT name, num, quantity FROM table1 GROUP BY name;

// 이렇게 집계 함수를 사용하면 됨
select name, min(num), sum(quantity) from talbe1 group by name;

// 이렇게 복수 그룹화도 가능하다.
SELECT name, quantity FROM tablename GROUP BY name, quantity;
SELECT name, COUNT(name), SUM(quantity) FROM tablename GROUP BY name ORDER BY SUM(quantity) DESC;

 

서브 쿼리

  • 서브 쿼리는 select 명령에 의한 데이터 질의로, 상부가 아닌 하부의 부수적인 질의를 의미한다.
DELETE FROM table WHERE a = (SELECT min(a) FROM table1);
mysql은 아래와 같이 하자
DELETE FROM table WHERE a = (SELECT min(a) FROM(SELECT min(a) AS a FROM table1)) AS x);

 

변수 설정

SET @a = (SELECT min(a) FROM table1);
DELETE FROM talbe1 WHERE a = @a;

 

스칼라 값

  • select 명령이 하나의 값만 반환하는 것
  • 스칼라 값이 서브 쿼리로 사용하기 좋아 이러한 별명이 생김
// 스칼라 값 사용
SELECT (SELECT count(*) FROM table1) AS sq1, (SELECT count(*) FROM table2) AS sq2;

 

insert 명령과 서브 쿼리

INSERT INTO table1 VALUES((SELECT count(*) FROM table1)), (SELECT count(*) FROM table2));
// 그냥 1, 2 넣는 것
INSERT INTO table1 SELECT 1, 2;
// 테이블 복사하기
INSERT INTO talbe1 SELECT * FROM table2;

 

상관 서브 쿼리

  • 서브 쿼리에서 부모 테이블을 참조하는 것
  • 그러므로 서브 쿼리를 단독 실행 불가!!
// 이렇게 테이블2의 num2와 같은 num을 가진 a가 존재할 때만 a를 있음으로 바꾼다.
UPDATE table SET a = '있음' WHERE EXISTS(SELECT * FROM table WHERE num2 = num);

// 위의 반대로 다를 때 '없음'이라고 set한다.
UPDATE table SET a = '있음' WHERE NOT EXISTS(SELECT * FROM table WHERE num2 = num);

// 만약 열이 같으면 이렇게 구별시켜줘야 에러가 안난다.
UPDATE table1 SET a = '있음' WHERE EXISTS (SELECT * FROM table2 WHERE table2.num = table1.num);

IN 사용
// 스칼라 값은 =으로 비교하지만 집합을 비교할 때는 IN을 사용한다.
SELECT * FROM table1 WHERE num IN (3, 5);

SELECT * FROM table1 WHERE num IN (SELECT num2 FROM table2);

데이터베이스 객체 작성과 삭제

데이터베이스 객체

  • 데이터베이스 내에 실체를 가지는 어떤 것 (테이블, 뷰, 인덱스 등)
  • SELECT, INSERT 등은 실체가 없으므로 객체가 아님

스키마

  • 데이터베이스 객체는 스키마라는 그릇 안에 만들어진다.
  • 데이터베이스의 구조와 제약조건에 관해 전반적인 명세를 기술한 것
// 테이블 생성
CREATE TABLE table1(
nom INTEGER NOT NULL,
a VARCHAR(30),
b DATE);

// 테이블 정보
DESC table1;

// 테이블 제거
DROP TABLE table1;

// 삭제할 행 지정, WHERE 구 불가하지만 모든 행을 빠르게 삭제 가능
TRUNCATE TABLE talbe1;

// 열 추가시 원래 있던행에 추가된 열의 값은 NULL이 들어간다.
// 그러므로 NOT NULL 제약을 걸고 기본값을 설정해야 한다.
ALTER TABLE table1 ADD newcol INTEGER;

// 자료형 변경시 테이블에 들어간 데이터의 자료형 역시 바뀐다.
ALTER TABLE table1 MODIFY newcol VARCHAR(20);

// 열 이름 변경 후 자료형 변경
ALTER TABLE table1 CHANGE [기존 열 이름] [신규 열 정의];
ALTER TABLE table1 CHANGE newcol c VARCHAR(20);

// 열삭제
ALTER TABLE talbe1 DROP c;

실무에서 사용하는 ALTER TABLE 들

최대 길이 연장:

// 최대 길이를 늘린다.
// 줄일 수도 있지만 존재하는 행의 글자수 보다 적게 불가, 줄이는건 잘 안씀
ALTER TABLE table1 MODIFY col VARCHAR(30);

 

열추가

// 열 추가후 INSERT문을 바꾸어 주지 않으면 열 개수 맞지 않아 에러 발생
ALTER TABLE table1 ADD new_col INTEGER;

제약

  • 기본키
    • 테이블의 행 한 개를 특정할 수 있는 검색 키이다.
  • 복수의 열로 기본키 구성하기
    • 하나만 설정이 한 개의 열이 아닌 PRIMARY KEY(no1, no2) 이런 식으로는 된다는 뜻
    • 이럴 경우 no1에 중복 값이 있어도 no2가 중복되지 않으면 전체로선 중복하지 않는다고 간주하고 INSERT 진행된다
// 열 제약
CREATE TABLE table1(
a INTEGER NOT NULL,
b INTEGER NOT NULL UNIQUE,
c VARCHAR(30)
);

// 테이블 제약(한개의 제약으로 복수의 열에 제약을 검)
CREATE TABLE table1(
no INTEGER NOT NULL,
sub_no INTEGER NOT NULL,
name VARCHAR(30)
PRIMARY KEY(no, sub_no)
);

// 제약에 이름을 붙이면 나중에 관리가 쉬워짐(CONSTRAINT 이용)
CREATE TABLE table1(
no INTEGER NOT NULL,
sub_no INTEGER NOT NULL,
name VARCHAR(30)
CONSTRAINT pkey_sample PRIMARY KEY(no, sub_no)
);

// 제약도 ALTER로 설정 가능, BUT c에 NULL이 존재하면 에러 발생
ALTER TABLE table1 MODIFY c VARCHAR (30) NOT NULL;

// 테이블 제약 추가도 가능하다.
ALTER TABLE table1 ADD CONSTRAINT pkey_sample PRIMARY KEY(a);

// 제약 삭제
ALTER TABLE table1 MODIFY c VARCHAR(30);

// 테이블 제약 삭제
ALTER TABLE table1 DROP CONSTRAINT pkey_sample;

// 기본키는 테이블당 하나만 존재하므로 이렇게 제약명 없이 삭제 가능
ALTER TABLE table1 DROP PRIMARY KEY;

인덱스

  • 테이블에 붙여진 색인
  • 역할은 검색(탐색) 속도 향상
  • 책의 목차나 색인 같은 것
  • 인덱스는 테이블과는 별개로 독립적인 데이터베이스 객체로 작성된다.
  • 인덱스만으로는 아무런 의미가 없으며 인덱스는 테이블에 의존하는 객체이다.
  • 대부분 DB에서 테이블 삭제 시 연관된 인덱스도 같이 삭제된다.
  • DB인덱스에서 사용하는 알고리즘은 대표적으로 이진트리, 해시가 있다

풀 테이블 스캔

  • 인덱스가 지정되지 않은 테이블을 검색할 때는 풀 테이블 스캔이라고 불리는 검색 방법 사용
  • 테이블의 모든 값을 처음부터 조사
  • O(n)

이진 탐색

  • 차례로 나열된 집합에 대해 유효한 검색 방법
  • 처음부터 순서대로 조사하는 것이 아닌 집합을 반으로 나누어 조사하는 방법

인덱스 작성과 삭제

  • 작성 유의 사항
    • Oracle, DB2에서는 인덱스가 스키마 객체로 관리되므로 같은 스키마 내에서는 중복 이름 허용하지 않음
    • SQL Server, MySQL에서는 인덱스는 테이블 객체로 치므로 테이블 내에서만 이름이 중복되지 않으면 된다.
    • 인덱스를 작성할 때는 해당 인덱스가 어느 테이블의 어느 열에 관한 것인지 지정할 필요가 있다.
    • 이때 열은 복수로도 지정할 수 있다.
// sample1 테이블의 no 열에 isample22이라는 인덱스를 지정한다
// 테이블 행의 크기가 클수록 생성 시간고 저장공간 많이 소비
CREATE INDEX isample22 ON sample1(no);

// 인덱스 삭제
DROP INDEX isample22 ON sample1;

인덱스를 작성해두면 검색이 빨라진다. 작성한 인덱스 열을 WHERE 구로 조건을 지정하여 SELECT 명령으로 검색하면 처리속도 향상
-> 모든 SELECT 명령에 적용되는 만능 인덱스는 작성 불가
-> INSERT 명령의 경우에는 인덱스를 최신 상태로 갱신하는 처리가 늘므로 처리속도가 조금 떨어진다.

 

CREATE INDEX isample22 ON sample1(a);
// 이렇게 인덱스로 지정한 열을 사용해야한다. 사용하지 않을시 인덱스 적용이 안된다.
SELECT * FROM table1 WHERE a = 'a';

 

인덱스를 사용하는지 검색하는 명령어: EXPLAIN

CREATE INDEX isample22 ON sample1(a);

// 이렇게 하면 possible_keys와 key열이 생긴다. possible_keys는 사용될수 있는 인덱스, key는 사용한 인덱스
// 여기서는 isample22라는 인덱스를 사용했고 isample22 인덱스만 존재하므로 key, possible_keys에는 isample22만 존재한다.
EXPLAIN SELECT * FROM table1 WHERE a = 'a';

// 인덱스 열을 지정안했으므로 possible_keys, key에 NULL 이 생긴다.!!
EXPLAIN SELECT * FROM table1 WHERE no > 10;

최적화

  • SELECT 명령을 실행할 때 인덱스 사용 여부를 선택
  • 이는 DB의 내부 최적화에 의해 처리되는 부분
  • 내부 처리에서는 SELECT명령을 실행하기에 앞서 실행계획을 세움
  • 실행계획에서는 '인덱스'가 지정된 열이 WHERE 조건으로 지정되면 인덱스를 사용하자 라는 처리가 이루어진다.
  • 실행 계획에서는 인덱스 유무뿐만 아니라 어느 인덱스를 사용할 것인지에 대한 것도 DB 내부 최적화가 판단한다.
  • 예, 아니오로만 이루어진 열의 인덱스는 단순한 리스트로 구조가 이루어질 것이므로 안 좋은 인덱스이다.
  • 즉 데이터의 종류가 적을수록 인덱스의 효율이 떨어진다.

뷰 작성과 삭제

  • 뷰는 테이블과 같은 부류의 DB 객체 중 하나
    • 서브 쿼리는 FROM 구에서도 기술할 수 있다. 여기서 FROM 구에 기술된 서브 쿼리에 이름을 붙이고 DB에 객체화하여 쓰기 쉽게 한 것을 보라고 한다.
    • 즉 DB 객체로 등록할 수 없는 SELECT 명령을 객체로서 이름을 붙여 관리할 수 있도록 한 것이 뷰이다.
    • 뷰는 SELECT 명령을 기록하는 데이터베이스 객체이다.
    • 자주 사용하거나 복잡한 SELECT 명령을 뷰로 만들어 편리하게 사용할 수 있다.
  • 가상 테이블
    • 뷰는 실체가 존재하지 않으므로 가상 테이블이라고도 불린다.
    • SELECT 명령에서만 사용하는 것을 권장
CREATE VIEW sample_view_1 AS SELECT * FROM table1; // AS 생략 불가
SELECT * FROM sample_view_1; // 뷰 사용

뷰의 약점

  • 뷰는 DB 객체로 저장된다. SELECT 명령뿐이므로 저장공간기 많지는 않다. 하지만 CPU 자원을 사용하게 된다.
  • 뷰를 참조하면 뷰에 등록되어 있는 SELECT 명령이 실행된다.
  • 실행 결과는 일시적으로 메모에 보관되며 뷰를 참조할 때마다 SEELCT 명령이 실행된다.

약점 보안

  • 머티리얼 라이즈 뷰
    • 처음 뷰가 참조되었을 때 저장 장치 내의 가상 테이블에 데이터가 저장된다.
    • 그 후 똑같은 명령이 들어오면 저장된 데이터를 그대로 전송해준다
    • 데이터가 변경되면 다시 SELECT을 실행한다.
    • MySQL에서는 불가하고 Oracle과 DB2에서만 가능하다.
  • 함수 테이블
    • 뷰를 구성하는 SELECT 은 단독 실행이 가능해야 한다.
    • 함수 인수를 지정하여 사용하면 서브 쿼리처럼 동작 가능하다.

복수의 테이블 다루기

UNION 정렬

// table1 = {1, 2, 3}, table2 = {2, 10, 11}일 경우 합집합인 {1, 2, 3, 10, 11}이 나온다.
// UNION 으로 여러 개의 SELECT을 묶을 수 있지만 묶은 테이블의 열 개수와 자료형이 다르면 안된다
SELECT * FROM table1 UNION SELECT * FROM table2;

// 다를 경우에는 이렇게 작성하면 된다.
SELECT a FROM table1
UNION
SELECT b FROM table2
UNION
SELECT age FROM table3;

// 에러 발생, 정렬은 마지막에 정의해야한다.
SELECT * FROM table1 ORDER BY a UNION SELECT * FROM table2;

// 마지막에 정의해도 만약 두개의 열이 다르면 오류 발생
SELECT * FROM table1 UNION SELECT * FROM table2 ORDER BY b;

// 별칭을 이용하자
SELECT * FROM table1 AS c UNION SELECT * FROM table2 AS c ORDER BY c;

// 똑같은 열을 생략하지 않고 모두 보고 싶으면 UNION ALL 이용.
// UNION은 기본이 DISTINCT이고 SELECT은 기본이 ALL 인것을 인지하고 있자.
SELECT * FROM table1 UNION ALL SELECT * FROM table2;

// UNIOM은 중복값을 검사하므로 중복값이 존재하지 않으면 UNION ALL 이 성능이 더 좋다.

테이블 결합 JOIN

교차 결합(Cross Join)

SELECT * FROM table1, table2;
/* 이렇게 곰집합을 구할수 있다. 곰집합이란 table1 = X열에 A, B, C 있고 table2=Y열에 1,2,3 있었다면 x열에는 a, b, c, a, b, c, a, b, c y열에는 1, 1, 1, 2, 2, 2, 3, 3, 3 이렇게 된다.*/ 

UNION은 열은 추가되지 않으나 결합은 결이 추가된다.

 

내부 결합: 교차 집합은 너무 거대해지기 때문에 내부 결합을 주로 사용한다.

// 일반 곰집합을 이용할 경우
SELECT 상품.상품명, 재고수.재고수 FROM 상품, 재고수 
WHERE 상품.상품코드 = 재고수.상품코드 AND 상품.상품분류 = '식료품';
/* 첫번째 WHERE 문은 교차결합으로 계산된 곰집합에서 원하는 조합을 검색하는 것이다. (결합 조건)
두번쨰 WHERE 문은 결합조건이 아닌 검색조건이다.*/


// 내부결합을 이용할 경우
SELECT 상품.상품명, 재고수.재고수 FROM 상품 INNER JOIN 재고수 ON 상품.상품코드 = 재고수.상품코드 WHERE 상품. 상품분류 = '식료품';
// 내부 결합은 INNER JOIN을 이용한다.

// 자기 결합
SELECT S1.상품명, S2.상품명 FROM 상품 S1 INNER JOIN 상품 S2 ON S1.상품코드 = S2.상품코드;
// 자기결합에서는 결합의 좌우가 같은 테이블이 되기 때문에 이를 구별하기 위해서는 반드시 별명이 필요!!

외부 결합

SELECT 상품 3.상품명, 재고수.재고수 FROM 상품3 LEFT JOIN 재고수 ON 상품3.상품코드 = 재고수.상품코드 WHERE 상품3.상품분류 = '식료품';
// LEFT JOIN 이므로 상품3 위주로 조인된다. RIGHT JOIN도 존재한다.

관계형 모델

- 관계형 모델로 작성된 데이터베이스가 관계형 데이터베이스이다.

- SQL은 관계형 모델에 의해 구축된 데이터베이스를 조작하는 체계적인 명령의 집합.

- 관계형 모델의 기본적인 요소는 릴레이션이다. - 릴레이션이라는 말은 관계를 뜻하지만 SQL에서는 테이블을 의미한다. - 관계형 모델에서 **열을 속성(attribute), 행을 튜플(Tuple)**이라고 부른다. - 즉 릴레이션은 튜플의 집합이다.(테이블은 행의 집합이다)

// 합집합 SQL에선 UNION
SELECT * FROM A UNION SELECT FROM B

// 차집합
SELECT * FROM A EXCEPT SELECT FROM B

// 교집합
SELECT * FROM A INTERSECT SELECT * FROM B

// 곰집합
SELECT * FROM A,B / SELECT * FROM A CROSS JOIN B

// 선택: 튜플의 추출
SELECT * FROM A WHERE no < 3;

// 투영: 속성의 추출
SELECT a FROM A;

// 결합: JOIN
SELECT a FROM A INNER JOIN B ON A.no = B.no;

정리

집합 연산: 테이블은 데이터행의 집합으로 간주하여 집합 연산을 적용할 수 있다.

교차결합, 곰 집합: FROM 구에 테이블을 복수로 지정하여 교차결합으로 곰 집합을 구할 수 있다. 내부, 외부 결합의 기반이 된다.

내부 결합: 곰 집합에서 필요한 행만 검색하도록 조건을 지정해서 결합하는 것을 말한다.

외부 결합: 내부 결합으로 결합되지 않는 행을 강제적으로 결과에 포함하는 방법이다.

관계형 모델: 관계형 모델은 관계형 DB의 기반이 되는 이론적 개념으로 사용되는 용어가 SQL가 일치하지는 않는다.


데이터베이스 설계

  • '데이터베이스 설계'란 데이터베이스의 스키마 내의 테이블, 인덱스, 유등의 데이터베이스 객체를 정의하는 것
  • 스키마 내에 정의한다는 뜻에서 '스키마 설계'라고도 부른다.
  • 데이터 베이스 열에 저장할 수 있는 크기는 의외로 작다. VARCHAR 형으로 지정할 수 있는 최대 크기는 수천 바이트이다.
  • 그래서 LOB(Large OBject)가 있는데 이 자료형은 인덱스로 지정이 불가하다.

정규화

  • 정규화란 데이터베이스의 테이블을 규정된 올바른 형태로 개선해나가는 것.
  • 정규화는 대부분 테이블 분할이나 기본키 작성을 통해 이루어지며 보통 제3 정규화까지 사용하는 것으로 알고 있다.

제1 정규화

  • 1단계: 반복되는 데이터들을 가로 방향이 아닌 세로 방향을 늘림(0001 이어폰 3개, 0003 신발 2) 일 때 0001, 이어폰 3개 / 0003, 신발 2개 이렇게 된다.
  • 2단계: 중복되는 행들이 존재하지 않도록 테이블을 분리한다. 그리고 기본키를 지정하여 매칭 시킨다.

제2 정규화

  • 기본키에 중복이 있는지 조사 후 테이블을 분리한다

제3 정규화

  • 기본키 이외의 부분에서 중복이 없는지를 조사 후 테이블을 분리한다.
  • 정규화의 목적은 중복하거나 반복되는 부분을 찾아내서 테이블을 분할하고 기본키를 작성해 사용하는 것을 기본개념으로 삼는다.
  • 이는 '하나의 데이터는 한 곳에 있어야 한다'는 규칙에 근거한다.

트랜잭션

  • 트랜잭션이란 데이터 관리를 위한 하나의 작업의 단위이다.
  • 트랙잭션 내에서는 여러 개의 쿼리를 날릴 수 있으며 한 트랜잭션 내에서의 데이터 처리는 커밋이 되어야 DB에 정상적으로 반영된다.
  • 만약 한 트랜잭션 내에서 문제가 발생 시 롤백으로 SQL명령을 취소할 수 있다.