제약조건
NOT NULL
UNIQUE
PRIMARY KEY
FOREIGN KEY
[연관된 필드 지정]
//삭제 및 수정시 연관되어 있는 필드 같이 삭제 및 수정
ON DELETE CASCADE
ON UPDATE CASCADE
// 삭제 및 수정시 연관되어 있는 필드 NULL
ON DELETE SET NULL
ON UPDATE SET NULL
// 삭제 및 수정시 연관되어 있는 필드 기본값으로 설정
ON DELETE SET DEFAULT
ON UPDATE SET DEFAULT
// 참조하는 테이블에 데이터 남아있으면 삭제 불가
ON DELETE RESTRICT
ON UPDATE RESTRICT
DEFAULT
CHECK
ALTER TABLE sopt_32
ADD CONSTRAINT SOPT_CK_NAME CHECK NUM IN (1, 2, 3, 4);
이상 현상
제 1정규형
모든 속성의 도메인이 더 이상 분해되지 않는 원자값으로만 구성된 것
이름 | 이메일 |
---|---|
졍이 | p@naver.com, n@naver.com, k@naver.com |
현이 | q@naver.com |
린이 | j@naver.com, jk@naver.com |
슬이 | dd@naver.com |
⬇️ 원자값으로 구성되도록
이름 | 이메일 |
---|---|
졍이 | p@naver.com |
졍이 | n@naver.com |
졍이 | k@naver.com |
현이 | q@naver.com |
린이 | j@naver.com |
린이 | jk@naver.com |
슬이 | dd@naver.com |
재 2정규형
모든 속성이 기본키에 완전 함수 종속되도록 한다.
부분 함수 종속 제거하고 모든 속성이 기본키에 완전 함수 종속되도록 분해
학생번호 | 강좌이름 | 교수명 | 성적 |
---|---|---|---|
1 | 알고리즘 | 박씨 | 100 |
2 | 알고리즘 | 박씨 | 80 |
3 | 운영체제 | 강씨 | 70 |
4 | 운영체제 | 강씨 | 90 |
5 | 데이터 구조 | 민씨 | 100 |
강좌 이름 -> 교수명
으로 교수명은 강좌이름에 의해 결정되므로 종속되어 있다고 할 수 있다.⬇️ 부분적 함수 종속 제거하기
두개의 구조로 나누기 가능
[수업 릴레이션]
학생번호 | 강좌이름 | 성적 |
---|---|---|
1 | 알고리즘 | 100 |
2 | 알고리즘 | 80 |
3 | 운영체제 | 70 |
4 | 운영체제 | 90 |
5 | 데이터 구조 | 100 |
[강좌 릴레이션]
강좌이름 | 교수명 |
---|---|
알고리즘 | 박씨 |
알고리즘 | 박씨 |
운영체제 | 강씨 |
운영체제 | 강씨 |
데이터 구조 | 민씨 |
-> 다음과 같이 두개의 구조로 나누면 부분 함수 종속을 제거할 수 있다.
제 3정규형
모든 속성이 기본키에 이행적 함수 종속 되지 않는 경우
학생번호 | 강좌이름 | 교수명 |
---|---|---|
1 | 알고리즘 | 박씨 |
2 | 알고리즘 | 박씨 |
3 | 운영체제 | 이씨 |
4 | 운영체제 | 이씨 |
5 | 데이터 구조 | 강씨 |
-> 이러한 구조로 학생번호는 교수명을 결정할 수 있기 때문에 이행적 함수 종속 구조를 갖고 있다.
⬇️ 이행적 함수 종속 제거하기
[수강신청 릴레이션]
학생번호 | 강좌이름 |
---|---|
1 | 알고리즘 |
2 | 알고리즘 |
3 | 운영체제 |
4 | 운영체제 |
5 | 데이터 구조 |
[강의 릴레이션]
강좌이름 | 교수명 |
---|---|
알고리즘 | 박씨 |
알고리즘 | 박씨 |
운영체제 | 이씨 |
운영체제 | 이씨 |
데이터 구조 | 강씨 |
-> 다음과 같이 수강신청, 강의 릴레이션 2개로 나누어 표현하면 이행적 함수 종속을 제거할 수 있다.
@Entity
@DynamicUpdate
public class User {
// Existing data and methods
}
@Pattern(regexp = "^[가-힣a-zA-Z]{2,10}$", message = "닉네임 형식에 맞지 않습니다.")
-> 이런식으로 문자열 형식을 체크하기 위한 것이다.
-> 해당 값만 입력받도록 설정