안녕하세요, 코딩하는곰입니다! 오늘은 MySQL과 MariaDB에서 데이터 무결성을 보장해주는 중요한 기능인 FOREIGN KEY(외래 키)에 대해 깊이 있게 알아보겠습니다. 관계형 데이터베이스의 핵심 개념 중 하나인 외래 키는 테이블 간의 관계를 설정하고 데이터의 일관성을 유지하는 데 필수적인 요소입니다. 20년 이상의 데이터베이스 개발 경험을 바탕으로 외래 키의 설정 방법부터 실제 활용 팁까지 상세히 설명드리겠습니다.
💻 프로그래밍에 관심이 많다면, (파이썬) 세트(Set) 자료형 완벽 가이드 중복 제거부터 집합 연산까지를 참고해보세요.
FOREIGN KEY(외래 키)는 관계형 데이터베이스에서 두 테이블 간의 관계를 정의하는 제약 조건입니다. 한 테이블의 컬럼이 다른 테이블의 기본 키(Primary Key)나 유니크 키(Unique Key)를 참조함으로써 데이터의 참조 무결성을 보장합니다.
MySQL과 MariaDB에서는 외래 키를 생성할 때 자동으로 해당 컬럼에 인덱스가 생성됩니다. 이는 참조 무결성 검사 성능을 최적화하기 위한 중요한 기능입니다.
-- 외래 키 생성 시 자동으로 인덱스가 생성되는 예제CREATE TABLE parent_table (id INT PRIMARY KEY,name VARCHAR(50));CREATE TABLE child_table (id INT PRIMARY KEY,parent_id INT,FOREIGN KEY (parent_id) REFERENCES parent_table(id)-- parent_id 컬럼에 자동으로 인덱스가 생성됨);
💡 개발 프로젝트 아이디어가 필요하다면, (자바 기초) 타입 변환 완벽 가이드 자동(Widening) vs 강제(Narrowing) 형변환를 참고해보세요.
CREATE TABLE child_table (column1 datatype,column2 datatype,...FOREIGN KEY (foreign_key_column)REFERENCES parent_table (parent_column)[ON DELETE reference_option][ON UPDATE reference_option]);
-- 부모 테이블 생성CREATE TABLE departments (department_id INT PRIMARY KEY AUTO_INCREMENT,department_name VARCHAR(100) NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);-- 자식 테이블 생성 (외래 키 포함)CREATE TABLE employees (employee_id INT PRIMARY KEY AUTO_INCREMENT,first_name VARCHAR(50) NOT NULL,last_name VARCHAR(50) NOT NULL,department_id INT,hire_date DATE,salary DECIMAL(10,2),-- 외래 키 설정FOREIGN KEY (department_id)REFERENCES departments(department_id)ON DELETE SET NULLON UPDATE CASCADE,INDEX idx_department (department_id));
ALTER TABLE child_tableADD CONSTRAINT constraint_nameFOREIGN KEY (foreign_key_column)REFERENCES parent_table (parent_column)[ON DELETE reference_option][ON UPDATE reference_option];
-- 기존 테이블에 외래 키 추가ALTER TABLE ordersADD CONSTRAINT fk_orders_customersFOREIGN KEY (customer_id)REFERENCES customers(customer_id)ON DELETE RESTRICTON UPDATE CASCADE;-- 복합 외래 키 추가 예제ALTER TABLE order_itemsADD CONSTRAINT fk_order_items_ordersFOREIGN KEY (order_id, product_id)REFERENCES orders(order_id, product_id)ON DELETE CASCADE;
-- 복합 기본 키를 가진 부모 테이블CREATE TABLE order_details (order_id INT,product_id INT,quantity INT,price DECIMAL(10,2),PRIMARY KEY (order_id, product_id));-- 복합 외래 키를 가진 자식 테이블CREATE TABLE shipments (shipment_id INT PRIMARY KEY,order_id INT,product_id INT,shipment_date DATE,status VARCHAR(20),FOREIGN KEY (order_id, product_id)REFERENCES order_details(order_id, product_id)ON DELETE CASCADE);
회원가입이나 비밀번호 변경 시 안전한 비밀번호를 빠르게 생성할 수 있는 온라인 도구가 유용합니다.
-- 특정 테이블의 외래 키 정보 조회SELECTTABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME,REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAMEFROM INFORMATION_SCHEMA.KEY_COLUMN_USAGEWHERE TABLE_SCHEMA = 'your_database_name'AND TABLE_NAME = 'your_table_name'AND REFERENCED_TABLE_NAME IS NOT NULL;-- 더 상세한 외래 키 정보SELECTrc.CONSTRAINT_NAME,rc.TABLE_NAME,rc.REFERENCED_TABLE_NAME,rc.UPDATE_RULE,rc.DELETE_RULEFROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rcWHERE rc.CONSTRAINT_SCHEMA = 'your_database_name';
-- 외래 키 제약 조건 삭제ALTER TABLE child_tableDROP FOREIGN KEY constraint_name;-- 인덱스는 별도로 삭제해야 함 (필요한 경우)ALTER TABLE child_tableDROP INDEX index_name;
외래 키 컬럼과 참조 컬럼의 데이터 타입은 정확히 일치해야 합니다.
-- 올바른 예: 데이터 타입이 완전히 일치CREATE TABLE parent (id INT UNSIGNED PRIMARY KEY);CREATE TABLE child (parent_id INT UNSIGNED,FOREIGN KEY (parent_id) REFERENCES parent(id));-- 잘못된 예: 데이터 타입이 일치하지 않음CREATE TABLE child_error (parent_id INT, -- UNSIGNED가 아님FOREIGN KEY (parent_id) REFERENCES parent(id) -- 에러 발생);
-- 대량 데이터 삽입 시 외래 키 검사 일시적 비활성화SET foreign_key_checks = 0;-- 대량의 데이터 삽입 작업 수행INSERT INTO child_table (...) VALUES (...), (...), ...;-- 외래 키 검사 다시 활성화SET foreign_key_checks = 1;-- 외래 키 검사 후 무결성 확인CHECK TABLE child_table;
-- 전자상거래 시스템 예제CREATE TABLE users (user_id INT PRIMARY KEY AUTO_INCREMENT,email VARCHAR(255) UNIQUE NOT NULL,password_hash VARCHAR(255) NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);CREATE TABLE user_addresses (address_id INT PRIMARY KEY AUTO_INCREMENT,user_id INT NOT NULL,address_type ENUM('home', 'work', 'other') DEFAULT 'home',street VARCHAR(255),city VARCHAR(100),zip_code VARCHAR(20),FOREIGN KEY (user_id) REFERENCES users(user_id)ON DELETE CASCADEON UPDATE CASCADE,INDEX idx_user_address (user_id, address_type));CREATE TABLE orders (order_id INT PRIMARY KEY AUTO_INCREMENT,user_id INT NOT NULL,order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,total_amount DECIMAL(10,2),status ENUM('pending', 'processing', 'shipped', 'delivered', 'cancelled'),FOREIGN KEY (user_id) REFERENCES users(user_id)ON DELETE RESTRICT -- 사용자 삭제 시 주문이 있으면 삭제 방지ON UPDATE CASCADE,INDEX idx_user_orders (user_id, order_date));
외래 키는 트랜잭션과 함께 사용될 때 진가를 발휘합니다. 여러 테이블에 걸친 데이터 변경 작업의 원자성을 보장합니다.
START TRANSACTION;-- 여러 테이블에 걸친 작업 수행INSERT INTO parent_table (...) VALUES (...);INSERT INTO child_table (parent_id, ...) VALUES (LAST_INSERT_ID(), ...);-- 외래 키로 인해 무결성이 자동으로 검증됨COMMIT;
인터넷을 사용할 때 우리가 사용하는 IP는 생각보다 많은 정보를 담고 있습니다. 아이피 기반 위치 조회로 간단히 알아볼 수 있습니다.
FOREIGN KEY는 MySQL과 MariaDB에서 데이터 무결성을 보장하는 강력한 도구입니다. 적절하게 설계되고 구현된 외래 키는 데이터베이스의 신뢰성을 크게 향상시킬 수 있습니다. 하지만 성능 implications을 이해하고 상황에 맞는 옵션을 선택하는 것이 중요합니다. 실제 프로젝트에서는 데이터 모델링 단계에서부터 외래 키 관계를 신중하게 설계하고, ON DELETE/ON UPDATE 옵션을業務需求에 맞게 설정하는 것이 좋습니다. 항상 외래 키의 존재를 인지하고 개발하며, 필요時에는 temporary로 foreign key checks를 disable하는 방법도 기억해두세요. 다음 포스팅에서는 외래 키의 고급 활용법과 troubleshooting 방법에 대해 더 깊이 알아보겠습니다!
두뇌 건강을 위해 매일 스도쿠를 풀 고 싶다면, AI 기반 힌트와 스토리 모드를 제공하는 스도쿠 저니를 다운로드해보세요.
