๐ books & category ์ฐ๊ด๊ด๊ณ ์ค์

๋์ ์กฐํํ ๋ ์นดํ ๊ณ ๋ฆฌ ํ ์ด๋ธ๊ณผ ์กฐ์ธํ์ฌ ์นดํ ๊ณ ๋ฆฌ๋ช ์ ์ถ๋ ฅํ ์ ์๋๋ก FK ์ค์
- Foreign Key Name : ์ฐ๊ด๊ด๊ณ๋ช
- Referenced Table : ์ฐ๊ฒฐํ ํ ์ด๋ธ
- Column : ํ์ฌ ์ ํ๋ ํ ์ด๋ธ ์ปฌ๋ผ ์ค FK๋ก ์ค์ ํ ์ปฌ๋ผ
- Referenced Column : Referenced Table์ ์ปฌ๋ผ ์ค ์ฐ๊ฒฐํ ์ปฌ๋ผ ์ ํ

์ด์ books์ ์นดํ ๊ณ ๋ฆฌ id๊ฐ๊ณผ category์ id๊ฐ์ด ๋์ผํ ๊ฒฝ์ฐ ์กฐ์ธํ ์ ์๊ฒ ๋์๋ค.
* ์ปฌ๋ผ๋ช ๋ง ๋ ๋ช ํํ๊ฒ ํ๊ธฐ ์ํด category์ name ์ปฌ๋ผ์ category_name์ผ๋ก ๋ณ๊ฒฝํด์ฃผ์๋ค.
let sql = `SELECT * FROM books LEFT JOIN category
ON books.category_id = category.id WHERE books.id=?`;

์ฝ๋์๋ JOIN๋ฌธ์ ์ ์ฉํด์ฃผ๋ฉด ์นดํ ๊ณ ๋ฆฌ๋ช ๊น์ง ์ ์ถ๋ ฅ๋๋ค.
โฐ SQL ์๊ฐ ๋ฒ์
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์๊ฐ์ ๋ฒ์๋ฅผ ๊ตฌํ๋ ๋ฐฉ๋ฒ
1. ์๊ฐ ๋ํ๊ธฐ (์ดํ)
DATE_ADD(๊ธฐ์ค๋ ์ง, INTERVAL ๊ฐ๊ฒฉ)


2. ์๊ฐ ๋นผ๊ธฐ (์ด์ )
DATE_SUB(๊ธฐ์ค๋ ์ง, INTERVAL ๊ฐ๊ฒฉ)

๊ธฐ์ค ๋ ์ง๋ฅผ NOW()๋ก ์ค์ ํ๋ฉด ํ์ฌ ๋ ์ง๋ฅผ ๊ธฐ์ค์ผ๋ก ์ก์์ค๋ค.
๊ทธ๋ผ ํ ๋ฌ์ด๋ด ์ถ๊ฐ๋ ๋์๋ฅผ ์ ๊ฐ์ด๋ผ ํ ๋, ์ ๊ฐ์ ์กฐํํ๋ SQL๋ฌธ์ ๋ค์๊ณผ ๊ฐ๋ค.
SELECT * FROM books
WHERE pub_date
BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH)
AND NOW();
- pub_date๊ฐ ํ ๋ฌ ์ ๋ถํฐ ํ์ฌ ์ฌ์ด์ธ ๋์๋ฅผ ์กฐํ

๐ ์นดํ ๊ณ ๋ฆฌ, ์ ๊ฐ ์ฌ๋ถ์ ๋ฐ๋ฅธ ๋์ ๋ชฉ๋ก ์กฐํ
SELECT * FROM books
WHERE category_id = 0 AND
pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW();
SQL๋ฌธ์์ WHERE์ ์ ์กฐ๊ฑด ๋ ๊ฐ๋ฅผ ์ฐ๋ ค๋ฉด AND ์ฌ์ฉํด ์ฐ๊ฒฐํด์ฃผ๋ฉด ๋๋ค.
๐ ๋์ ๋ชฉ๋ก ์กฐํ ํ์ด์ง
ํ์ด์ง (paging)
: ๋ช ๊ฐ์ฉ ๋ณด์ฌ์ค ๊ฒ์ธ๊ฐ, ์ฆ ๋ฐ์ดํฐ๋ฅผ ์ชผ๊ฐ์ ํ์ํ ๊ฐ์๋งํผ ์ฉ ๋ณด๋ด์ฃผ๋ ๊ฒ

์๋ SELECT ์คํ ์ ์ ์ฒด ๋ฐ์ดํฐ๊ฐ ์ถ๋ ฅ๋๋ค.
SELECT * FROM books LIMIT ์ซ์ OFFSET ์ซ์;
- LIMIT : ์ถ๋ ฅํ ํ์ ์
- OFFSET : ์์ ์ง์ ( = ๋ด๊ฐ ์ง๊ธ ๋ช ํ์ด์ง๋๋ผ?)
- ์ ์ฌ์ง ์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ฉด ์ฒซ๋ฒ์งธ ๋ฐ์ดํฐ์ id๋ 1์ด์ง๋ง ์ด๊ฑด ๋ด๊ฐ ์ค์ ํ ๊ฐ
- ์ฒซ ๋ฒ์งธ ์ค์ ํญ์ 0๋ฒ์งธ ๋ฐ์ดํฐ !


SELECT * FROM books LIMIT 4 OFFSET 8;
SELECT * FROM books LIMIT 8, 4;
์ด ์ฒ๋ผ ์ค์ฌ์ ์์ฑํ ์๋ ์๋ค.
๋จ, ์๋์ค์ฒ๋ผ ์ค์ฌ์ ์์ฑํ ๋์๋ OFFSET๊ฐ์ด ๋จผ์ ์จ๋ค๋ ์ ์ ์ฃผ์ํด์ผํ๋ค.
๊ทธ๋ผ ์ด์ ํ๋ก ํธ์์ ๋ช ๊ฐ์ฉ, ์ด๋์๋ถํฐ ๋ฐ์ ๊ฒ์ธ์ง ์์ฒญํ๋๋ก ํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
๊ทธ๋ฐ๋ฐ OFFSET๊ฐ์ ์ง์ ๋ฐ๊ธฐ๋ณด๋จ ํ์ฌ ํ์ด์ง๋ฅผ ๋ฐ์์ ๋ฐฑ์์ ๊ณ์ฐํด์ฃผ๋ ํธ์ด ์ข์ ๊ฒ ๊ฐ๋ค.
์ด๋ป๊ฒ?
offset = limit * (currentPage - 1)
์๋ ๊ฒ
์ฟผ๋ฆฌ๋ฅผ ํตํด limit๊ณผ currentPage ๊ฐ์ ๋ฐ์์ค๊ธด ํ์ง๋ง ๋ฌธ์ ๋ ๋ฌธ์์ด๋ก ๋ฐ์์ง๋ค๋ ๊ฒ์ด๋ค.
SQL๋ฌธ์ ์ซ์ ๋์ ๋ฌธ์์ด๋ก ๋ค์ด๊ฐ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
๊ทธ๋ฌ๋ ์ซ์๋ก ๋ฐ๊ฟ์ฃผ๋ ์์ ์ด ํ์ํ๋ค.
let values = [parseInt(limit), offset];
์ offset์ ์๋ฐ๊ฟ์คฌ๋?
์์์ ์์์ ํตํด ๋ง๋ค์ด์ค ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ์์์ ํ๋ณํ์ด ๋์๊ธฐ ๋๋ฌธ์ด๋ค.

์ด์ ๋ฐ์ดํฐ๋ค์ด ํ์ด์ง๋์ด ์ ์ถ๋ ฅ๋๋ค.
๐ LIMIT OFFSET๋ฌธ์ด WHERE์ ์์ผ๋ก ๊ฐ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๋ฐ๋์ WHERE์ ๋ค์ ์์ฑ.
let sql = 'SELECT * FROM books ';
let values = [];
if(category_id && news) {
sql += 'WHERE category_id=? AND pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()';
values = [category_id];
}
else if(category_id) {
sql += 'WHERE category_id=?';
values = [category_id];
}
else if(news) {
sql += 'WHERE pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()';
}
sql += ' LIMIT ? OFFSET ?';
values.push(parseInt(limit), offset);


'๐๏ธ DevCourse > Backend' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[TIL] Week 9 ์ฅ๋ฐ๊ตฌ๋ API (2) | 2025.03.17 |
---|---|
[TIL] Week 8 ๋์ ์์ ์ข์์ API (2) | 2025.03.15 |
[TIL] Week 8 ๋์ API (1) | 2025.03.13 |
[TIL] Week 8 ์ปจํธ๋กค๋ฌ & ๋น๋ฐ๋ฒํธ ์ํธํ (1) | 2025.03.12 |
[TIL] Week 8 Express-generator ๊ตฌ์กฐ & ๋์ ์์ API ๊ธฐ๋ณธ ์ธํ (3) | 2025.03.11 |
๐ books & category ์ฐ๊ด๊ด๊ณ ์ค์

๋์ ์กฐํํ ๋ ์นดํ ๊ณ ๋ฆฌ ํ ์ด๋ธ๊ณผ ์กฐ์ธํ์ฌ ์นดํ ๊ณ ๋ฆฌ๋ช ์ ์ถ๋ ฅํ ์ ์๋๋ก FK ์ค์
- Foreign Key Name : ์ฐ๊ด๊ด๊ณ๋ช
- Referenced Table : ์ฐ๊ฒฐํ ํ ์ด๋ธ
- Column : ํ์ฌ ์ ํ๋ ํ ์ด๋ธ ์ปฌ๋ผ ์ค FK๋ก ์ค์ ํ ์ปฌ๋ผ
- Referenced Column : Referenced Table์ ์ปฌ๋ผ ์ค ์ฐ๊ฒฐํ ์ปฌ๋ผ ์ ํ

์ด์ books์ ์นดํ ๊ณ ๋ฆฌ id๊ฐ๊ณผ category์ id๊ฐ์ด ๋์ผํ ๊ฒฝ์ฐ ์กฐ์ธํ ์ ์๊ฒ ๋์๋ค.
* ์ปฌ๋ผ๋ช ๋ง ๋ ๋ช ํํ๊ฒ ํ๊ธฐ ์ํด category์ name ์ปฌ๋ผ์ category_name์ผ๋ก ๋ณ๊ฒฝํด์ฃผ์๋ค.
let sql = `SELECT * FROM books LEFT JOIN category
ON books.category_id = category.id WHERE books.id=?`;

์ฝ๋์๋ JOIN๋ฌธ์ ์ ์ฉํด์ฃผ๋ฉด ์นดํ ๊ณ ๋ฆฌ๋ช ๊น์ง ์ ์ถ๋ ฅ๋๋ค.
โฐ SQL ์๊ฐ ๋ฒ์
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์๊ฐ์ ๋ฒ์๋ฅผ ๊ตฌํ๋ ๋ฐฉ๋ฒ
1. ์๊ฐ ๋ํ๊ธฐ (์ดํ)
DATE_ADD(๊ธฐ์ค๋ ์ง, INTERVAL ๊ฐ๊ฒฉ)


2. ์๊ฐ ๋นผ๊ธฐ (์ด์ )
DATE_SUB(๊ธฐ์ค๋ ์ง, INTERVAL ๊ฐ๊ฒฉ)

๊ธฐ์ค ๋ ์ง๋ฅผ NOW()๋ก ์ค์ ํ๋ฉด ํ์ฌ ๋ ์ง๋ฅผ ๊ธฐ์ค์ผ๋ก ์ก์์ค๋ค.
๊ทธ๋ผ ํ ๋ฌ์ด๋ด ์ถ๊ฐ๋ ๋์๋ฅผ ์ ๊ฐ์ด๋ผ ํ ๋, ์ ๊ฐ์ ์กฐํํ๋ SQL๋ฌธ์ ๋ค์๊ณผ ๊ฐ๋ค.
SELECT * FROM books
WHERE pub_date
BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH)
AND NOW();
- pub_date๊ฐ ํ ๋ฌ ์ ๋ถํฐ ํ์ฌ ์ฌ์ด์ธ ๋์๋ฅผ ์กฐํ

๐ ์นดํ ๊ณ ๋ฆฌ, ์ ๊ฐ ์ฌ๋ถ์ ๋ฐ๋ฅธ ๋์ ๋ชฉ๋ก ์กฐํ
SELECT * FROM books
WHERE category_id = 0 AND
pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW();
SQL๋ฌธ์์ WHERE์ ์ ์กฐ๊ฑด ๋ ๊ฐ๋ฅผ ์ฐ๋ ค๋ฉด AND ์ฌ์ฉํด ์ฐ๊ฒฐํด์ฃผ๋ฉด ๋๋ค.
๐ ๋์ ๋ชฉ๋ก ์กฐํ ํ์ด์ง
ํ์ด์ง (paging)
: ๋ช ๊ฐ์ฉ ๋ณด์ฌ์ค ๊ฒ์ธ๊ฐ, ์ฆ ๋ฐ์ดํฐ๋ฅผ ์ชผ๊ฐ์ ํ์ํ ๊ฐ์๋งํผ ์ฉ ๋ณด๋ด์ฃผ๋ ๊ฒ

์๋ SELECT ์คํ ์ ์ ์ฒด ๋ฐ์ดํฐ๊ฐ ์ถ๋ ฅ๋๋ค.
SELECT * FROM books LIMIT ์ซ์ OFFSET ์ซ์;
- LIMIT : ์ถ๋ ฅํ ํ์ ์
- OFFSET : ์์ ์ง์ ( = ๋ด๊ฐ ์ง๊ธ ๋ช ํ์ด์ง๋๋ผ?)
- ์ ์ฌ์ง ์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ฉด ์ฒซ๋ฒ์งธ ๋ฐ์ดํฐ์ id๋ 1์ด์ง๋ง ์ด๊ฑด ๋ด๊ฐ ์ค์ ํ ๊ฐ
- ์ฒซ ๋ฒ์งธ ์ค์ ํญ์ 0๋ฒ์งธ ๋ฐ์ดํฐ !


SELECT * FROM books LIMIT 4 OFFSET 8;
SELECT * FROM books LIMIT 8, 4;
์ด ์ฒ๋ผ ์ค์ฌ์ ์์ฑํ ์๋ ์๋ค.
๋จ, ์๋์ค์ฒ๋ผ ์ค์ฌ์ ์์ฑํ ๋์๋ OFFSET๊ฐ์ด ๋จผ์ ์จ๋ค๋ ์ ์ ์ฃผ์ํด์ผํ๋ค.
๊ทธ๋ผ ์ด์ ํ๋ก ํธ์์ ๋ช ๊ฐ์ฉ, ์ด๋์๋ถํฐ ๋ฐ์ ๊ฒ์ธ์ง ์์ฒญํ๋๋ก ํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
๊ทธ๋ฐ๋ฐ OFFSET๊ฐ์ ์ง์ ๋ฐ๊ธฐ๋ณด๋จ ํ์ฌ ํ์ด์ง๋ฅผ ๋ฐ์์ ๋ฐฑ์์ ๊ณ์ฐํด์ฃผ๋ ํธ์ด ์ข์ ๊ฒ ๊ฐ๋ค.
์ด๋ป๊ฒ?
offset = limit * (currentPage - 1)
์๋ ๊ฒ
์ฟผ๋ฆฌ๋ฅผ ํตํด limit๊ณผ currentPage ๊ฐ์ ๋ฐ์์ค๊ธด ํ์ง๋ง ๋ฌธ์ ๋ ๋ฌธ์์ด๋ก ๋ฐ์์ง๋ค๋ ๊ฒ์ด๋ค.
SQL๋ฌธ์ ์ซ์ ๋์ ๋ฌธ์์ด๋ก ๋ค์ด๊ฐ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
๊ทธ๋ฌ๋ ์ซ์๋ก ๋ฐ๊ฟ์ฃผ๋ ์์ ์ด ํ์ํ๋ค.
let values = [parseInt(limit), offset];
์ offset์ ์๋ฐ๊ฟ์คฌ๋?
์์์ ์์์ ํตํด ๋ง๋ค์ด์ค ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ์์์ ํ๋ณํ์ด ๋์๊ธฐ ๋๋ฌธ์ด๋ค.

์ด์ ๋ฐ์ดํฐ๋ค์ด ํ์ด์ง๋์ด ์ ์ถ๋ ฅ๋๋ค.
๐ LIMIT OFFSET๋ฌธ์ด WHERE์ ์์ผ๋ก ๊ฐ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๋ฐ๋์ WHERE์ ๋ค์ ์์ฑ.
let sql = 'SELECT * FROM books ';
let values = [];
if(category_id && news) {
sql += 'WHERE category_id=? AND pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()';
values = [category_id];
}
else if(category_id) {
sql += 'WHERE category_id=?';
values = [category_id];
}
else if(news) {
sql += 'WHERE pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()';
}
sql += ' LIMIT ? OFFSET ?';
values.push(parseInt(limit), offset);


'๐๏ธ DevCourse > Backend' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[TIL] Week 9 ์ฅ๋ฐ๊ตฌ๋ API (2) | 2025.03.17 |
---|---|
[TIL] Week 8 ๋์ ์์ ์ข์์ API (2) | 2025.03.15 |
[TIL] Week 8 ๋์ API (1) | 2025.03.13 |
[TIL] Week 8 ์ปจํธ๋กค๋ฌ & ๋น๋ฐ๋ฒํธ ์ํธํ (1) | 2025.03.12 |
[TIL] Week 8 Express-generator ๊ตฌ์กฐ & ๋์ ์์ API ๊ธฐ๋ณธ ์ธํ (3) | 2025.03.11 |