Post

๐ŸฆŠ 7. Database

7. Database

SQL ๋ฌธ์ ‘๊ณผ ๊ทธ ๋ณ€์ข…๋“ค

  • ๋ช…์‹œ์  JOIN
1
2
3
SELECT CourseName, TeacherName
FROM Courses INNER JOIN Teachers
ON Courses.TeacherID = Teachers.TeacherID
  • ๋ฌต์‹œ์  JOIN
1
2
3
SELECT CourseName, TeacherName
FROM Courses, Teachers
WHERE Courses.TeacherID = Teachers.TeacherID

์ด ๋‘˜์€ ๋™๋“ฑํ•˜๋‹ค. ์–ด๋Š ์ชฝ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋ƒ ํ•˜๋Š” ๊ฒƒ์€ ๊ฐœ์ธ ์ทจํ–ฅ์˜ ๋ฌธ์ œ์ด๋‹ค.

๋น„์ •๊ทœํ™” vs. ์ •๊ทœํ™” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค

  • ์ •๊ทœํ™” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค : ์ค‘๋ณต์„ ์ตœ์†Œํ™”ํ•˜๋„๋ก ์„ค๊ณ„๋จ
  • ๋น„์ •๊ทœํ™” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค : ์ฝ๋Š” ์‹œ๊ฐ„์„ ์ตœ์ ํ™”ํ•˜๋„๋ก ์„ค๊ณ„๋จ

Courses ๋‚˜ Teachers ์™€ ๊ฐ™์€ ์ž๋ฃŒ๋ฅผ ํฌํ•จํ•˜๋Š” ์ „ํ˜•์ ์ธ ์ •๊ทœํ™” DB๋Š” ์™ธ๋ž˜ํ‚ค๋ฅผ ๊ฐ–์€ ์ปฌ๋Ÿผ์ด ์žˆ๋‹ค.

์ด ์„ค๊ณ„์˜ ์žฅ์ ์€ ๊ต์‚ฌ ์ •๋ณด๋ฅผ DB์— ํ•œ ๋ฒˆ๋งŒ ์ €์žฅํ•ด๋„ ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๋ฐ˜๋ฉด ์ƒ๋‹น์ˆ˜์˜ ์ผ์ƒ์  ์งˆ์˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด JOIN์„ ๋งŽ์ด ํ•˜๊ฒŒ ๋˜๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

๋น„์ •๊ทœํ™” DB์—์„œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ค‘๋ณตํ•ด์„œ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฐ™์€ ์งˆ์˜๋ฅผ ์ž์ฃผ ๋ฐ˜๋ณตํ•ด์•ผ ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋ฏธ๋ฆฌ ์•Œ๊ณ  ์žˆ์œผ๋ฉด, ๊ต์‚ฌ์˜ ์ด๋ฆ„ ์ •๋ณด๋ฅผ Courses ํ…Œ์ด๋ธ”์— ์ค‘๋ณตํ•ด ์ €์žฅํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

๋†’์€ ๊ทœ๋ชจ ํ™•์žฅ์„ฑ์„ ์‹คํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ฒ•์ด๋‹ค.

SQL ๋ฌธ

1
2
3
4
Courses: CourseID*, CourseName, TeacherID
Teachers: TeacherID*, TeacherName
Students: StudentID*, StudentName
StudentCourses: CourseID*, StudentID*

์งˆ์˜ #1: ํ•™์ƒ ๋“ฑ๋ก

๋ชจ๋“  ํ•™์ƒ์„ ๋ฝ‘๊ณ  ๊ฐ ํ•™์ƒ์ด ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ๊ฐ•์˜๋ฅผ ์ˆ˜๊ฐ•ํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์งˆ์˜๋ฌธ์„ ๋งŒ๋“ค์–ด๋ณด์ž.

  • ๋‹ค๋ฅธ ์งˆ์˜๋ฌธ์œผ๋กœ ๊ฐ์‹ธ๊ธฐ
1
2
3
4
5
6
7
SELECT StudentName, Students.StudentID, Cnt
FROM (
	SELECT Students.StudentID, count(StudentCourses.CourseID) as [cnt]
	FROM Students LEFT JOIN StudentCourses
	ON Students.StudentID = StudentCourses.StudentID
	GROUP BY Students.StudentID
) T INNER JOIN Sudents on T.studentID = Students.StudentID
  • StudentNAme ์„ GROUP BY ์ ˆ์— ์ถ”๊ฐ€ํ•˜๊ธฐ
1
2
3
4
SELECT StudentName, Students.StudentID, count(StudentCourses.CourseID) as [cnt]
FROM Students LEFT JOIN StudentCourses
ON Students.StudentID = StudentCourses.StudentID
GROUP BY Students.StudentID, Students.StudentName
  • ์ง‘ํ•ฉ ํ•จ์ˆ˜๋กœ ๊ฐ์‹ธ๊ธฐ
1
2
3
4
5
SELECT max(StudentName) as [StudentName], Students.StudentID,
									count(StudentCourses.CourseID) as [count]
FROM Students LEFT JOIN StudentCourses
ON Students.StudentID = StudentCourses.StudentID
GROUP BY Students.StudentID

์งˆ์˜ #2: ์ˆ˜๊ฐ•์ƒ ์ˆ˜ ๊ตฌํ•˜๊ธฐ

1
2
3
4
5
6
7
8
SELECT TeacherName, isnull(StudentSize.Number, 0)
FROM Teachers LEFT JOIN
	(SELECT TeacherID, count(StudentCourses.CourseID) AS [Number]
		FROM Courses INNER JOIN StudentCourses
		ON Courses.CourseID = StudnetCourses
		GROUP BY Courses.TeacherID) StudentSize
ON Teachers.TeacherID = StudentSize.TeacherID
ORDER BY StudentSize.Number DESC

์†Œ๊ทœ๋ชจ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค๊ณ„

1๋‹จ๊ณ„: ๋ชจํ˜ธ์„ฑ ์ฒ˜๋ฆฌ

์„ค๊ณ„๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ์ •ํ™•ํžˆ ๋ฌด์—‡์„ ์„ค๊ณ„ํ•ด์•ผ ํ•˜๋Š”์ง€ ์ดํ•ดํ•ด์•ผ ํ•œ๋‹ค.

2๋‹จ๊ณ„: ํ•ต์‹ฌ ๊ฐ์ฒด ์ •์˜

๊ทธ ๋‹ค์Œ์œผ๋กœ, ์ด ์‹œ์Šคํ…œ์˜ ํ•ต์‹ฌ ๊ฐ์ฒด๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์‚ดํŽด๋ณธ๋‹ค.

ํ•ต์‹ฌ ๊ฐ์ฒด ํ•˜๋‚˜๋‹น ๋ณดํ†ต ํ•˜๋‚˜์˜ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•œ๋‹ค.

3๋‹จ๊ณ„: ๊ด€๊ณ„ ๋ถ„์„

ํ•ต์‹ฌ ๊ฐ์ฒด์˜ ์œค๊ณฝ์„ ์žก๊ณ  ๋‚˜๋ฉด ํ…Œ์ด๋ธ”๋ผ๋ฆฌ ์–ด๋–ค ๊ด€๊ณ„๊ฐ€ ์žˆ์„์ง€ ์‚ดํŽด๋ณธ๋‹ค.

4๋‹จ๊ณ„: ํ–‰์œ„ ์กฐ์‚ฌ

ํ”ํ•˜๊ฒŒ ์ˆ˜ํ–‰๋  ์ž‘์—…๋“ค์„ ์‚ดํŽด๋ณด๊ณ  ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ป๊ฒŒ ์ €์žฅํ•˜๊ณ  ๊ฐ€์ ธ์˜ฌ ๊ฒƒ์ธ์ง€ ์ดํ•ดํ•ด์•ผ ํ•œ๋‹ค.

๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค๊ณ„

๋Œ€๊ทœ๋ชจ์˜ ๊ทœ๋ชจ ํ™•์žฅ์„ฑ์ด ๋†’์€ DB๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ์— JOIN ์—ฐ์‚ฐ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์•„์ฃผ ๋Š๋ฆฌ๋‹ค๊ณ  ๊ฐ„์ฃผํ•ด์•ผ ํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋น„์ •๊ทœํ™”ํ•ด์•ผ ํ•œ๋‹ค.

๋ฉด์ ‘ ๋ฌธ์ œ

14.1 ํ•˜๋‚˜ ์ด์ƒ์˜ ์ง‘

ํ•˜๋‚˜ ์ด์ƒ์˜ ์ง‘์„ ๋Œ€์—ฌํ•œ ๋ชจ๋“  ๊ฑฐ์ฃผ์ž์˜ ๋ชฉ๋ก์„ ๊ตฌํ•˜๋Š” SQL ์งˆ์˜๋ฌธ์„ ์ž‘์„ฑํ•˜๋ผ.

1
2
3
4
5
SELECT *
FROM Tenants
INNER JOIN TenantApartments
ON Tenants.TenantID = TenantApartments
GROUP BY Tenents.TenentID

14.2 Open ์ƒํƒœ์ธ Request

๋ชจ๋“  ๊ฑด๋ฌผ ๋ชฉ๋ก๊ณผ Status ๊ฐ€ Open ์ธ ๋ชจ๋“  Request ๊ฐœ์ˆ˜๋ฅผ ๊ตฌํ•˜๋ผ.

1
2
3
4
5
6
SELECT Buildings.BuildingName, count(*) as [cnt]
FROM Buildings
INNER JOIN Requests
ON Buildings.BuildingID = Requests.BuildingID
	and Requests.status = 'Open'
GROUP BY Building.BuildingID

14.3 Request ๋ฅผ Close๋กœ ๋ฐ”๊พธ๊ธฐ

11๋ฒˆ ๋นŒ๋”ฉ์—์„œ ๋Œ€๊ทœ๋ชจ ๋ฆฌ๋ชจ๋ธ๋ง ๊ณต์‚ฌ๋ฅผ ์ง„ํ–‰ ์ค‘์ด๋‹ค.

์ด ๊ฑด๋ฌผ์— ์žˆ๋Š” ๋ชจ๋“  ์ง‘์— ๋Œ€ํ•œ ๋ชจ๋“  Request ์˜ Status ๋ฅผ Close ๋กœ ๋ณ€๊ฒฝํ•ด์ฃผ๋Š” ์งˆ์˜๋ฌธ์„ ์ž‘์„ฑํ•˜๋ผ.

1
2
3
UPDATE Requests
SET Status = 'Close'
WHERE Requests.BuildingID = 11

14.4 JOIN

์„œ๋กœ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ JOIN ์€ ์–ด๋–ค ๊ฒƒ๋“ค์ด ์žˆ๋Š”๊ฐ€? ๊ฐ๊ฐ์ด ์–ด๋–ป๊ฒŒ ๋‹ค๋ฅด๊ณ , ์–ด๋–ค ์ƒํ™ฉ์—์„œ ์–ด๋–ค JOIN ๊ณผ ์–ด์šธ๋ฆฌ๋Š”์ง€ ์„ค๋ช…ํ•˜๋ผ.

  • LEFT JOIN : ๊ธฐ์ค€ ํ…Œ์ด๋ธ”์—์„œ ๋งคํ•‘๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ™์ž„, ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ๋Š” NULL ์ฒ˜๋ฆฌ
  • RIGHT JOIN : ์ƒ๋Œ€ ํ…Œ์ด๋ธ”์—์„œ ๋งคํ•‘๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ด. ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ธฐ์ค€ ๋ฐ์ดํ„ฐ๋Š” NULL ์ฒ˜๋ฆฌ
  • INNER JOIN : ๊ต์ง‘ํ•ฉ, ์„œ๋กœ ๋งคํ•‘๋˜๋Š” ๊ฒƒ๋งŒ ์กฐํšŒ, ๋‚˜๋จธ์ง€๋Š” ์‚ฌ๋ผ์ง
  • FULL JOIN : ํ•ฉ์ง‘ํ•ฉ, ๋‘ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ๊ฐ€์ ธ์˜ด

14.5 ๋น„์ •๊ทœํ™”

๋น„์ •๊ทœํ™”๋ž€ ๋ฌด์—‡์ธ๊ฐ€? ๊ทธ ์žฅ๋‹จ์ ์„ ์„ค๋ช…ํ•˜๋ผ.

DB ์—์„œ์˜ ์ค‘๋ณต์œผ๋กœ ์กด์žฌํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํ—ˆ์šฉํ•จ

๋ฐ์ดํ„ฐ์˜ ์ค‘๋ณต์œผ๋กœ ์ผ๊ด€์„ฑ์ด ์—†์–ด์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, JOIN ์„ ํ•˜์ง€ ์•Š์•„ ์ฝ๊ธฐ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋จ.

14.6 ๊ฐœ์ฒด-๊ด€๊ณ„ ๋‹ค์ด์–ด๊ทธ๋žจ

ํšŒ์‚ฌ, ์‚ฌ๋žŒ, ์ง์›์œผ๋กœ ๊ตฌ์„ฑ๋œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ER ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๊ทธ๋ ค๋ผ.

1
2
3
4
5
6
7
8
companyID   BIGINT
companyName VARCHAR(50)

personID    BIGINT
personeName VARCHAR(50)

employee    BIGINT
employeeName VARCHAR(50)
This post is licensed under CC BY 4.0 by the author.