2025-08-16 01:49

Tags:

๐Ÿ“š SQL ์ฐธ์กฐ(Reference)์˜ ๋ชจ๋“  ๊ฒƒ: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๊ณ„์˜ ์™„์ „ํ•œ ํ•ธ๋“œ๋ถ ๊ฐ€์ด๋“œ

๐Ÿ“Œ ๋“ค์–ด๊ฐ€๋ฉฐ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ **์ฐธ์กฐ(Reference)**๋ผ๋Š” ๊ฐœ๋…์€ ํ…Œ์ด๋ธ” ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ์ •์˜ํ•˜๊ณ  ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ํ•ต์‹ฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. ๋งˆ์น˜ ๋„์„œ๊ด€์—์„œ ์ฑ…์„ ์ฐพ๊ธฐ ์œ„ํ•ด ๋„์„œ ๋ชฉ๋ก์„ ์ฐธ์กฐํ•˜๋“ฏ์ด, SQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ๋Š” ํ•œ ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์˜ ํŠน์ • ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•จ์œผ๋กœ์จ ๋…ผ๋ฆฌ์ ์ธ ์—ฐ๊ฒฐ๊ณ ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด๋ƒ…๋‹ˆ๋‹ค.12

SQL์—์„œ ์ฐธ์กฐ๋Š” ์ฃผ๋กœ ์™ธ๋ž˜ ํ‚ค(Foreign Key) ์ œ์•ฝ์กฐ๊ฑด์„ ํ†ตํ•ด ๊ตฌํ˜„๋˜๋ฉฐ, ์ด๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค๊ณ„์˜ ๊ธฐ์ดˆ๊ฐ€ ๋˜๋Š” ๊ด€๊ณ„ํ˜• ๋ชจ๋ธ์˜ ํ•ต์‹ฌ ์›๋ฆฌ์ž…๋‹ˆ๋‹ค. ์ด ํ•ธ๋“œ๋ถ์€ SQL ์ฐธ์กฐ์˜ ๋ชจ๋“  ์ธก๋ฉด์„ ์ฒด๊ณ„์ ์œผ๋กœ ๋‹ค๋ฃจ์–ด, ์ดˆ๋ณด์ž๋ถ€ํ„ฐ ๊ณ ๊ธ‰ ๊ฐœ๋ฐœ์ž๊นŒ์ง€ ์‹ค๋ฌด์—์„œ ๋ฐ”๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์‹ค์šฉ์ ์ธ ์ง€์‹์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

SQL ์™ธ๋ž˜ ํ‚ค ๊ด€๊ณ„๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์ „์ž์ƒ๊ฑฐ๋ž˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ตฌ์กฐ๋„

SQL ์™ธ๋ž˜ ํ‚ค ๊ด€๊ณ„๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์ „์ž์ƒ๊ฑฐ๋ž˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ตฌ์กฐ๋„

๐ŸŽฏ SQL ์ฐธ์กฐ๊ฐ€ ๋งŒ๋“ค์–ด์ง„ ์ด์œ ์™€ ๋ฐฐ๊ฒฝ

๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์˜ ํ•„์š”์„ฑ

SQL ์ฐธ์กฐ ์‹œ์Šคํ…œ์€ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์•„๋ฒ„์ง€๋กœ ๋ถˆ๋ฆฌ๋Š” Edgar F. Codd์˜ ๊ด€๊ณ„ํ˜• ๋ชจ๋ธ์—์„œ ์ถœ๋ฐœํ–ˆ์Šต๋‹ˆ๋‹ค. 1970๋…„๋Œ€ IBM์—์„œ ๊ฐœ๋ฐœ๋œ ์ด ๊ฐœ๋…์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ•ต์‹ฌ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค:3

1. ๋ฐ์ดํ„ฐ ์ค‘๋ณต์„ฑ ๋ฌธ์ œ

๊ธฐ์กด์˜ ํŒŒ์ผ ๊ธฐ๋ฐ˜ ์‹œ์Šคํ…œ์—์„œ๋Š” ๊ฐ™์€ ์ •๋ณด๊ฐ€ ์—ฌ๋Ÿฌ ๊ณณ์— ์ €์žฅ๋˜์–ด ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ณ ๊ฐ ์ •๋ณด๊ฐ€ ์ฃผ๋ฌธ ํ…Œ์ด๋ธ”๊ณผ ๋ฐฐ์†ก ํ…Œ์ด๋ธ”์— ๊ฐ๊ฐ ์ €์žฅ๋˜๋ฉด, ๊ณ ๊ฐ์ด ์ฃผ์†Œ๋ฅผ ๋ณ€๊ฒฝํ–ˆ์„ ๋•Œ ๋ชจ๋“  ๊ณณ์„ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ–ˆ์ฃ .4

2. ๊ณ ์•„ ๋ ˆ์ฝ”๋“œ(Orphan Records) ๋ฐฉ์ง€

์ฐธ์กฐ ๋ฌด๊ฒฐ์„ฑ์ด ์—†๋‹ค๋ฉด ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ณ ๊ฐ์— ๋Œ€ํ•œ ์ฃผ๋ฌธ์ด๋‚˜ ์‚ญ์ œ๋œ ๋ถ€์„œ์— ์†ํ•œ ์ง์› ๊ฐ™์€ ๋…ผ๋ฆฌ์ ์œผ๋กœ ๋ถˆ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.56

3. ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ ๋ณด์žฅ

๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ ˆ๋ฒจ์—์„œ ๊ฐ•์ œํ•จ์œผ๋กœ์จ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ์ง์˜ ๋ณต์žก์„ฑ์„ ์ค„์ด๊ณ , ๋‹ค์–‘ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด๋„ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.78

์‹ค์ œ ์—…๋ฌด์—์„œ์˜ ํ•„์š”์„ฑ

ํ˜„์‹ค ์„ธ๊ณ„์˜ ๋น„์ฆˆ๋‹ˆ์Šค๋Š” ๊ด€๊ณ„๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณ ๊ฐ์€ ์ฃผ๋ฌธ์„ ํ•˜๊ณ , ์ง์›์€ ๋ถ€์„œ์— ์†Œ์†๋˜๋ฉฐ, ์ œํ’ˆ์€ ์นดํ…Œ๊ณ ๋ฆฌ์— ๋ถ„๋ฅ˜๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ด€๊ณ„๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ •ํ™•ํžˆ ๋ฐ˜์˜ํ•˜๊ณ  ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ฐธ์กฐ ์‹œ์Šคํ…œ์ด ํ•„์ˆ˜์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค.910

๐Ÿ—๏ธ SQL ์ฐธ์กฐ์˜ ํ•ต์‹ฌ ๊ตฌ์กฐ์™€ ๊ฐœ๋…

์™ธ๋ž˜ ํ‚ค(Foreign Key)์˜ ์ •์˜

์™ธ๋ž˜ ํ‚ค๋Š” ํ•œ ํ…Œ์ด๋ธ”์˜ ์ปฌ๋Ÿผ์ด ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์˜ ๊ธฐ๋ณธ ํ‚ค๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ œ์•ฝ์กฐ๊ฑด์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋‘ ํ…Œ์ด๋ธ” ์‚ฌ์ด์— ๋…ผ๋ฆฌ์  ์—ฐ๊ฒฐ์„ ๋งŒ๋“ค๊ณ , ๋ฐ์ดํ„ฐ์˜ ์ฐธ์กฐ ๋ฌด๊ฒฐ์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.211

 
-- ๊ธฐ๋ณธ ๊ตฌ์กฐ ์˜ˆ์‹œ
 
CREATE TABLE customers (
 
customer_id INT PRIMARY KEY,
 
name VARCHAR(50),
 
email VARCHAR(100)
 
);
 
  
 
CREATE TABLE orders (
 
order_id INT PRIMARY KEY,
 
customer_id INT,
 
order_date DATE,
 
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
 
);
 

์ฐธ์กฐ ๋ฌด๊ฒฐ์„ฑ(Referential Integrity)์˜ ์›๋ฆฌ

์ฐธ์กฐ ๋ฌด๊ฒฐ์„ฑ์€ ์™ธ๋ž˜ ํ‚ค ๊ฐ’์ด ์œ ํšจํ•œ ๊ธฐ๋ณธ ํ‚ค ๊ฐ’์„ ์ฐธ์กฐํ•˜๊ฑฐ๋‚˜ NULL์ด์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ทœ์น™์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:34

  1. ์กด์žฌํ•˜๋Š” ๊ฐ’ ์ฐธ์กฐ: ์™ธ๋ž˜ ํ‚ค ๊ฐ’์€ ๋ฐ˜๋“œ์‹œ ๋ถ€๋ชจ ํ…Œ์ด๋ธ”์˜ ๊ธฐ๋ณธ ํ‚ค์— ์กด์žฌํ•˜๋Š” ๊ฐ’์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค

  2. NULL ํ—ˆ์šฉ: ์™ธ๋ž˜ ํ‚ค ์ปฌ๋Ÿผ์ด NULL์„ ํ—ˆ์šฉํ•œ๋‹ค๋ฉด, NULL ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

๋ถ€๋ชจ-์ž์‹ ํ…Œ์ด๋ธ” ๊ด€๊ณ„

SQL ์ฐธ์กฐ์—์„œ๋Š” **๋ถ€๋ชจ ํ…Œ์ด๋ธ”(Parent Table)**๊ณผ **์ž์‹ ํ…Œ์ด๋ธ”(Child Table)**์˜ ๊ฐœ๋…์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค:212

  • ๋ถ€๋ชจ ํ…Œ์ด๋ธ”: ๊ธฐ๋ณธ ํ‚ค๋ฅผ ์ œ๊ณตํ•˜๋Š” ํ…Œ์ด๋ธ” (์˜ˆ: customers)

  • ์ž์‹ ํ…Œ์ด๋ธ”: ์™ธ๋ž˜ ํ‚ค๋ฅผ ํฌํ•จํ•˜๋Š” ํ…Œ์ด๋ธ” (์˜ˆ: orders)

๐Ÿ“‹ SQL ์ฐธ์กฐ์˜ ๋‹ค์–‘ํ•œ ์œ ํ˜•๊ณผ ์‚ฌ์šฉ๋ฒ•

1. ์ผ๋Œ€๋‹ค ๊ด€๊ณ„ (One-to-Many)

๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๊ด€๊ณ„๋กœ, ํ•œ ๋ถ€๋ชจ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์—ฌ๋Ÿฌ ์ž์‹ ๋ ˆ์ฝ”๋“œ์™€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.1314

 
-- ๋ถ€์„œ-์ง์› ๊ด€๊ณ„ ์˜ˆ์‹œ
 
CREATE TABLE departments (
 
dept_id INT PRIMARY KEY,
 
dept_name VARCHAR(50)
 
);
 
  
 
CREATE TABLE employees (
 
emp_id INT PRIMARY KEY,
 
emp_name VARCHAR(50),
 
dept_id INT,
 
FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
 
);
 

์‹ค๋ฌด ํ™œ์šฉ ์˜ˆ์‹œ:

  • ๊ณ ๊ฐ โ†” ์ฃผ๋ฌธ ๊ด€๊ณ„

  • ์นดํ…Œ๊ณ ๋ฆฌ โ†” ์ œํ’ˆ ๊ด€๊ณ„

  • ๋ถ€์„œ โ†” ์ง์› ๊ด€๊ณ„

2. ์ผ๋Œ€์ผ ๊ด€๊ณ„ (One-to-One)

๊ฐ ๋ถ€๋ชจ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์ •ํ™•ํžˆ ํ•˜๋‚˜์˜ ์ž์‹ ๋ ˆ์ฝ”๋“œ์™€ ์—ฐ๊ฒฐ๋˜๋Š” ๊ด€๊ณ„์ž…๋‹ˆ๋‹ค.15

 
-- ์ง์›-์—ฌ๊ถŒ ๊ด€๊ณ„ ์˜ˆ์‹œ
 
CREATE TABLE employees (
 
emp_id INT PRIMARY KEY,
 
emp_name VARCHAR(50)
 
);
 
  
 
CREATE TABLE passports (
 
passport_id INT PRIMARY KEY,
 
emp_id INT UNIQUE NOT NULL,
 
passport_number VARCHAR(20),
 
FOREIGN KEY (emp_id) REFERENCES employees(emp_id)
 
);
 

์ฃผ์˜์‚ฌํ•ญ: ์ผ๋Œ€์ผ ๊ด€๊ณ„์—์„œ๋Š” ์™ธ๋ž˜ ํ‚ค์— UNIQUE ์ œ์•ฝ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.15

3. ๋‹ค๋Œ€๋‹ค ๊ด€๊ณ„ (Many-to-Many)

**์—ฐ๊ฒฐ ํ…Œ์ด๋ธ”(Junction Table)**์„ ํ†ตํ•ด ๊ตฌํ˜„๋˜๋Š” ๋ณตํ•ฉ ๊ด€๊ณ„์ž…๋‹ˆ๋‹ค.1316

 
-- ํ•™์ƒ-๊ณผ๋ชฉ ๊ด€๊ณ„ ์˜ˆ์‹œ
 
CREATE TABLE students (
 
student_id INT PRIMARY KEY,
 
student_name VARCHAR(50)
 
);
 
  
 
CREATE TABLE subjects (
 
subject_id INT PRIMARY KEY,
 
subject_name VARCHAR(50)
 
);
 
  
 
-- ์—ฐ๊ฒฐ ํ…Œ์ด๋ธ”
 
CREATE TABLE enrollments (
 
student_id INT,
 
subject_id INT,
 
enrollment_date DATE,
 
grade CHAR(2),
 
PRIMARY KEY (student_id, subject_id),
 
FOREIGN KEY (student_id) REFERENCES students(student_id),
 
FOREIGN KEY (subject_id) REFERENCES subjects(subject_id)
 
);
 

4. ์ž๊ธฐ์ฐธ์กฐ ๊ด€๊ณ„ (Self-Referencing)

๊ฐ™์€ ํ…Œ์ด๋ธ” ๋‚ด์—์„œ ๋ ˆ์ฝ”๋“œ๋“ค์ด ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ด€๊ณ„์ž…๋‹ˆ๋‹ค.171819

 
-- ์ง์›-๊ด€๋ฆฌ์ž ๊ด€๊ณ„ ์˜ˆ์‹œ
 
CREATE TABLE employees (
 
emp_id INT PRIMARY KEY,
 
emp_name VARCHAR(50),
 
manager_id INT,
 
FOREIGN KEY (manager_id) REFERENCES employees(emp_id)
 
);
 

ํ™œ์šฉ ์‚ฌ๋ก€:

  • ์กฐ์ง๋„์—์„œ ์ƒํ•˜๊ธ‰ ๊ด€๊ณ„

  • ๊ฒŒ์‹œํŒ์˜ ๋Œ“๊ธ€-๋Œ€๋Œ“๊ธ€ ๊ตฌ์กฐ

  • ์นดํ…Œ๊ณ ๋ฆฌ์˜ ์ƒ์œ„-ํ•˜์œ„ ๋ถ„๋ฅ˜

โš™๏ธ ์ฐธ์กฐ ๋™์ž‘ ์˜ต์…˜๊ณผ ํ™œ์šฉ๋ฒ•

SQL์—์„œ๋Š” ๋ถ€๋ชจ ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ฑฐ๋‚˜ ์‚ญ์ œ๋  ๋•Œ ์ž์‹ ํ…Œ์ด๋ธ”์—์„œ ์–ด๋–ค ๋™์ž‘์„ ์ˆ˜ํ–‰ํ• ์ง€ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.7812

CASCADE ์˜ต์…˜

๋ถ€๋ชจ ๋ ˆ์ฝ”๋“œ์˜ ๋ณ€๊ฒฝ/์‚ญ์ œ๊ฐ€ ์ž์‹ ๋ ˆ์ฝ”๋“œ์— ์ž๋™์œผ๋กœ ์ „ํŒŒ๋ฉ๋‹ˆ๋‹ค.820

 
CREATE TABLE orders (
 
order_id INT PRIMARY KEY,
 
customer_id INT,
 
order_date DATE,
 
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
 
ON DELETE CASCADE
 
ON UPDATE CASCADE
 
);
 

์žฅ์ :

  • ๊ด€๋ จ ๋ฐ์ดํ„ฐ๊ฐ€ ์ž๋™์œผ๋กœ ๋™๊ธฐํ™”๋จ

  • ๊ณ ์•„ ๋ ˆ์ฝ”๋“œ ๋ฐœ์ƒ ๋ฐฉ์ง€

์ฃผ์˜์‚ฌํ•ญ:

  • ์˜๋„ํ•˜์ง€ ์•Š์€ ๋Œ€๋Ÿ‰ ์‚ญ์ œ ์œ„ํ—˜

  • ๋ณต๊ตฌ๊ฐ€ ์–ด๋ ค์›€

SET NULL ์˜ต์…˜

๋ถ€๋ชจ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์‚ญ์ œ๋˜๋ฉด ์ž์‹ ํ…Œ์ด๋ธ”์˜ ์™ธ๋ž˜ ํ‚ค ๊ฐ’์„ NULL๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.820

 
CREATE TABLE orders (
 
order_id INT PRIMARY KEY,
 
customer_id INT,
 
order_date DATE,
 
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
 
ON DELETE SET NULL
 
);
 

ํ™œ์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค:

  • ๋‹ด๋‹น์ž๊ฐ€ ํ‡ด์‚ฌํ•ด๋„ ํ”„๋กœ์ ํŠธ ๊ธฐ๋ก์€ ์œ ์ง€ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ

  • ์นดํ…Œ๊ณ ๋ฆฌ๊ฐ€ ์‚ญ์ œ๋˜์–ด๋„ ์ œํ’ˆ์€ ๋ณด๊ด€ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ

RESTRICT/NO ACTION ์˜ต์…˜

์ž์‹ ๋ ˆ์ฝ”๋“œ๊ฐ€ ์กด์žฌํ•˜๋ฉด ๋ถ€๋ชจ ๋ ˆ์ฝ”๋“œ์˜ ์‚ญ์ œ/์ˆ˜์ •์„ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค.712

 
CREATE TABLE orders (
 
order_id INT PRIMARY KEY,
 
customer_id INT,
 
order_date DATE,
 
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
 
ON DELETE RESTRICT
 
);
 

์žฅ์ :

  • ์‹ค์ˆ˜๋กœ ์ธํ•œ ๋ฐ์ดํ„ฐ ์†์‹ค ๋ฐฉ์ง€

  • ๋ช…์‹œ์ ์ธ ๋ฐ์ดํ„ฐ ์ •๋ฆฌ ๊ณผ์ • ๊ฐ•์ œ

๐Ÿ”ง ์‹ค๋ฌด์—์„œ์˜ SQL ์ฐธ์กฐ ํ™œ์šฉ๋ฒ•

JOIN ์—ฐ์‚ฐ๊ณผ์˜ ์—ฐ๊ณ„

์™ธ๋ž˜ ํ‚ค๋Š” JOIN ์—ฐ์‚ฐ์˜ ๊ธฐ์ดˆ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.212223

 
-- INNER JOIN ์˜ˆ์‹œ
 
SELECT
 
c.customer_name,
 
o.order_date,
 
o.total_amount
 
FROM customers c
 
INNER JOIN orders o ON c.customer_id = o.customer_id
 
WHERE o.order_date >= '2025-01-01';
 
  
 
-- LEFT JOIN์œผ๋กœ ๋ชจ๋“  ๊ณ ๊ฐ ์กฐํšŒ (์ฃผ๋ฌธ์ด ์—†๋Š” ๊ณ ๊ฐ ํฌํ•จ)
 
SELECT
 
c.customer_name,
 
COUNT(o.order_id) as order_count
 
FROM customers c
 
LEFT JOIN orders o ON c.customer_id = o.customer_id
 
GROUP BY c.customer_id, c.customer_name;
 

๋ณตํ•ฉ ์™ธ๋ž˜ ํ‚ค

์—ฌ๋Ÿฌ ์ปฌ๋Ÿผ์„ ์กฐํ•ฉํ•œ ์™ธ๋ž˜ ํ‚ค๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.6

 
CREATE TABLE order_details (
 
order_id INT,
 
product_id INT,
 
line_number INT,
 
quantity INT,
 
price DECIMAL(10,2),
 
PRIMARY KEY (order_id, line_number),
 
FOREIGN KEY (order_id, product_id)
 
REFERENCES order_products(order_id, product_id)
 
);
 

์ธ๋ฑ์Šค ์ตœ์ ํ™”

์™ธ๋ž˜ ํ‚ค ์ปฌ๋Ÿผ์—๋Š” ์ž๋™์œผ๋กœ ์ธ๋ฑ์Šค๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์ง€๋งŒ, ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ๋ช…์‹œ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.1224

 
-- ์™ธ๋ž˜ ํ‚ค ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ์ธ๋ฑ์Šค
 
CREATE INDEX idx_orders_customer_id ON orders(customer_id);
 
CREATE INDEX idx_order_items_product_id ON order_items(product_id);
 

๐Ÿ“ ์ฐธ์กฐ์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ •๊ทœํ™”

SQL ์ฐธ์กฐ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ •๊ทœํ™”์™€ ๋ฐ€์ ‘ํ•œ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค.252627

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

๊ฐ ์ปฌ๋Ÿผ์ด ์›์ž๊ฐ’์„ ๊ฐ€์ง€๊ณ  ๊ธฐ๋ณธ ํ‚ค๊ฐ€ ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.2526

์œ„๋ฐ˜ ์‚ฌ๋ก€:

 
-- ์ž˜๋ชป๋œ ์˜ˆ์‹œ (1NF ์œ„๋ฐ˜)
 
CREATE TABLE orders_bad (
 
order_id INT,
 
customer_name VARCHAR(50),
 
product_names TEXT -- ์—ฌ๋Ÿฌ ์ œํ’ˆ๋ช…์ด ํ•˜๋‚˜์˜ ์ปฌ๋Ÿผ์— ์ €์žฅ
 
);
 

์˜ฌ๋ฐ”๋ฅธ ์˜ˆ์‹œ:

 
-- 1NF ์ค€์ˆ˜
 
CREATE TABLE orders (
 
order_id INT PRIMARY KEY,
 
customer_id INT,
 
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
 
);
 
  
 
CREATE TABLE order_items (
 
order_id INT,
 
product_id INT,
 
quantity INT,
 
PRIMARY KEY (order_id, product_id),
 
FOREIGN KEY (order_id) REFERENCES orders(order_id),
 
FOREIGN KEY (product_id) REFERENCES products(product_id)
 
);
 

์ œ2์ •๊ทœํ˜• (2NF)

๋ชจ๋“  ๋น„ํ‚ค ์†์„ฑ์ด ๊ธฐ๋ณธ ํ‚ค ์ „์ฒด์— ์™„์ „ ํ•จ์ˆ˜์  ์ข…์†๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.252627

์ œ3์ •๊ทœํ˜• (3NF)

๋น„ํ‚ค ์†์„ฑ์ด ๋‹ค๋ฅธ ๋น„ํ‚ค ์†์„ฑ์— ์ข…์†๋˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.2728

๐ŸŽจ ์ฐธ์กฐ ๋ช…๋ช… ๊ทœ์น™๊ณผ ๋ชจ๋ฒ” ์‚ฌ๋ก€

์ผ๊ด€๋œ ๋ช…๋ช… ๊ทœ์น™

๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ์œ„ํ•ด ์ผ๊ด€๋œ ๋ช…๋ช… ๊ทœ์น™์„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.24293031

 
-- ๊ถŒ์žฅ ๋ช…๋ช… ๊ทœ์น™
 
-- ๊ธฐ๋ณธ ํ‚ค: pk_ํ…Œ์ด๋ธ”๋ช…
 
-- ์™ธ๋ž˜ ํ‚ค: fk_ํ…Œ์ด๋ธ”๋ช…_์ฐธ์กฐํ…Œ์ด๋ธ”๋ช…
 
-- ์ธ๋ฑ์Šค: idx_ํ…Œ์ด๋ธ”๋ช…_์ปฌ๋Ÿผ๋ช…
 
  
 
CREATE TABLE customers (
 
customer_id INT,
 
customer_name VARCHAR(50),
 
email VARCHAR(100),
 
CONSTRAINT pk_customers PRIMARY KEY (customer_id)
 
);
 
  
 
CREATE TABLE orders (
 
order_id INT,
 
customer_id INT,
 
order_date DATE,
 
CONSTRAINT pk_orders PRIMARY KEY (order_id),
 
CONSTRAINT fk_orders_customers
 
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
 
);
 

์ œ์•ฝ์กฐ๊ฑด ๋ช…๋ช… ๋ชจ๋ฒ” ์‚ฌ๋ก€

์ฒด๊ณ„์ ์ธ ์ œ์•ฝ์กฐ๊ฑด ๋ช…๋ช…์œผ๋กœ ๋””๋ฒ„๊น…๊ณผ ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:313233

  • ๊ธฐ๋ณธ ํ‚ค: pk_ํ…Œ์ด๋ธ”๋ช…

  • ์™ธ๋ž˜ ํ‚ค: fk_์ž์‹ํ…Œ์ด๋ธ”_๋ถ€๋ชจํ…Œ์ด๋ธ”

  • ๊ณ ์œ  ์ œ์•ฝ: uq_ํ…Œ์ด๋ธ”๋ช…_์ปฌ๋Ÿผ๋ช…

  • ์ฒดํฌ ์ œ์•ฝ: ck_ํ…Œ์ด๋ธ”๋ช…_์ปฌ๋Ÿผ๋ช…

๐Ÿšจ ์‹ค๋ฌด์—์„œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ฐธ์กฐ ๊ด€๋ จ ์ด์Šˆ๋“ค

์ˆœํ™˜ ์ฐธ์กฐ ๋ฌธ์ œ

ํ…Œ์ด๋ธ”๋“ค์ด ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ˆœํ™˜ ๊ตฌ์กฐ๋Š” ํ”ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 
-- ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ์„ค๊ณ„
 
CREATE TABLE employees (
 
emp_id INT PRIMARY KEY,
 
dept_id INT,
 
FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
 
);
 
  
 
CREATE TABLE departments (
 
dept_id INT PRIMARY KEY,
 
manager_id INT,
 
FOREIGN KEY (manager_id) REFERENCES employees(emp_id) -- ์ˆœํ™˜ ์ฐธ์กฐ!
 
);
 

ํ•ด๊ฒฐ์ฑ…:

 
-- ๊ฐœ์„ ๋œ ์„ค๊ณ„
 
CREATE TABLE departments (
 
dept_id INT PRIMARY KEY,
 
dept_name VARCHAR(50)
 
);
 
  
 
CREATE TABLE employees (
 
emp_id INT PRIMARY KEY,
 
emp_name VARCHAR(50),
 
dept_id INT,
 
manager_id INT,
 
FOREIGN KEY (dept_id) REFERENCES departments(dept_id),
 
FOREIGN KEY (manager_id) REFERENCES employees(emp_id) -- ์ž๊ธฐ์ฐธ์กฐ๋กœ ํ•ด๊ฒฐ
 
);
 

์„ฑ๋Šฅ ๊ณ ๋ ค์‚ฌํ•ญ

๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ์—์„œ ์™ธ๋ž˜ ํ‚ค ์ œ์•ฝ์กฐ๊ฑด์€ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:1234

  1. INSERT/UPDATE ์„ฑ๋Šฅ: ์ฐธ์กฐ ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์‚ฌ๋กœ ์ธํ•œ ์˜ค๋ฒ„ํ—ค๋“œ

  2. DELETE ์„ฑ๋Šฅ: CASCADE ์˜ต์…˜ ์‚ฌ์šฉ ์‹œ ์—ฐ์‡„ ์‚ญ์ œ ์ฒ˜๋ฆฌ

  3. ์ธ๋ฑ์Šค ๊ด€๋ฆฌ: ์™ธ๋ž˜ ํ‚ค ์ปฌ๋Ÿผ์˜ ์ ์ ˆํ•œ ์ธ๋ฑ์‹ฑ ํ•„์š”

๋ฐ์ดํ„ฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹œ ์ฃผ์˜์‚ฌํ•ญ

๊ธฐ์กด ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ํ…Œ์ด๋ธ”์— ์™ธ๋ž˜ ํ‚ค๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ๋Š” ์‹ ์ค‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

 
-- ๊ธฐ์กด ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ ๊ฒ€์‚ฌ ํ›„ ์ œ์•ฝ์กฐ๊ฑด ์ถ”๊ฐ€
 
-- 1๋‹จ๊ณ„: ๋ฌธ์ œ ๋ฐ์ดํ„ฐ ํ™•์ธ
 
SELECT o.order_id, o.customer_id
 
FROM orders o
 
LEFT JOIN customers c ON o.customer_id = c.customer_id
 
WHERE c.customer_id IS NULL;
 
  
 
-- 2๋‹จ๊ณ„: ๋ฌธ์ œ ๋ฐ์ดํ„ฐ ์ •๋ฆฌ ํ›„ ์ œ์•ฝ์กฐ๊ฑด ์ถ”๊ฐ€
 
ALTER TABLE orders
 
ADD CONSTRAINT fk_orders_customers
 
FOREIGN KEY (customer_id) REFERENCES customers(customer_id);
 

๐Ÿ” ๊ณ ๊ธ‰ ์ฐธ์กฐ ๊ธฐ๋ฒ•๊ณผ ์‹ค์ „ ํ™œ์šฉ

์กฐ๊ฑด๋ถ€ ์ฐธ์กฐ

ํŠน์ • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ์ฐธ์กฐ๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๊ณ ๊ธ‰ ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค.

 
-- ํ™œ์„ฑํ™”๋œ ๊ณ ๊ฐ๋งŒ ์ฐธ์กฐ ํ—ˆ์šฉํ•˜๋Š” CHECK ์ œ์•ฝ์กฐ๊ฑด
 
CREATE TABLE orders (
 
order_id INT PRIMARY KEY,
 
customer_id INT,
 
order_date DATE,
 
FOREIGN KEY (customer_id) REFERENCES customers(customer_id),
 
CONSTRAINT ck_active_customer
 
CHECK (customer_id IN (
 
SELECT customer_id FROM customers WHERE status = 'ACTIVE'
 
))
 
);
 

๋‹ค์ค‘ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ„ ์ฐธ์กฐ

์„œ๋กœ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ„์˜ ์ฐธ์กฐ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ œ์•ฝ์กฐ๊ฑด์œผ๋กœ ๊ฐ•์ œํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ์—์„œ ๊ด€๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 
-- ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๊ต์ฐจ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฐธ์กฐ
 
-- order_db.orders ํ…Œ์ด๋ธ”
 
CREATE TABLE orders (
 
order_id INT PRIMARY KEY,
 
customer_id INT, -- customer_db.customers๋ฅผ ์ฐธ์กฐํ•˜์ง€๋งŒ FK ์ œ์•ฝ์กฐ๊ฑด ๋ถˆ๊ฐ€
 
order_date DATE
 
);
 

์†Œํ”„ํŠธ ์ฐธ์กฐ์™€ ํ•˜๋“œ ์ฐธ์กฐ

์†Œํ”„ํŠธ ์ฐธ์กฐ: ์ œ์•ฝ์กฐ๊ฑด ์—†์ด ๋…ผ๋ฆฌ์ ์œผ๋กœ๋งŒ ์—ฐ๊ฒฐ

ํ•˜๋“œ ์ฐธ์กฐ: ์™ธ๋ž˜ ํ‚ค ์ œ์•ฝ์กฐ๊ฑด์œผ๋กœ ๋ฌผ๋ฆฌ์  ์—ฐ๊ฒฐ ๊ฐ•์ œ

 
-- ์†Œํ”„ํŠธ ์ฐธ์กฐ (์œ ์—ฐํ•˜์ง€๋งŒ ๋ฌด๊ฒฐ์„ฑ ๋ณด์žฅ ์•ˆ๋จ)
 
CREATE TABLE logs (
 
log_id INT PRIMARY KEY,
 
user_id INT, -- users ํ…Œ์ด๋ธ” ์ฐธ์กฐํ•˜์ง€๋งŒ FK ์ œ์•ฝ์กฐ๊ฑด ์—†์Œ
 
action_type VARCHAR(50),
 
created_at TIMESTAMP
 
);
 
  
 
-- ํ•˜๋“œ ์ฐธ์กฐ (๋ฌด๊ฒฐ์„ฑ ๋ณด์žฅํ•˜์ง€๋งŒ ์ œ์•ฝ์ด ์žˆ์Œ)
 
CREATE TABLE orders (
 
order_id INT PRIMARY KEY,
 
customer_id INT,
 
order_date DATE,
 
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
 
);
 

๐Ÿ“Š ์„ฑ๋Šฅ ์ตœ์ ํ™” ์ „๋žต

์™ธ๋ž˜ ํ‚ค ์ธ๋ฑ์Šค ์„ค๊ณ„

์™ธ๋ž˜ ํ‚ค ์ปฌ๋Ÿผ์— ๋Œ€ํ•œ ํšจ์œจ์ ์ธ ์ธ๋ฑ์Šค ์ „๋žต์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค:1224

 
-- ๋ณตํ•ฉ ์ธ๋ฑ์Šค๋กœ ์„ฑ๋Šฅ ์ตœ์ ํ™”
 
CREATE INDEX idx_orders_customer_date
 
ON orders(customer_id, order_date DESC);
 
  
 
-- ๋ถ€๋ถ„ ์ธ๋ฑ์Šค ํ™œ์šฉ (PostgreSQL ์˜ˆ์‹œ)
 
CREATE INDEX idx_active_orders
 
ON orders(customer_id)
 
WHERE status = 'ACTIVE';
 

ํ†ต๊ณ„ ์ •๋ณด ๊ด€๋ฆฌ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์˜ตํ‹ฐ๋งˆ์ด์ €๋ฅผ ์œ„ํ•œ ํ†ต๊ณ„ ์ •๋ณด๋ฅผ ์ตœ์‹  ์ƒํƒœ๋กœ ์œ ์ง€:

 
-- SQL Server ์˜ˆ์‹œ
 
UPDATE STATISTICS customers;
 
UPDATE STATISTICS orders;
 
  
 
-- MySQL ์˜ˆ์‹œ
 
ANALYZE TABLE customers;
 
ANALYZE TABLE orders;
 

๐Ÿ› ๏ธ ์ฐธ์กฐ ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์ฆ๊ณผ ๋ชจ๋‹ˆํ„ฐ๋ง

์ฐธ์กฐ ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์‚ฌ ์ฟผ๋ฆฌ

์‹œ์Šคํ…œ์˜ ์ฐธ์กฐ ๋ฌด๊ฒฐ์„ฑ ์ƒํƒœ๋ฅผ ์ฃผ๊ธฐ์ ์œผ๋กœ ์ ๊ฒ€ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค:

 
-- ๊ณ ์•„ ๋ ˆ์ฝ”๋“œ ์ฐพ๊ธฐ
 
SELECT 'orders' as table_name, COUNT(*) as orphan_count
 
FROM orders o
 
LEFT JOIN customers c ON o.customer_id = c.customer_id
 
WHERE c.customer_id IS NULL
 
  
 
UNION ALL
 
  
 
SELECT 'order_items' as table_name, COUNT(*) as orphan_count
 
FROM order_items oi
 
LEFT JOIN orders o ON oi.order_id = o.order_id
 
WHERE o.order_id IS NULL;
 

์ œ์•ฝ์กฐ๊ฑด ์ƒํƒœ ๋ชจ๋‹ˆํ„ฐ๋ง

 
-- SQL Server์—์„œ ๋น„ํ™œ์„ฑํ™”๋œ ์ œ์•ฝ์กฐ๊ฑด ํ™•์ธ
 
SELECT
 
t.name AS table_name,
 
fk.name AS constraint_name,
 
fk.is_disabled
 
FROM sys.foreign_keys fk
 
INNER JOIN sys.tables t ON fk.parent_object_id = t.object_id
 
WHERE fk.is_disabled = 1;
 

๐Ÿ“ˆ ๋ฏธ๋ž˜์ง€ํ–ฅ์  ์ฐธ์กฐ ์„ค๊ณ„

๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜์—์„œ์˜ ์ฐธ์กฐ

๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ํ™˜๊ฒฝ์—์„œ๋Š” ์„œ๋น„์Šค ๊ฐ„ ๊ฐ•ํ•œ ๊ฒฐํ•ฉ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค:

  1. ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์ผ๊ด€์„ฑ: ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์„ ์ด๋ฒคํŠธ๋กœ ์ „ํŒŒ

  2. Saga ํŒจํ„ด: ๋ถ„์‚ฐ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ

  3. ์ตœ์ข… ์ผ๊ด€์„ฑ: ๊ฐ•ํ•œ ์ผ๊ด€์„ฑ ๋Œ€์‹  ์ตœ์ข…์  ์ผ๊ด€์„ฑ ์ˆ˜์šฉ

ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์—์„œ์˜ ๊ณ ๋ ค์‚ฌํ•ญ

ํด๋ผ์šฐ๋“œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ๋Š” ์ถ”๊ฐ€์ ์ธ ๊ณ ๋ ค์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค:

  • ๋ฆฌ์ „ ๊ฐ„ ๋ณต์ œ: ์™ธ๋ž˜ ํ‚ค ์ œ์•ฝ์กฐ๊ฑด๊ณผ ๋ณต์ œ ์ •์ฑ…์˜ ์ถฉ๋Œ

  • ์ž๋™ ์Šค์ผ€์ผ๋ง: ์ฐธ์กฐ ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์‚ฌ์˜ ์„ฑ๋Šฅ ์˜ํ–ฅ

  • ๋ฐฑ์—…/๋ณต๊ตฌ: ๊ด€๋ จ ํ…Œ์ด๋ธ”์˜ ์ผ๊ด€๋œ ๋ฐฑ์—… ๋ณด์žฅ

๐ŸŽฏ ๊ฒฐ๋ก  ๋ฐ ํ•ต์‹ฌ ํฌ์ธํŠธ

SQL์—์„œ ์ฐธ์กฐ๋Š” ๋‹จ์ˆœํžˆ ํ…Œ์ด๋ธ”์„ ์—ฐ๊ฒฐํ•˜๋Š” ๊ธฐ์ˆ ์ด ์•„๋‹Œ, ๋ฐ์ดํ„ฐ์˜ ํ’ˆ์งˆ๊ณผ ์‹ ๋ขฐ์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ํ•ต์‹ฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. ํ˜„๋Œ€์˜ ๋ณต์žกํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ์œ ์ง€ํ•˜๋ ค๋ฉด ์ฐธ์กฐ ์„ค๊ณ„์— ๋Œ€ํ•œ ๊นŠ์€ ์ดํ•ด๊ฐ€ ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ธฐ์–ต์‚ฌํ•ญ:

  1. ์ฐธ์กฐ๋Š” ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์˜ ๊ธฐ์ดˆ - ์™ธ๋ž˜ ํ‚ค ์ œ์•ฝ์กฐ๊ฑด์„ ํ†ตํ•ด ๋…ผ๋ฆฌ์ ์œผ๋กœ ๋ถˆ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ์„ ๋ฐฉ์ง€

  2. ๊ด€๊ณ„ ์œ ํ˜•์˜ ์ •ํ™•ํ•œ ํŒŒ์•… - ์ผ๋Œ€๋‹ค, ์ผ๋Œ€์ผ, ๋‹ค๋Œ€๋‹ค, ์ž๊ธฐ์ฐธ์กฐ ๊ด€๊ณ„์˜ ํŠน์„ฑ์„ ์ดํ•ดํ•˜๊ณ  ์ ์ ˆํžˆ ๊ตฌํ˜„

  3. ์ฐธ์กฐ ๋™์ž‘ ์˜ต์…˜์˜ ์‹ ์ค‘ํ•œ ์„ ํƒ - CASCADE, SET NULL, RESTRICT ๋“ฑ์˜ ์˜ต์…˜์ด ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž๋Š”์ง€ ๊ฒ€ํ† 

  4. ์„ฑ๋Šฅ๊ณผ ๋ฌด๊ฒฐ์„ฑ์˜ ๊ท ํ˜• - ์ฐธ์กฐ ๋ฌด๊ฒฐ์„ฑ ๋ณด์žฅ๊ณผ ์„ฑ๋Šฅ ์ตœ์ ํ™” ์‚ฌ์ด์˜ ์ ์ ˆํ•œ ๊ท ํ˜•์  ์ฐพ๊ธฐ

  5. ์ผ๊ด€๋œ ๋ช…๋ช… ๊ทœ์น™ - ํŒ€ ํ˜‘์—…๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ์œ„ํ•œ ์ฒด๊ณ„์ ์ธ ๋„ค์ด๋ฐ ์ปจ๋ฒค์…˜ ์ ์šฉ

SQL ์ฐธ์กฐ๋ฅผ ๋งˆ์Šคํ„ฐํ•˜๋Š” ๊ฒƒ์€ ๊ฒฌ๊ณ ํ•˜๊ณ  ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค๊ณ„์˜ ์ถœ๋ฐœ์ ์ž…๋‹ˆ๋‹ค. ์ด ํ•ธ๋“œ๋ถ์˜ ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ ์‹ค๋ฌด์—์„œ ๋งŒ๋‚˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ๊ด€๊ณ„๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์„ค๊ณ„ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ์˜ ๋ฌด๊ฒฐ์„ฑ์€ ๊ณง ๋น„์ฆˆ๋‹ˆ์Šค์˜ ์‹ ๋ขฐ์„ฑ์ด๋ฉฐ, SQL ์ฐธ์กฐ๋Š” ๊ทธ ์‹ ๋ขฐ์„ฑ์„ ๊ธฐ์ˆ ์ ์œผ๋กœ ๋’ท๋ฐ›์นจํ•˜๋Š” ํ•ต์‹ฌ ๋„๊ตฌ์ž„์„ ๊ธฐ์–ตํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

โ‚

๋ ˆํผ๋Ÿฐ์Šค(References)

์ฐธ์กฐ

Footnotes

  1. https://learn.microsoft.com/en-us/sql/relational-databases/tables/create-foreign-key-relationships?view=sql-server-ver17 โ†ฉ

  2. https://www.w3schools.com/sql/sql_foreignkey.asp โ†ฉ โ†ฉ2 โ†ฉ3

  3. https://stackoverflow.com/questions/41906587/database-design-without-relations-with-relations-should-i-use-foreign-keys โ†ฉ โ†ฉ2

  4. https://cloud.google.com/spanner/docs/foreign-keys/how-to โ†ฉ โ†ฉ2

  5. https://www.geeksforgeeks.org/dbms/foreign-key-in-dbms/ โ†ฉ

  6. https://www.ibm.com/docs/en/i/7.5.0?topic=constraints-referential โ†ฉ โ†ฉ2

  7. https://www.slainstitute.com/primary-key-and-foreign-in-sql/ โ†ฉ โ†ฉ2 โ†ฉ3

  8. https://milvus.io/ai-quick-reference/how-do-foreign-keys-work-in-sql โ†ฉ โ†ฉ2 โ†ฉ3 โ†ฉ4

  9. https://www.acceldata.io/blog/why-referential-integrity-constraints-are-vital-for-data-accuracy โ†ฉ

  10. https://docs.oracle.com/cd/E05553_01/books/admintool/admintool_DataModeling4.html โ†ฉ

  11. https://dev.mysql.com/doc/en/create-table-foreign-keys.html โ†ฉ

  12. https://opentextbc.ca/dbdesign01/chapter/chapter-9-integrity-rules-and-constraints/ โ†ฉ โ†ฉ2 โ†ฉ3 โ†ฉ4 โ†ฉ5 โ†ฉ6

  13. https://dev.to/bshadmehr/mastering-table-relationships-in-relational-databases-the-role-of-primary-and-foreign-keys-1go9 โ†ฉ โ†ฉ2

  14. https://www.cockroachlabs.com/blog/what-is-a-foreign-key/ โ†ฉ

  15. https://www.ibm.com/docs/en/db2/11.5.x?topic=constraints-foreign-key-referential โ†ฉ โ†ฉ2

  16. https://stackoverflow.com/questions/23771547/database-design-foreign-key-and-primary-key-relationships-across-3-tables โ†ฉ

  17. https://strapi.io/blog/5-key-sql-relationship-types-to-improve-database-design โ†ฉ

  18. https://learn.microsoft.com/en-us/sql/relational-databases/tables/primary-and-foreign-key-constraints?view=sql-server-ver17 โ†ฉ

  19. https://www.reddit.com/r/SQL/comments/17bq4p2/primary_key_vs_foreign_key/ โ†ฉ

  20. https://public.support.unisys.com/aseries/docs/ClearPath-MCP-20.0/82223819-004/section-000018865.html โ†ฉ โ†ฉ2

  21. https://www.geeksforgeeks.org/sql/relationships-in-sql-one-to-one-one-to-many-many-to-many/ โ†ฉ

  22. https://www.reddit.com/r/SQL/comments/1e14nqr/many_to_many_one_to_many_many_to_one/ โ†ฉ

  23. https://stackoverflow.com/questions/4601703/difference-between-one-to-many-and-many-to-one-relationship โ†ฉ

  24. https://www.devart.com/dbforge/sql/studio/sql-relationships.html โ†ฉ โ†ฉ2 โ†ฉ3

  25. https://www.metabase.com/learn/grow-your-data-skills/data-fundamentals/table-relationships โ†ฉ โ†ฉ2 โ†ฉ3

  26. https://stackoverflow.com/questions/25878192/how-to-add-a-foreign-key-referring-to-itself-in-sql-server-2008 โ†ฉ โ†ฉ2 โ†ฉ3

  27. https://www.geeksforgeeks.org/dbms/difference-between-on-delete-cascade-and-on-delete-set-null-in-dbms/ โ†ฉ โ†ฉ2 โ†ฉ3

  28. https://codefinity.com/courses/v2/5ac24d9d-4a16-45b3-8856-07dec028c5e9/3d6c4ab0-f470-4b5d-ad0e-5f76d28ca0af/7992cacf-81b2-4169-b8e9-6d2e322daf07 โ†ฉ

  29. https://www.dbvis.com/thetable/how-to-use-a-foreign-key-referring-to-the-source-table-in-postgres/ โ†ฉ

  30. https://support.microsoft.com/en-us/office/guide-to-table-relationships-30446197-4fbe-457b-b992-2f6fb812b58f โ†ฉ

  31. https://database.guide/understanding-self-referencing-foreign-keys-a-beginners-tutorial/ โ†ฉ โ†ฉ2

  32. https://stackoverflow.com/questions/5383612/setting-up-table-relations-what-do-cascade-set-null-and-restrict-do โ†ฉ

  33. https://voiceofthedba.com/2023/11/06/creating-a-self-referencing-fk-in-a-create-statement-sqlnewblogger/ โ†ฉ

  34. https://www.geeksforgeeks.org/sql/cascading-referential-integrity-constraints-in-sql-server-management-studio/ โ†ฉ