๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ฆฌ์์ ๋ฌด๊ฒฐ์ฑ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ด๋ฅผ ๋ณด์ฅํ๊ธฐ ์ํ ๋ฐฉ๋ฒ ์ค ํ๋๊ฐ ๋ฐ๋ก ์ธ๋ ํค(Foreign Key) ์ ์ฝ ์กฐ๊ฑด์ ๋๋ค. MariaDB์์๋ ์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด์ ํตํด ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ๊ณผ ๋ฌด๊ฒฐ์ฑ์ ์ ์งํ ์ ์์ต๋๋ค. ์ด๋ฒ ํฌ์คํ ์์๋ MariaDB ์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด์ ๊ฐ๋ ๋ถํฐ ์ค์ ๋ฐฉ๋ฒ, ๋ค์ํ ์ต์ , ์ค์ ์์ , ๊ทธ๋ฆฌ๊ณ ์์ฃผ ๋ฐ์ํ๋ ๋ฌธ์ ์ ํด๊ฒฐ ๋ฐฉ๋ฒ๊น์ง ์๋ฒฝํ๊ฒ ์๋ดํด ๋๋ฆฌ๊ฒ ์ต๋๋ค.
โฃ ๋ชฉ์ฐจ
๊ธฐ๋ณธ ๊ฐ๋ ๐งฉ
์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด์ ์ ์
์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด์ ํ ํ ์ด๋ธ์ ํ๋๊ฐ ๋ค๋ฅธ ํ ์ด๋ธ์ ๊ธฐ๋ณธ ํค(Primary Key)์ ์ฐ๊ฒฐ๋๋๋ก ๊ฐ์ ํ๋ ์ ์ฝ ์กฐ๊ฑด์ ๋๋ค. ์ด๋ฅผ ํตํด ๋ ํ ์ด๋ธ ๊ฐ์ ์ฐธ์กฐ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํฉ๋๋ค.
์ธ๋ ํค์ ์ญํ ๊ณผ ํ์์ฑ
์ธ๋ ํค๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ค์ํ ์ญํ ์ ํฉ๋๋ค. ๋ ํ ์ด๋ธ ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ช ํํ๊ฒ ์ ์ํ๊ณ , ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ์ ์งํ๋ฉฐ, ์๋ชป๋ ๋ฐ์ดํฐ ์ ๋ ฅ์ ๋ฐฉ์งํฉ๋๋ค.
MARIADB์์ ์ธ๋ ํค ์ฌ์ฉ์ ์ฅ์
- ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ๋ณด์ฅ: ์ธ๋ ํค๋ ๊ด๋ จ ๋ฐ์ดํฐ๊ฐ ํญ์ ์ผ๊ด์ฑ์ ์ ์งํ๋๋ก ํฉ๋๋ค.
- ์๋ ๋ฐ์ดํฐ ์ญ์ /์ ๋ฐ์ดํธ: ๊ด๋ จ ๋ฐ์ดํฐ๋ฅผ ์๋์ผ๋ก ์ญ์ ํ๊ฑฐ๋ ์ ๋ฐ์ดํธํ ์ ์์ต๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ ๋ช ํํ: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๊ณ ์ ํ ์ด๋ธ ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ช ํํ๊ฒ ํฉ๋๋ค.
MariaDB์์ ์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด ์ค์ ํ๊ธฐ๐ง
์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด ๊ตฌ๋ฌธ ๋ฐ ์ต์ ์ค๋ช
์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด์ ์ค์ ํ๊ธฐ ์ํด์๋ ๋ค์๊ณผ ๊ฐ์ SQL ๊ตฌ๋ฌธ์ ์ฌ์ฉํฉ๋๋ค.
CREATE TABLE `์์ํ
์ด๋ธ` (
`id` INT PRIMARY KEY,
`๋ถ๋ชจ_id` INT,
FOREIGN KEY (`๋ถ๋ชจ_id`) REFERENCES `๋ถ๋ชจํ
์ด๋ธ`(`id`)
);
๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ ๋ฐ ์์
์๋ฅผ ๋ค์ด, orders ํ ์ด๋ธ๊ณผ customers ํ ์ด๋ธ์ด ์๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค. orders ํ ์ด๋ธ์ customer_id๊ฐ customers ํ ์ด๋ธ์ id์ ์ธ๋ ํค ๊ด๊ณ๋ฅผ ๋งบ๋๋ก ์ค์ ํ ์ ์์ต๋๋ค.
CREATE TABLE `customers` (
`id` INT PRIMARY KEY,
`name` VARCHAR(100)
);
CREATE TABLE `orders` (
`id` INT PRIMARY KEY,
`order_date` DATE,
`customer_id` INT,
FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`)
);
์ธ๋ ํค ์์ฑ ์ ์ฃผ์์ฌํญ
- ์ธ๋ ํค๊ฐ ์ฐธ์กฐํ๋ ์นผ๋ผ๊ณผ ๋์ผํ ๋ฐ์ดํฐ ํ์ ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
- ์ฐธ์กฐ๋๋ ํ ์ด๋ธ(๋ถ๋ชจ ํ ์ด๋ธ)์ ๊ธฐ๋ณธ ํค ๋๋ ๊ณ ์ ํค(UNIQUE KEY)๊ฐ ์ค์ ๋์ด ์์ด์ผ ํฉ๋๋ค.
์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด ์ต์ โ๏ธ
์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด ์ต์
์ธ๋ ํค ์ค์ ์ ์ฌ์ฉํ ์ ์๋ ์ฃผ์ ์ต์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
1. CASCADE
CASCADE ์ต์ ์ ๋ถ๋ชจ ํ ์ด๋ธ์ ๋ ์ฝ๋๊ฐ ๋ณ๊ฒฝ๋ ๋ ์์ ํ ์ด๋ธ์ ๋ ์ฝ๋๋ฅผ ์๋์ผ๋ก ๋ณ๊ฒฝํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
- ON DELETE CASCADE: ๋ถ๋ชจ ํ ์ด๋ธ์ ๋ ์ฝ๋๊ฐ ์ญ์ ๋ ๋, ํด๋น ๋ ์ฝ๋๋ฅผ ์ฐธ์กฐํ๋ ์์ ํ ์ด๋ธ์ ๋ชจ๋ ๋ ์ฝ๋๋ ํจ๊ป ์ญ์ ๋ฉ๋๋ค.
- ON UPDATE CASCADE: ๋ถ๋ชจ ํ ์ด๋ธ์ ๊ธฐ๋ณธ ํค๊ฐ ์ ๋ฐ์ดํธ๋ ๋, ํด๋น ํค๋ฅผ ์ฐธ์กฐํ๋ ์์ ํ ์ด๋ธ์ ์ธ๋ ํค ๊ฐ๋ ํจ๊ป ์ ๋ฐ์ดํธ๋ฉ๋๋ค.
2. SET NULL
SET NULL ์ต์ ์ ๋ถ๋ชจ ํ ์ด๋ธ์ ๋ ์ฝ๋๊ฐ ๋ณ๊ฒฝ๋ ๋ ์์ ํ ์ด๋ธ์ ์ธ๋ ํค ๊ฐ์ NULL๋ก ์ค์ ํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
- ON DELETE SET NULL: ๋ถ๋ชจ ํ ์ด๋ธ์ ๋ ์ฝ๋๊ฐ ์ญ์ ๋ ๋, ํด๋น ๋ ์ฝ๋๋ฅผ ์ฐธ์กฐํ๋ ์์ ํ ์ด๋ธ์ ์ธ๋ ํค ๊ฐ์ด NULL๋ก ์ค์ ๋ฉ๋๋ค.
- ON UPDATE SET NULL: ๋ถ๋ชจ ํ ์ด๋ธ์ ๊ธฐ๋ณธ ํค๊ฐ ์ ๋ฐ์ดํธ๋ ๋, ํด๋น ํค๋ฅผ ์ฐธ์กฐํ๋ ์์ ํ ์ด๋ธ์ ์ธ๋ ํค ๊ฐ์ด NULL๋ก ์ค์ ๋ฉ๋๋ค.
3. RESTRICT
RESTRICT ์ต์ ์ ๋ถ๋ชจ ํ ์ด๋ธ์ ๋ ์ฝ๋๊ฐ ๋ณ๊ฒฝ๋ ๋ ์์ ํ ์ด๋ธ์ ๋ ์ฝ๋๊ฐ ์ฐธ์กฐํ๊ณ ์์ผ๋ฉด ๋ณ๊ฒฝ์ ๊ฑฐ๋ถํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
- ON DELETE RESTRICT: ๋ถ๋ชจ ํ ์ด๋ธ์ ๋ ์ฝ๋๊ฐ ์์ ํ ์ด๋ธ์์ ์ฐธ์กฐ๋๊ณ ์์ผ๋ฉด ์ญ์ ๋ฅผ ๊ฑฐ๋ถํฉ๋๋ค.
- ON UPDATE RESTRICT: ๋ถ๋ชจ ํ ์ด๋ธ์ ๊ธฐ๋ณธ ํค๊ฐ ์์ ํ ์ด๋ธ์์ ์ฐธ์กฐ๋๊ณ ์์ผ๋ฉด ์ ๋ฐ์ดํธ๋ฅผ ๊ฑฐ๋ถํฉ๋๋ค.
3.NO ACTIOIN
NO ACTION ์ต์ ์ ๋ถ๋ชจ ํ ์ด๋ธ์ ๋ ์ฝ๋๊ฐ ๋ณ๊ฒฝ๋ ๋ ์์ ํ ์ด๋ธ์ ์๋ฌด๋ฐ ์๋ ๋ณ๊ฒฝ์ ์ํํ์ง ์์ต๋๋ค. ๋ถ๋ชจ ํ ์ด๋ธ์ ๋ณ๊ฒฝ์ด ์์ ํ ์ด๋ธ์ ์ ์ฝ ์กฐ๊ฑด์ ์๋ฐํ๋ฉด ์๋ฌ๋ฅผ ๋ฐ์์ํต๋๋ค.
- ON DELETE NO ACTION: ๋ถ๋ชจ ํ ์ด๋ธ์ ๋ ์ฝ๋๊ฐ ์ญ์ ๋ ๋ ์์ ํ ์ด๋ธ์์ ์ฐธ์กฐ๋๊ณ ์์ผ๋ฉด ์๋ฌ๋ฅผ ๋ฐ์์ํค๊ณ ์ญ์ ๋ฅผ ์ํํ์ง ์์ต๋๋ค.
- ON UPDATE NO ACTION: ๋ถ๋ชจ ํ ์ด๋ธ์ ๊ธฐ๋ณธ ํค๊ฐ ์ ๋ฐ์ดํธ๋ ๋ ์์ ํ ์ด๋ธ์์ ์ฐธ์กฐ๋๊ณ ์์ผ๋ฉด ์๋ฌ๋ฅผ ๋ฐ์์ํค๊ณ ์ ๋ฐ์ดํธ๋ฅผ ์ํํ์ง ์์ต๋๋ค.
๊ฐ ์ต์ ์ ์ฐจ์ด์ ๋ฐ ์ฌ์ฉ ์ฌ๋ก
- CASCADE: ๊ณ์ธต์ ๋ฐ์ดํฐ ๊ตฌ์กฐ์์ ์ ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ณ ๊ฐ์ ์ญ์ ํ๋ฉด ํด๋น ๊ณ ๊ฐ์ ์ฃผ๋ฌธ๋ ๋ชจ๋ ์ญ์ ๋ฉ๋๋ค.
- SET NULL: ๊ด๊ณ๊ฐ ๋์ด์ก์์ ๋ช ํํ๊ฒ ํ์ํ๊ณ ์ ํ ๋ ์ฌ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ณ ๊ฐ์ ์ญ์ ํ๋ฉด ํด๋น ์ฃผ๋ฌธ์ ๊ณ ๊ฐ ID๋ฅผ NULL๋ก ์ค์ ํฉ๋๋ค.
- RESTRICT: ์ค์ํ ์ฐธ์กฐ ๋ฐ์ดํฐ๋ฅผ ์ค์๋ก ์ญ์ ํ์ง ์๋๋ก ๋ฐฉ์งํฉ๋๋ค.
- NO ACTION: ๋ณต์กํ ํธ๋์ญ์ ์ฒ๋ฆฌ ์ ์ ์ฉํฉ๋๋ค.
์์ ์ ํจ๊ป ์ดํดํ๊ธฐ
-- CASCADE ์์
CREATE TABLE `orders` (
`id` INT PRIMARY KEY,
`order_date` DATE,
`customer_id` INT,
FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`) ON DELETE CASCADE ON UPDATE CASCADE
);
-- SET NULL ์์
CREATE TABLE `orders` (
`id` INT PRIMARY KEY,
`order_date` DATE,
`customer_id` INT,
FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`) ON DELETE SET NULL ON UPDATE SET NULL
);
์ค์ ์์ ๐ป
๊ฐ๋จํ ํ ์ด๋ธ ์์ฑ ๋ฐ ์ธ๋ ํค ์ค์ ์์
CREATE TABLE `products` (
`id` INT PRIMARY KEY,
`name` VARCHAR(100)
);
CREATE TABLE `orders` (
`id` INT PRIMARY KEY,
`order_date` DATE,
`product_id` INT,
FOREIGN KEY (`product_id`) REFERENCES `products`(`id`)
);
๋ค์ํ ์ธ๋ ํค ์ต์ ์ ์ ์ฉํ ๋ณต์กํ ์์
CREATE TABLE `customers` (
`id` INT PRIMARY KEY,
`name` VARCHAR(100)
);
CREATE TABLE `orders` (
`id` INT PRIMARY KEY,
`order_date` DATE,
`customer_id` INT,
FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`) ON DELETE SET NULL ON UPDATE CASCADE
);
์ธ๋ ํค ์ค์ ํ ๋ฐ์ดํฐ ์ฝ์ , ์ญ์ , ์ ๋ฐ์ดํธ ์์ ๋์ ํ์ธ
-- ๊ณ ๊ฐ ๋ฐ ์ฃผ๋ฌธ ๋ฐ์ดํฐ ์ฝ์
INSERT INTO `customers` (`id`, `name`) VALUES (1, 'John Doe');
INSERT INTO `orders` (`id`, `order_date`, `customer_id`) VALUES (1, '2023-01-01', 1);
-- ๊ณ ๊ฐ ๋ฐ์ดํฐ ์
๋ฐ์ดํธ
UPDATE `customers` SET `id` = 2 WHERE `id` = 1;
-- ์ฃผ๋ฌธ ๋ฐ์ดํฐ ํ์ธ
SELECT * FROM `orders`; -- customer_id๊ฐ 2๋ก ์
๋ฐ์ดํธ๋จ
-- ๊ณ ๊ฐ ๋ฐ์ดํฐ ์ญ์
DELETE FROM `customers` WHERE `id` = 2;
-- ์ฃผ๋ฌธ ๋ฐ์ดํฐ ํ์ธ
SELECT * FROM `orders`; -- customer_id๊ฐ NULL๋ก ์ค์ ๋จ
์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด ๊ด๋ฆฌ๐ ๏ธ
์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด ์์ ๋ฐ ์ญ์ ๋ฐฉ๋ฒ
-- ์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด ์ญ์
ALTER TABLE `orders` DROP FOREIGN KEY `orders_ibfk_1`;
-- ์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด ์์
ALTER TABLE `orders` ADD CONSTRAINT `fk_customer_id` FOREIGN KEY (`customer_id`) REFERENCES customers(`id`) ON DELETE CASCADE;
์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด ํ์ธ ๋ฐ ๋๋ฒ๊น ํ
-- ์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด ํ์ธ
SHOW CREATE TABLE `orders`;
-- ์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด ๋๋ฒ๊น
-- ๊ด๋ จ ์ค๋ฅ ๋ฉ์์ง ํ์ธ
-- ์ธ๋ ํค ์ค์ ์ ์๋ชปํ ๋ถ๋ถ์ ์์
์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํ ์ธ๋ ํค ๊ด๋ฆฌ ์๋ น
- ์ธ๋ ํค๊ฐ ์์ฃผ ์ฐธ์กฐ๋๋ ์นผ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ์ฌ ์ฑ๋ฅ์ ํฅ์ํฉ๋๋ค.
- ๋๋์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ ๋๋ ์ธ๋ ํค ์ ์ฝ ์กฐ๊ฑด์ ์ ์ ๋นํ์ฑํํ๋ ๊ฒ๋ ๊ณ ๋ คํด ๋ณผ ์ ์์ต๋๋ค.
๐์ฌ๊ธฐ์ ์ ๊น! ์ธ๋ฑ์ค ์ถ๊ฐ, ํ์ธํด ๋ณด๊ธฐ!
MariaDB์์ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค. ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ๋ ๊ธฐ๋ณธ ๊ตฌ๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
CREATE INDEX `์ธ๋ฑ์ค๋ช
` ON `ํ
์ด๋ธ๋ช
`(`์ปฌ๋ผ๋ช
`);
์๋ฅผ ๋ค์ด, orders ํ
์ด๋ธ์์ customer_id ์นผ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํด ๋ณด๊ฒ ์ต๋๋ค.
CREATE INDEX `idx_customer_id` ON `orders`(`customer_id`);
์ธ๋ฑ์ค๊ฐ ์ ์ถ๊ฐ๋์๋์ง ํ์ธํ๋ ค๋ฉด ๋ค์ ๋ช
๋ น์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด ๋ช
๋ น์ orders ํ
์ด๋ธ์ ์๋ ๋ชจ๋ ์ธ๋ฑ์ค๋ฅผ ๋ณด์ฌ์ค๋๋ค.
SHOW INDEX FROM `orders`;
์์ฃผ ๋ฐ์ํ๋ ๋ฌธ์ ์ ํด๊ฒฐ ๋ฐฉ๋ฒ๐
์ธ๋ ํค ๊ด๋ จ ์ค๋ฅ ๋ฉ์์ง์ ๊ทธ ํด๊ฒฐ ๋ฐฉ๋ฒ
- Error 1452: Cannot add or update a child row: ๋ถ๋ชจ ํ ์ด๋ธ์ ์ฐธ์กฐ๋๋ ํค๊ฐ ์กด์ฌํ์ง ์์์ ์๋ฏธํฉ๋๋ค. ๋ถ๋ชจ ํ ์ด๋ธ์ ํด๋น ํค๋ฅผ ๋จผ์ ์ถ๊ฐํฉ๋๋ค.
- Error 1451: Cannot delete or update a parent row: ์์ ํ ์ด๋ธ์์ ์ฐธ์กฐ ์ค์ธ ๋ถ๋ชจ ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ๋๋ ์ ๋ฐ์ดํธํ๋ ค ํ ๋ ๋ฐ์ํฉ๋๋ค. ์์ ํ ์ด๋ธ์ ๊ด๋ จ ๋ฐ์ดํฐ๋ฅผ ๋จผ์ ์ฒ๋ฆฌํฉ๋๋ค.
์ธ๋ ํค ์ค์ ์ ํํ ์ ์ง๋ฅด๋ ์ค์์ ํผํ๋ ๋ฐฉ๋ฒ
- ๋ฐ์ดํฐ ํ์ ๋ถ์ผ์น: ์ธ๋ ํค์ ์ฐธ์กฐํ๋ ํค์ ๋ฐ์ดํฐ ํ์ ์ด ์ผ์นํด์ผ ํฉ๋๋ค.
- ์กด์ฌํ์ง ์๋ ํค ์ฐธ์กฐ: ๋ถ๋ชจ ํ ์ด๋ธ์ ์กด์ฌํ์ง ์๋ ํค๋ฅผ ์ฐธ์กฐํ๋ ค๊ณ ํ์ง ์๋๋ก ์ฃผ์ํฉ๋๋ค.
- ์ ์ ํ ์ต์ ์ค์ : ๋ฐ์ดํฐ์ ํน์ฑ๊ณผ ์ฌ์ฉ ์๋๋ฆฌ์ค์ ๋ง๋ ์ต์ ์ ์ค์ ํด์ผ ํฉ๋๋ค.
ํต์ฌ ๋ด์ฉ๐