SQL - MySQL, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ •๊ทœํ™”, Foreign Key, JOIN

2026. 3. 25. 11:07ยท๐Ÿงฉ SQL

MySQL

 

 

โœ… ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ •๊ทœํ™”๋ž€? (Normalization)


๋ฐ์ดํ„ฐ ์ค‘๋ณต์„ ์ค„์ด๊ณ , ๊ตฌ์กฐ๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด ๋ฌด๊ฒฐ์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ์„ค๊ณ„ ๋ฐฉ๋ฒ•

 

โ‘  ์ œ1์ •๊ทœํ˜• (1NF)

์ปฌ๋Ÿผ์€ ์›์ž๊ฐ’(Atomic)๋งŒ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค

 

 

 

โ‘ก ์ œ2์ •๊ทœํ˜• (2NF)

๋ถ€๋ถ„ ํ•จ์ˆ˜ ์ข…์† ์ œ๊ฑฐ

 

 

โ‘ข ์ œ3์ •๊ทœํ˜• (3NF)

์ดํ–‰์  ์ข…์† ์ œ๊ฑฐ

 

 

โœ… Foreign Key


๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์˜ Primary Key๋ฅผ ์ฐธ์กฐํ•˜๋Š” Column

 

CREATE TABLE dogs (
    dog_id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL, weight DECIMAL(5, 2),
    date_of_birth DATE,
    owner_id BIGINT UNSIGNED,
    breed_id BIGINT UNSIGNED
);

owner_id์™€ breed_id๋Š” Foreign Key

 

Foreign Key Constraint

CREATE TABLE dogs (
	dog_id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(50) NOT NULL,
	weight DECIMAL(5, 2),
	date_of_birth DATE,
	owner_id BIGINT UNSIGNED,
	breed_id BIGINT UNSIGNED,
	FOREIGN KEY (owner_id) REFERENCES owners (owner_id),
	CONSTRAINT breed_fk FOREIGN KEY (breed_id) REFERENCES breeds (breed_id)
);

Foreign Key Constraint๋„ ์ด๋ฆ„์„ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.(์ถ”ํ›„์— ์ œ์•ฝ์„ ์‚ญ์ œํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์ด๋ฆ„์œผ๋กœ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋‹ค.)

 

 

ON DELETE

FOREIGN KEY (owner_id) REFERENCES owners (owner_id) ON DELETE CASCADE,

owner๊ฐ€ ์‚ญ์ œ ๋์„ ๋•Œ ํ•ด๋‹น dog๋„ ์‚ญ์ œ.

(owner_id๊ฐ€ update ๋˜์—ˆ์„ ๋•Œ ์„ค์ •์ด ๊ฐ€๋Šฅํ•œ ON UPDATE๋„ ์žˆ์ง€๋งŒ id๊ฐ€ ์—…๋ฐ์ดํŠธ ๋˜๋Š” ๊ฒฝ์šฐ๋Š” ๋“œ๋ฌผ๋‹ค.)

 

FOREIGN KEY (owner_id) REFERENCES owners (owner_id) ON DELETE SET NULL,

owner๊ฐ€ ์‚ญ์ œ ๋์„ ๋•Œ ํ•ด๋‹น dog์—์„œ owner_id ๊ฐ’์„ null๋กœ ์„ค์ •

(NOT NULL ์ œ์•ฝ์ด ์—†์–ด์•ผ ํ•œ๋‹ค.)

 

owner_id BIGINT UNSIGNED,
breed_id BIGINT UNSIGNED DEFAULT 2,
FOREIGN KEY (owner_id) REFERENCES owners (owner_id) ON DELETE SET NULL,
CONSTRAINT breed_fk FOREIGN KEY (breed_id) REFERENCES breeds (breed_id) ON DELETE SET DEFAULT

breed๊ฐ€ ์‚ญ์ œ ๋์„ ๋•Œ ํ•ด๋‹น dog์˜ breed_id ๊ฐ’์„ ๊ธฐ๋ณธ๊ฐ’(2)์œผ๋กœ ์„ค์ •

(MySQL์—์„œ๋Š” SET DEFAULT๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค.)

 

CREATE TABLE dogs (
	dog_id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(50) NOT NULL,
	weight DECIMAL(5, 2),
	date_of_birth DATE,
	owner_id BIGINT UNSIGNED,
	breed_id BIGINT UNSIGNED DEFAULT 2,
	-- FOREIGN KEY (owner_id) REFERENCES owners (owner_id) ON DELETE SET NULL,
	CONSTRAINT breed_fk FOREIGN KEY (breed_id) REFERENCES breeds (breed_id) ON DELETE SET DEFAULT
);

ALTER TABLE dogs CONSTRAINT owner_fkFOREIGN KEY (owner_id) REFERENCES owners (owner_id) ON DELETE SET NULL;

์ œ์•ฝ์„ ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•ด์•ผ ํ•  ๋•Œ dogs table์„ ๊ตณ์ด ์‚ญ์ œํ•˜๊ณ  ๋‹ค์‹œ ์ถ”๊ฐ€ํ•  ํ•„์š”์—†์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถ”๊ฐ€๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

ALTER TABLE dogs
DROP FOREIGN KEY owner_fk,
CONSTRAINT owner_fk FOREIGN KEY (owner_id) REFERENCES owners (owner_id) ON DELETE SET NULL;

Foreign Key ์ œ์•ฝ ์กฐ๊ฑด์„ ์ˆ˜์ •ํ•  ๋•Œ๋Š” ๋จผ์ € ์‚ญ์ œํ–ˆ๋‹ค๊ฐ€ ๋‹ค์‹œ ์„ค์ •์„ ํ•œ๋‹ค.

(PostgreSQL์—์„œ๋Š” DROP CONSTRAINT๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, MySQL์—์„œ๋Š” DROP FOREIGN KEY๋กœ Foreign Key๋ฅผ ์‚ญ์ œํ•ด์•ผ ํ•œ๋‹ค.)

 

 

โœ… One to Many, Many to One


1. One-To-Many (1:N) ๊ด€๊ณ„
ํ•œ ํ…Œ์ด๋ธ”์˜ ํ•˜๋‚˜์˜ ๋ ˆ์ฝ”๋“œ๊ฐ€, ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์˜ ์—ฌ๋Ÿฌ ๋ ˆ์ฝ”๋“œ์™€ ์—ฐ๊ฒฐ๋˜๋Š” ๊ด€๊ณ„
(1:N์€ ์™ธ๋ž˜ ํ‚ค๋งŒ ์žˆ์œผ๋ฉด ํ‘œํ˜„ ๊ฐ€๋Šฅ)
ex) ํ•œ ๋ช…์˜ ์ฃผ์ธ์€ ์—ฌ๋Ÿฌ ๋งˆ๋ฆฌ ๊ฐ•์•„์ง€๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

2. One-To-One (1:1) ๊ด€๊ณ„
๋‘ ํ…Œ์ด๋ธ” ์‚ฌ์ด์—์„œ, ํ•˜๋‚˜์˜ ๋ ˆ์ฝ”๋“œ๊ฐ€ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์˜ ์˜ค์ง ํ•˜๋‚˜์˜ ๋ ˆ์ฝ”๋“œ์™€๋งŒ ์—ฐ๊ฒฐ๋˜๋Š” ๊ด€๊ณ„
(1:1์€ ์™ธ๋ž˜ ํ‚ค + UNIQUE ์กฐ๊ฑด์ด ์žˆ์–ด์•ผ ๊ฐ•์ œ ๊ฐ€๋Šฅ)
ex) ํ•œ ๋งˆ๋ฆฌ์˜ ๊ฐ•์•„์ง€๋Š” ํ•˜๋‚˜์˜ ์—ฌ๊ถŒ๋งŒ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

 

 

โœ… Many to Many


SQL์€ ๋‹ค ๋Œ€ ๋‹ค ๊ด€๊ณ„(N:N relationship)๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์—†์–ด์„œ ์ค‘๊ฐ„ ํ…Œ์ด๋ธ”(bridge table, link table)์„ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

 

CREATE TABLE tricks (trick_id BIGINT UNSIGNED PRIMARY KEY auto_increment, name VARCHAR(50) UNIQUE NOT NULL, difficulty ENUM('easy', 'medium', 'hard') NOT NULL DEFAULT 'easy');

CREATE TABLE dog_tricks (
	dog_id BIGINT UNSIGNED,
	trick_id BIGINT UNSIGNED,
	proficiency ENUM('begginer', 'intermediate', 'expert') NOT NULL DEFAULT 'begginer',
	date_learned TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
	PRIMARY KEY (dog_id, trick_id),
	FOREIGN KEY (dog_id) REFERENCES dogs (dog_id) ON DELETE CASCADE,
	FOREIGN KEY (trick_id) REFERENCES tricks (trick_id) ON DELETE CASCADE
);

dog_id์™€ trick_id์˜ ์กฐํ•ฉ์„ Primary Key๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๋‘˜์˜ ์กฐํ•ฉ์ด uniqueํ•ด์•ผํ•จ์„ ์ •์˜ํ•œ๋‹ค.

(๋™์ผํ•œ dog์ด ๋™์ผํ•œ trick์„ ์ค‘๋ณต์œผ๋กœ ๋ฐฐ์šธ ์ˆ˜ ์—†๋‹ค.)

 

 

โœ… JOIN


์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์„ ์—ฐ๊ฒฐํ•ด ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

CROSS JOIN

๋ณ„๋กœ ์œ ์šฉํ•˜์ง€ ์•Š๋‹ค.

์ฒซ ๋ฒˆ์งธ ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  row์™€ ๋‘ ๋ฒˆ์งธ ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  row๋ฅผ ๊ฐ๊ฐ ์—ฐ๊ฒฐ์‹œํ‚จ๋‹ค.

SELECT
	*
FROM
	dogs
	CROSS JOIN owners;

use case: ๊ฐœ์™€ ์ฃผ์ธ ์‚ฌ์ด์˜ ๋ชจ๋“  ์กฐํ•ฉ์„ ์•Œ์•„๋ณด๊ณ  ์‹ถ์„ ๋•Œ

 

INNER JOIN

๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๊ฒŒ ๋  JOIN

SELECT
	*
FROM
	dogs
	INNER JOIN owners;

INNER ์—†์ด JOIN๋งŒ ์‚ฌ์šฉํ•ด๋„ INNER๋ฅผ ์ ์€ ๊ฒƒ๊ณผ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•œ๋‹ค.

 

SELECT
	*
FROM
	dogs
	JOIN owners;

 

์กฐ๊ฑด์„ ์ ์–ด์„œ row๋ฅผ ๋งค์นญ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

SELECT
	*
FROM
	dogs
	JOIN owners ON dogs.owner_id = owners.owner_id;

dogs ํ…Œ์ด๋ธ”์˜ owner_id์™€ owners ํ…Œ์ด๋ธ”์˜ owner_id๊ฐ€ ๊ฐ™์€ row๋“ค๋งŒ ๋งค์นญ

์กฐ๊ฑด์„ ์ ์ง€ ์•Š์œผ๋ฉด JOIN์€ CROSS JOIN์ด ๋œ๋‹ค.

 

USING

SELECT
	dogs.name AS dog_name,
	owners.name AS owner_name,
	breeds.name AS breed_name
FROM
	dogs
	JOIN owners USING (owner_id)
	JOIN breeds ON dogs.breed_id = breeds.breed_id;

ON์œผ๋กœ ์กฐ๊ฑด์„ ์ž‘์„ฑํ•  ๋•Œ ๊ฐ™์€ column ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๋ฉด USING์œผ๋กœ ์งง๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

OUTER JOIN

2๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋Š”๋ฐ ์œ ์šฉํ•˜๋‹ค.

1. LEFT OUTER JOIN (LEFT JOIN)

2. RIGHT OUTER JOIN (RIGHT JOIN)

(LEFT ํ˜น์€ RIGHT์„ ์ ์œผ๋ฉด OUTER๋Š” ํ•„์ˆ˜ ํ‚ค์›Œ๋“œ๊ฐ€ ์•„๋‹ˆ๋‹ค.)

 

์• ๋งคํ•˜๊ฑฐ๋‚˜ ์˜๋ฏธ๊ฐ€ ๋ถˆ๋ถ„๋ช…ํ•œ row๋ฅผ ํ™•์ธํ•ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

SELECT
	dogs.name AS dog_name,
	owners.name AS owner_name
FROM
	dogs
	LEFT JOIN owners USING (owner_id);

LEFT์— ํ•ด๋‹นํ•˜๋Š” dogs์˜ ๋ชจ๋“  row๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ๋งค์นญ ๋˜๋Š” ๊ฒƒ์€ ๋งค์นญ ์‹œํ‚ค๊ณ  owner_id ๊ฐ’์ด null์ธ dog๋„ ํ‘œ์‹œํ•ด์ค€๋‹ค.

SQLite์—์„œ๋Š” CROSS JOIN, INNER JOIN, LEFT OUTER JOIN๋งŒ ์ง€์›ํ•œ๋‹ค.

 

 

โœ… SELECT๋ฌธ์˜ ๊ฐ’์œผ๋กœ column ์ฑ„์šฐ๊ธฐ


INSERT INTO
	statuses (status_name)
SELECT
	status
FROM
	movies
GROUP BY
	status;

 

 

โœ… ๊ธฐ์กด Table์— Foreign key๋ฅผ ๊ฐ€์ง€๋Š” ์ƒˆ column ์ƒ์„ฑํ•˜๊ธฐ


ALTER TABLE movies
ADD COLUMN status_id BIGINT UNSIGNED;

ALTER TABLE movies
ADD CONSTRAINT fk_status FOREIGN KEY (status_id) REFERENCES statuses (status_id) ON DELETE SET NULL;

 

๊ทธ๋ฆฌ๊ณ  ๊ทธ column์— movies table์—์„œ status column๊ณผ ๊ฐ™์€ ์ด๋ฆ„์„ ๊ฐ€์ง€๋Š” status๋ฅผ statuses table์˜ status_id๋ฅผ ๊ฐ€์ ธ์™€ ๋ฐฉ๊ธˆ ๋งŒ๋“  ์ƒˆ column์— ๋„ฃ์–ด์ฃผ๊ธฐ

UPDATE movies
SET
	status_id = (
		SELECT
			status_id
		FROM
			statuses
		WHERE
			status_name = movies.status
	);

 

๋งˆ์ง€๋ง‰์œผ๋กœ ๊ธฐ์กด movies์˜ status column์„ ์‚ญ์ œํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

ALTER TABLE movies
DROP COLUMN status;

'๐Ÿงฉ SQL' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

SQL - MySQL, Event & Trigger  (0) 2026.03.31
SQL - MySQL, UNION  (0) 2026.03.27
SQL - MySQL, ๋ฌธ๋ฒ•  (0) 2026.03.24
SQL - MySQL Data Types  (0) 2026.03.23
SQL - MySQL Setup  (0) 2026.03.23
'๐Ÿงฉ SQL' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • SQL - MySQL, Event & Trigger
  • SQL - MySQL, UNION
  • SQL - MySQL, ๋ฌธ๋ฒ•
  • SQL - MySQL Data Types
j2yonghwa
j2yonghwa
Trying to be a fullstack developer ๐Ÿš€
  • j2yonghwa
    j2yonghwa
    j2yonghwa
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (156)
      • โฐ Daily WakaTime (1)
      • ๐Ÿ–๏ธ ๋…ธ๋งˆ๋“œ์ฝ”๋” (2)
      • ๐Ÿบ Dev Setup (3)
      • ๐Ÿ”ญ Tech Info (1)
      • ๐Ÿšซ Error (1)
      • ๐Ÿ“‚ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (23)
      • ♣๏ธ Next.js 14 (10)
      • ♠๏ธ Next.js 12 (20)
      • ๐Ÿ›ธ React Native (12)
      • ๐Ÿฆ‹ TypeScript (1)
      • ๐Ÿ Python (2)
      • ๐ŸŒŠ TailwindCSS (4)
      • ๐Ÿงฉ SQL (25)
      • ๐Ÿ’Ž Prisma (5)
      • ๐ŸŒฑ MongoDB (4)
      • ๐ŸŽฏ Redis (1)
      • ๐Ÿงฌ GraphQL (2)
      • ๐Ÿ”ฅ Firebase (7)
      • ๐Ÿ’ธ Third-Party Services (2)
      • ๐Ÿ•ธ๏ธ Web (1)
      • ๐Ÿ† ์ฝ”๋”ฉํ…Œ์ŠคํŠธ (23)
      • ๐Ÿ“™ ๋ชจ๋”ฅ๋‹ค (5)
      • ๐Ÿ“— ์ฝ”ํ…Œ ํ•ฉ๊ฒฉ์ž ๋˜๊ธฐ -JS- (0)
      • ๐Ÿ“˜ ํด๋ฆฐ์ฝ”๋“œ (0)
      • ๐Ÿฏ ๊ฟ€ํŒ ๐Ÿ (1)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ํƒœ๊ทธ
    • ๋ฐฉ๋ช…๋ก
  • ๋งํฌ

    • ๊นƒํ—™
  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    Next.js
    SQL
    PostgreSQL
    next.js 12
    ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ
    Python
    React Native
    Prisma
    react router
    next.js 14
    Firebase
    dev setup
    MySQL
    0๋ ˆ๋ฒจ
    mongoDB
    API
    ๋ชจ๋”ฅ๋‹ค
    tailwindcss
    ์ฝ”๋”ฉํ…Œ์ŠคํŠธ ์ž…๋ฌธ
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.3
j2yonghwa
SQL - MySQL, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ •๊ทœํ™”, Foreign Key, JOIN
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”