정규화 Normalization와 조인 Join
1. 정규형
: 데이터베이스의 테이블에 담기는 데이터를 적절하게 나누어 구조화 하는 방법론
1) 초기 데이터 (상품관리 테이블)
>> 기본적으로 각 레코드가 중복되지 않은, 정규화가 전혀 진행되지 않은 상태.
>> 수령 방식은 하나의 레코드에 복수의 속성값을 정의하고 있다...
반복해서 등장할 수 있는 데이터를 뽑아 다른 테이블에 넣어주자~~~~!
2) 제1 정규형
** 하나의 컬럼이 복수의 데이터를 가지고 있지 않아야 한다!
>> 제1 정규형 테이블 두개.
3) 제2 정규형
** 기본키에 종속되지 않는 컬럼은 테이블에서 분리되어야 한다.
4) 제3 정규형
** 기본키가 아닌 다른 속성에 종속성을 갖는 컬럼은 별도로 분리해야 한다.
>> 제조사 국적은 상품 자체가 아닌, 제조사와 종속적인 관계!
2. JOIN 절
~> 나눠진 테이블을 다시 합칠 때...?
>> 왼쪽 테이블의 제조사 id는 오른쪽 테이블의 id를 의미
- 자신의 테이블이 아닌 테이블의 key ==> 외래키
한쪽 테이블의 레코드에 다른 테이블의 기본키를 가르키는 외래키를 기준으로 연결. = 두개의 테이블을 JOIN 한다.
1) RDB에서의 관계
- 1:1 One to One 관계
: 한 테이블의 레코드 하나가 다른 테이블의 레코드 하나와 연관된 관계
특정 데이터를 성능 또는 보안적 측면에서 나눌 때 사용
- N:1 Many to One 관계
: 한 테이블의 레코드 0개 이상이 다른 테이블의 레코드 하나와 연관된 관계
일반적인 데이터베이스의 흔한 관계
ex. 게시글 - 댓글, 가게 - 상품 등
- M:N Many to Many 관계
: 한 테이블의 레코드 0개 이상이 다른 테이블의 레코드 0개 이상과 연관된 관계
양쪽 테이블의 PK를 FK로 가진 Join Table, Associative Table 활용
1) CROSS JOIN
: 연관관계와 상관없이 양쪽 테이블의 레코드를 각각 짝지은 결과
- 곱집합, Cartesian Product
SELECT *
FROM lecture, instructor;
2) INNER JOIN
: 양쪽 테이블 모두 존재하는 데이터에 대해서, ON 절의 조건을 기준으로 JOIN
- INNER는 생략 가능
SELECT *
FROM lecture INNER JOIN instructor
ON lecture.instructor_id = instructor.id;
> 만약 한쪽 테이블의 레코드가 없다면, 반대쪽의 레코드도 나오지 않음.
3) OUTER JOIN
: 삭제, 누락된 데이터를 함께 보고 싶다면 OUTER JOIN 활용
- 존재하지 않는 쪽은 NULL로 표시됨.
- RIGHT / LEFT에 따라 어떤 테이블 데이터가 누락되지 않을지를 결정.
>> LEFT JOIN : 왼쪽만 있는 데이터도 모두 표시
RIGHT JOIN : 오른쪽만 있는 데이터도 모두 표시
- FULL OUTER JOIN : LEFT, RIGHT 둘다 조회, 없는 컬럼은 전부 NULL
SELECT *
FROM instructor LEFT OUTER JOIN lecture
ON instructor.id = lecture.instructor_id; --왼쪽(instructor)만 있는 데이터도 모두 표시
SELECT *
FROM student RIGHT OUTER JOIN instructor
ON student.advisor_id = instructor.id; --오른쪽(instructor)만 있는 데이터도 모두 표시
SELECT *
FROM student RIGHT JOIN instructor
ON student.advisor_id = instructor.id;
SELECT *
FROM student FULL OUTER JOIN instructor
ON student.advisor_id = instructor.id;
4) Many To Many
- 한 번의 FROM에서 여러 번 JOIN을 진행해보자
SELECT student.id, s.first_name, s.last_name, l.name
FROM student
INNER JOIN attending_lectures
ON student.id = attending_lectures.student_id
INNER JOIN lecture
ON attending_lectures.attending_id = lecture.id
ORDER BY student.id;
SELECT student.id, s.first_name, s.last_name, l.name
FROM student
LEFT JOIN attending_lectures
ON student.id = attending_lectures.student_id
LEFT JOIN lecture
ON attending_lectures.attending_id = lecture.id
ORDER BY student.id;
5) 그 외
- SQL의 결과는 테이블 형태로 돌아온다.
- JOIN으로 반환된 결과를 바탕으로 본래의 SQL 문법 활용 가능.
SELECT lecture.name, instructor.first_name, instructor.last_name
FROM lecture INNER JOIN instructor
ON lecture.instructor_id = instructor.id
WHERE lecture.day = 'tue';
- 테이블의 이름을 좀더 간결하게 사용 가능.
SELECT s.id, s.first_name, s.last_name, l.name
FROM student s
LEFT JOIN attending_lectures a ON s.id = a.student_id
LEFT JOIN lecture l ON a.attending_id = l.id
ORDER BY s.id;
- JOIN의 결과를 다시 쿼리문 내부에 데이터로 활용 가능. (서브쿼리)
SELECT s.id AS student_id, s.first_name AS student_first_name, s.last_name AS student_last_name, subquery.name AS lecture
FROM student s
LEFT JOIN (
SELECT al.student_id, l.name
FROM attending_lectures al
JOIN lecture l ON al.attending_id = l.id
WHERE l.instructor_id = 2
) subquery ON s.id = subquery.student_id;
'Programming > Database' 카테고리의 다른 글
Transaction (0) | 2024.02.02 |
---|---|
JDBC (1) | 2023.12.20 |
[연습문제 모음] (0) | 2023.12.18 |
Database 기초 (0) | 2023.12.18 |
JDBC와 DBCP(DataBase Connection Pool) (0) | 2023.09.15 |