보다 효율적으로 데이터베이스에 질의할 수 있는 다양한 방법
()로 감싸진 SELECT문을 말함SELECT문 안에 SELECT문이 포함된 서브 쿼리

외부 쿼리는 users 테이블에서 username과 서브 쿼리의 결과를 조회
그리고 서브 쿼리의 결과를 post_count라고 간주함(AS post_count),
서브 쿼리는 posts 테이블의 user_id와 users 테이블의 user_id가 같은 posts 테이블의 레코드 수를 조회
즉, 사용자별로 작성한 글의 개수를 조회하는 SQL문
DELETE문 안에 DELETE문이 포함된 서브 쿼리

외부 쿼리는 posts 테이블에서 user_id가 서브 쿼리의 결과와 같은 레코드를 삭제
그리고 서브 쿼리는 users 테이블에서 email이 kim@example.com인 레코드를 조회
즉, email이 kim@example.com인 사용자의 글을 삭제하는 SQL문


가장 일반적인 조인으로 보통 '조인'이라 하면 INNER 조인을 의미하는 경우가 많음
orders.customer_id와 customers.id를 기준으로 INNER 조인
SELECT customer.name, customer.age, customer.email, order.id,
orders.product_id, orders.quantity, orders.amount
FROM customers
INNER JOIN orders ON customer.id = orders.customer_id;
이 SQL문의 결과는 customers 테이블의 name, age, email 필드와 orders 테이블의 id, product_id, quantity, amount가 필드로 구성된 하나의 테이블 형태로 조회됨
조인 결과에 대해 WHERE절을 추가하면 조건에 따라 레코드를 필터링하여 조회할 수도 있음
SELECT customers.name, customers.age, customers.email,
orders.id, orders.product_id, orders.quantity, orders.amount
FROM customers
INNER JOIN orders ON customers.id = orders.customer_id
WHERE orders.amount >= 5000;
customers 테이블과 orders 테이블의 LEFT OUTER 조인 결과
customers 테이블의 모든 항목을 선택하고, 이를 기준으로 orders 테이블의 레코드를 합치되,
customers 테이블의 레코드 중 orders 테이블의 레코드에 대응되는 레코드가 없는 경우 NULL이 채워짐
SELECT customer.name, orders.id AS order_id, orders.product_id,
orders.quantity, orders.amount
FROM customers
LEFT OUTER JOIN orders ON customers.id = orders.customer_id;
RIGHT OUTER 조인은 LEFT OUTER JOIN과 정확하게 반대
customers 테이블과 orders 테이블의 RIGHT OUTER 조인 결과
orders테이블의 모든 항목을 선택하고, 이를 기준으로 customers 테이블의 레코드를 합치되,
orders 테이블 레코드 중 customers 테이블의 레코드에 대응되는 레코드가 없는 경우 NULL이 채워짐
SELECT customer.name, orders.id AS order_id, orders.product_id,
orders.quantity, orders.amount
FROM customers
RIGHT OUTER JOIN orders ON customers.id = orders.customer_id;
MySQL을 포함한 많은 RDBMS에서는 FULL OUTER 조인 문법을 따로 지원하지 않음
그러나 FULL OUTER 조인 문법을 명시적으로 지원하지 않더라도 LEFT OUTER 조인과 RIGHT OUTER 조인의 결과를 하나로 합치면 FULL OUTER 조인을 구현할 수 있음
이 과정에서 여러 SQL문을 결합하는 키워드인 UNION이 사용될 수 있음
customers 테이블과 orders 테이블을 각각 LEFT OUTER 조인, RIGHT OUTER 조인한 뒤,
그 결과를 하나로 합친 형태로 구현
SELECT customer.name, orders.id AS order_id, orders.product_id,
orders.quantity, orders.amount
FROM customers
LEFT OUTER JOIN orders ON customers.id = orders.customer_id;
UNION
SELECT customer.name, orders.id AS order_id, orders.product_id,
orders.quantity, orders.amount
FROM customers
RIGHT OUTER JOIN orders ON customers.id = orders.customer_id;
products 테이블에 없는 customers 테이블의 레코드가 NULL로 채워지고,
customers 테이블에 없는 products 테이블의 레코드가 NULL로 채워짐
-- 생성
CREATE VIEW 뷰_이름 AS SELECT문;
-- 삭제
DROP VIEW 뷰_이름;
예시
CREATE VIEW myview AS
SELECT users.username, user.email, posts.title
FROM users, posts
WHERE users.user_id = posts.user_id;
myview 뷰는 마치 하나의 논리적인 테이블처럼 활용할 수 있음클러스터형 인덱스: 테이블당 하나씩 만들 수 있는 인덱스
우리가 이미 접해 본 적이 있는 유형의 인덱스(기본 키)
세컨더리 인덱스: 클러스터형 인덱스가 아닌 인덱스. 논클러스터형 인덱스라고도 부름
테이블당 여러 개가 존재할 수 있지만 클러스터형 인덱스를 활용한 검색보다 일반적으로 느림
-- '테이블_이름'의 '필드'에 세컨더리 인덱스인 '인덱스_이름'을 생성
CREATE INDEX 인덱스_이름 ON 테이블_이름 (필드);
-- 인덱스 조회
SHOW INDEX FROM 테이블_이름;
-- 인덱스 삭제
DROP INDEX 인덱스_이름 FROM 테이블_이름;
인덱스로 사용되는 대표적인 자료구조는 해시 테이블과 B 트리
인덱스 활용 상황
- 데이터가 충분히 많은 테이블
- 조회가 자주 이루어지는 테이블
- 특히 JOIN, WHERE, ORDER BY에 자주 사용되는 필드에 적절함
중복값이 많은 필드는 인덱스 효과가 떨어짐
인덱스 개수는 3개 이하가 일반적인 권장 기준
참고: 북스터디 - 이것이 취업을 위한 컴퓨터 과학이다 (Chapter 6-4)