외래키(Foreign Key, FK)의 참조 무결성

외래키가 기본키를 참조할 때 참조무결성이 발생 가능한 상황

  1. 부모 테이블 - 데이터 삽입 : (X) 값이 생겨도 무관하다

  2. 부모 테이블 - 데이터 삭제 : (O) 참조 못할 수 있음

  3. 부모 테이블 - 데이터 수정 : (O) 참조 못할 수 있음

  4. 자식 테이블 - 데이터 삽입 : (O) 잘못된 값 삽입

  5. 자식 테이블 - 데이터 삭제 : (X) 참조할 테이블에 문제가 없기 때문에 가능성이 없다

  6. 자식 테이블 - 데이터 수정 : (O) 외래키가 수정되면 참조 무결성 발생

※ 부모테이블 데이터 삽입, 자식테이블 데이터 삭제시 참조 무결성이 발생하지 않는다.

부모, 자식 테이블 생성

부모테이블에 PK 설정 자식테이블에 부모테이블의 PK를 참조하는 FK 설정


mysql> create table parent_table(col1 int primary key);
Query OK, 0 rows affected (0.02 sec)

mysql> create table child_table(col1 int);
Query OK, 0 rows affected (0.02 sec)

mysql> alter table child_table add foreign key (col1) references parent_table(col1);
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

부모 PK 데이터 INSERT

mysql> insert into parent_table value (10);
Query OK, 1 row affected (0.00 sec)

mysql> insert into parent_table value (20);
Query OK, 1 row affected (0.00 sec)

mysql> insert into parent_table value (30);
Query OK, 1 row affected (0.00 sec)

mysql> insert into parent_table value (40);
Query OK, 1 row affected (0.00 sec)

mysql> insert into parent_table value (50);
Query OK, 1 row affected (0.00 sec)

mysql> select * from parent_table;
+------+
| col1 |
+------+
|   10 |
|   20 |
|   30 |
|   40 |
|   50 |
+------+
5 rows in set (0.00 sec)

자식 테이블 외래키가 지정된(부모 PK 참조) 필드에 부모 PK가 없는 값 입력

mysql> insert into child_table value (100);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`mysite`.`child_table`, CONSTRAINT `child_table_ibfk_1` FOREIGN KEY (`col1`) REFERENCES `parent_table` (`col1`))

부모테이블에 있는 값 입력

mysql> insert into child_table value (10);
Query OK, 1 row affected (0.00 sec)

mysql> insert into child_table value (20);
Query OK, 1 row affected (0.00 sec)

mysql> insert into child_table value (30);
Query OK, 1 row affected (0.00 sec)

mysql> select * from child_table;
+------+
| col1 |
+------+
|   10 |
|   20 |
|   30 |
+------+
3 rows in set (0.00 sec)

부모 테이블 데이터 삭제 시 오류

자식 테이블 데이터를 먼저 삭제하고 부모 데이터 삭제한다.

mysql> delete from parent_table where col1 = 10;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`mysite`.`child_table`, CONSTRAINT `child_table_ibfk_1` FOREIGN KEY (`col1`) REFERENCES `parent_table` (`col1`))

자식 삭제 후 부모 데이터 삭제

테이블도 자식, 부모 순으로 삭제해야한다

mysql> delete from child_table where col1 = 10;
Query OK, 1 row affected (0.00 sec)

mysql> delete from parent_table where col1 = 10;
Query OK, 1 row affected (0.04 sec)

mysql> select * from parent_table;
+------+
| col1 |
+------+
|   20 |
|   30 |
|   40 |
|   50 |
+------+
4 rows in set (0.00 sec)

mysql> select * from child_table;
+------+
| col1 |
+------+
|   20 |
|   30 |
+------+
2 rows in set (0.00 sec)

자식테이블 제약조건 확인


mysql> show create table child_table;
+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table       | Create Table                                                                                                                                                                                                                                |
+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| child_table | CREATE TABLE `child_table` (
  `col1` int DEFAULT NULL,
  KEY `col1` (`col1`),
  CONSTRAINT `child_table_ibfk_1` FOREIGN KEY (`col1`) REFERENCES `parent_table` (`col1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

제약조건 제거

ALTER TABLE child_table DROP CONSTRAINT child_table_ibkf_1;
mysql> alter table child_table drop constraint child_table_ibfk_1;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

FOREIGN KEY 비활성화

운영중인 서비스 및 타 테이블에 영향을 줄 수 있기 때문에 알아만 두고 넘어가자.

SELECT @@FOREIGN_KEY_CHECK;

비활성화

SET FOREIGN_KEY_CHECK = 0;

활성화

SET FOREIGN_KEY_CHECK = 1;
반응형

'MYSQL' 카테고리의 다른 글

[MYSQL][08] ALTER  (1) 2024.11.27
[MYSQL][07] ORDER BY  (0) 2024.11.26
[MYSQL][05] KEY  (0) 2024.11.24
[MYSQL][04] SELECT  (0) 2024.11.22
[MYSQL][03] CREATE : 회원 테이블 생성  (0) 2024.11.21
KEY

상품 테이블

상품코드 회사명 단가
A 교촌 25,000
B BBQ 30,000
C 네네 23,000
D 노랑통닭 22,000

판매 테이블

판매번호 상품코드 수량 판매일 판매금액
1 B 1 2024-11-19
2 A 1 2024-11-19
3 D 1 2024-11-19
4 C 1 2024-11-19

유일성

데이터베이스 내에서 중복되지 않도록 보장하며 고유하게 식별할 수 있는 것을 말한다. 예를 들어 주민등록번호, 학번 등이 있고 이 기준으로 하나의 데이터(사람)을 식별할 수 있다.

특정 필드를 기준으로 테이블 내에서 유일하게 하나를 선택할 수 있다면 유일성을 만족하게 되며 위 상품테이블 예시에서 상품코드 기준으로 중복없이 회사명, 단가를 확인할 수 있다.

최소성

후보키를 구성하는 속성의 집합에서 어느 하나라도 제거하면 더 이상 해당 키가 테이블의 튜플(행)을 고유하게 식별할 수 없는 경우를 최소성이라 한다.

즉, 최소성이란 후보키가 데이터를 고유하게 식별하기 위해 꼭 필요한 속성만 포함하고, 불필요한 속성을 포함하지 않는 상태를 의미한다.

다른 속성과 결합하지 않아도 유일성을 유지할 수 있는 필드는 최소성을 충족한다고 말한다.

키의 개념 및 종류

상품 테이블에서 유일성, 최소성을 만족하는 필드는 상품코드 또는 회사명이다.
이러한 키를 후보키(Candidate key)라고 하며 후보키 중에서 하나가 기본키가 될 수 있으며 기본키(Primary Key, PK)는 개발자가 직접 지정한다.

후보키 중에서 기본키가 되지 못한 키를 대체키(Alternative Key)라고 하며 유일성은 만족하지만 최소성을 만족하지 못하는 키를 슈퍼키(Super Key)라고 한다.

판매 테이블이 상품코드 필드를 값으로 상품 테이블을 참조하여 상품코드가 B라면 상품명 네네, 단가 23000을 확인할 수 있다. 다른 테이블의 기본키를 참조하는 현재 테이블의 필드를 외래키(Foreign Key, FK)라고 한다

무결성

무결성에는 개체, 참조, 도메인이 있다

개체 무결성 : 기본키(Primary Key, PK)는 중복 값 입력과 null도 불가능하다. 각 행을 고유하게 식별해야할 때 PK로 지정한다

도메인 무결성 : 각 열의 데이터가 타입, 형식 제한 조건을 준수해야 함을 뜻한다. 성별 필드의 경우 남, 여의 값만 저장되어야한다 등의 제약조건이 필요하며 데이터 타입, not null, check 제약 조건 등을 사용한다.

참조 무결성 : 자식 테이블의 FK(Foreing Key, FK)를 통해 자식테이블이 부모테이블을 참조할 수 있도록 보장한다.

외래키가 기본키를 참조할 때 참조 무결성이 발생 가능한 상황

  1. 상품 테이블 - 데이터 삽입 : X, 새로운 상품코드가 생겨 무관하다
  2. 상품 테이블 - 데이터 삭제 : O, 참조 못할 수 있음
  3. 상품 테이블 - 데이터 수정 : O, 참조 못할 수 있음
  4. 판매 테이블 - 데이터 삽입 : O, 잘못된 값 삽입
  5. 판매 테이블 - 데이터 삭제 : X, 참조할 테이블에 문제가 없기 때문에 가능성이 없다
  6. 판매 테이블 - 데이터 수정 : O, 외래키가 수정되면 참조 무결성 발생

따라서 상품 테이블의 데이터 삽입 또는 판매 테이블의 데이터 삭제는 참조 무결성이 발생할 가능성이 없다.

정리

  1. 후보키(Candidate key) : 유일성, 최소성을 만족하는 키
  2. 기본키(Primary Key, PK) : 후보키 중에서 선택
  3. 대체키(Alternative Key) : 기본키가 되지 못한 후보키
  4. 슈퍼키(Super Key) : 유일성은 만족하나 최소성을 만족하지 못하는 키
  5. 외래키(Foreign Key, FK) : 다른 테이블의 기본키를 참조하는 현재 테이블의 필드
  6. 기본키는 중복 값 입력과 null도 불가능 => 개체 무결성
반응형

Math.random()을 이용한 난수 생성

Java에서 난수를 생성할 때 가장 많이 사용되는 방법 중 하나가 Math.random() 메서드이다.
Math.random()은 java.lang.Math 클래스에 속한 정적 메서드이고 기본적으로 0.0 (포함)에서 1.0 (미포함) 사이의
난수를 생성한다

배열의 인덱스값을 랜덤으로 생성해서 배열을 셔플하거나,
1 ~ 45 범위의 로또 번호 생성, x y 좌표 랜덤 등 다양한 곳에 사용가능하다.

실수이기 때문에 정수를 원한다면 (int)로 캐스팅하여 정수로 변환한다.

시작수를 n, 종료를 m 이라고 할 때(이때 n,m은 양의 정수)

기본 활용 형식

(int)(Math.random() * m) + n

범위 : 1 ~ 45

(int)(Math.random() * 45) + 1

범위 : 0 ~ 5

(int)(Math.random() * 5)

시작수를 n, 종료를 m 이라고 할 때(이때 n은 음의 정수)

기본 활용 형식

(int)(Math.random()∗(m−n+1))+n

범위 : -10 ~ 10

(int)(Math.random()∗(10-(-10)+1)) - 10

범위 : - 2000 ~ 4000

(int)(Math.random()∗(4000−(-2000)+1)) - 2000

※ n, m의 절대값을 더한 후 1 더해주면 종료값이라 생각하면 편하다 => 6001

예제

// 0.0 이상 1.0 미만의 난수 생성
double ran1 = Math.random(); // 0.0 <= num < 1.0
System.out.println("0.0 이상 1.0 미만의 난수: " + ran1);
// 0부터 9까지의 정수 난수 생성
// (Math.random() * 10) 의 결과는 0.0 (포함)에서 10.0 (미포함) 사이의 실수
// 정수로 변환하기 위해 (int)로 캐스팅 
// 0부터 9까지의 정수가 생성
int ran2 = (int)(Math.random() * 10); // 0 <= num <= 9
System.out.println("0부터 9까지의 정수 난수: " + ran2);
// 1부터 10까지의 정수 난수 생성
// 1을 더함으로써 난수의 범위를 1에서 10으로 변경
// 0 + 1 <= num <= 9 + 1
// 1 <= num <= 10

int ran3 = (int)(Math.random() * 10) + 1;
System.out.println("1부터 10까지의 정수 난수: " + ran3);
// -10부터 10까지의 정수 난수 생성
// (Math.random() * 21)의 결과는 0.0 (포함)에서 21.0 (미포함) 사이의 실수입니다.
// 여기에 -10을 더해 난수의 범위를 -10에서 10
// -10부터 10까지의 정수가 생성
int ran4 = (int)(Math.random() * 21) - 10; // -10 <= num <= 0
System.out.println("-10부터 0까지의 정수 난수: " + ran4);
반응형

'JAVA' 카테고리의 다른 글

[JAVA][09] Scanner 클래스  (0) 2024.11.17
[JAVA][07] 형변환(Type Casting)  (0) 2024.10.22
[JAVA][06] 변수 기본 타입(Primitive Type)  (0) 2024.10.12
[JAVA][05] 변수값 바꾸기1  (0) 2024.10.09
[JAVA][04] 변수(Variable)란?  (1) 2024.10.03

+ Recent posts