관계형 데이터 베이스 디자인의 기본원리
판매처 정보 (Vendors) 테이블 | |
---|---|
판매처1 | 판매처 ID = 식별자1 |
판매처2 | 판매처 ID = 식별자2 |
판매처3 | 판매처 ID = 식별자3 |
각 행은 판매처를 구별할 수 있는 고유한 식별자
를 갖는다. 이런 값을 기본키(Primary Key)
라고 부른다.
여기서는 판매처 ID를 기본 키로 사용했다.
제품 정보 (Products) 테이블 | |
---|---|
제품 정보1 | 판매처 ID = 식별자1 |
제품 정보2 | 판매처 ID = 식별자2 |
제품 정보3 | 판매처 ID = 식별자3 |
판매처 ID는 Vendors 테이블과 Products 테이블을 연결하는데, 이 키를 이용해 Vendors 테이블에서 제품 정보를 찾을 수 있다.
조인은 SELECT 문 안에서 테이블을 연결할 때 사용한다.
특별한 문법을 사용해서 여러 개의 테이블을 조인하면, 하나의 결과를 가져올 수 있다.
조인은 각 테이블에서 적절한 행을 서로 연결하는 역할을 한다.
=> 조인은 데이터베이스 테이블에서 실제로 존재하지 않는다. DBMS에서 필요할 때 생성하고, 쿼리가 수행되는 동안에만 유지된다.
두 개의 테이블을 조인할 때, 할 일은 첫 번째 테이블의 행과 두 번째 테이블을 행으로 짝을 짓는 것이다. WHERE 절은 필터로 동작해 지정한 조건과 일치하는 행만 가져온다. WHERE 절이 없다면 첫 번째 테이블에 있는 모든 행은 두 번째 테이블에 있는 모든 행과 짝이 된다.
따라서 조인을 사용할 때 WHERE 절이 있는지 꼭 확인하자.
SELECT vend_name, prod_name, prod_price
FROM Vendors, Products
WHERE Vendors.vend_id = Products.vend_id;
여기서 사용한 조인은 동등 조인 혹은 이퀴 조인(Equi-Join)이라고 하는데, 이 조인은 두 개의 테이블에 있는 공통 열의 값이 같은 것을 결과로 가져온다. 이런 종류의 조인을 내부 조인(Inner Join)이라고도 부른다.
조인 타입을 표시할 때는 다른 문법을 사용해야 한다.
SELECT vend_name, prod_name, prod_price
FROM Vendors INNER JOIN Products
ON Vendors.vend_id = Products.vend_id;
SELECT prod_name, vend_name, prod_price, quantity
FROM OrderItems, Products, Vendors
WHERE Products.vend_id = Vendors.vend_id
AND OrderItems.prod_id = Products.prod_id
AND order_num = 20007;
✔️ 성능에 대한 고려
테이블을 연결하는 조인은 많은 테이블을 조인할 수록 성능이 저하되므로 불필요한 테이블을 조인하지 않도록 주의하자.
-- 이퀴 조인
SELECT cust_name, order_num
FROM Customers, Orders
WHERE Customers.cust_id = Orders.cust_id
ORDER BY cust_name, order_num;
-- 내부 조인
SELECT cust_name, order_num
FROM Customers INNER JOIN Orders
ON Customers.cust_id = Orders.cust_id
ORDER BY cust_name, order_num;
⭐열 이름이 같을 경우 오류가 나므로 완전한 열 이름을 사용하자⭐
-- 서브쿼리
SELECT cust_name, order_num, ( SELECT SUM(quantity * item_price)
FROM OrderItems
WHERE Orders.order_num = OrderItems.order_num ) AS OrderTotal
FROM Customers, Orders
WHERE Customers.cust_id = Orders.cust_id
ORDER BY cust_name, order_num;
-- 그룹 함수
SELECT cust_name, Orders.order_num, SUM(quantity * item_price) AS OrderTotal
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_id
AND Orders.order_num = OrderItems.order_num
GROUP BY cust_name, Orders.order_num
ORDER BY cust_name, order_num;
SELECT cust_id, order_date
FROM Orders, OrderItems
WHERE Orders.order_num = OrderItems.order_num
AND prod_id = 'BR01'
ORDER BY order_date;
⭐두 개의 내부 조인 사용법을 익혀두자⭐
SELECT cust_email
FROM Customers
INNER JOIN Orders ON Customers.cust_id = Orders.cust_id
INNER JOIN OrderItems ON Orders.order_num = OrderItems.order_num
WHERE prod_id = 'BR01';
-- 이퀴 조인
SELECT cust_name, SUM(quantity * item_price) AS sum_total
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_id
AND Orders.order_num = OrderItems.order_num
GROUP BY cust_name
HAVING SUM(quantity * item_price) >= 1000
ORDER BY cust_name;
-- 내부 조인
SELECT cust_name, SUM(quantity * item_price) AS sum_total
FROM Customers
INNER JOIN Orders ON Customers.cust_id = Orders.cust_id
INNER JOIN OrderItems ON Orders.order_num = OrderItems.order_num
GROUP BY cust_name
HAVING SUM(quantity * item_price) >= 1000
ORDER BY cust_name;