보충DB

JIN·2023년 4월 12일
0

삽히

목록 보기
5/6
post-thumbnail

제약조건

종류

  • NOT NULL : 컬럼에 NULL 값을 허용 X
  • UNIQUE : 컬럼에 중복값 허용X NULL 값은 허용 O
  • PRIMARY KEY : NOT NULL + UNIQUE, 각 행을 고유하게 식별하는 열
  • CHECK : 열에 저장할 수 있는 값을 제한하는 조건 정의
    : MYSQL 8.0.16부터 사용가능, 이전 버전의 경우 설정은 되나 적용안됨
  • DEFAULT : NULL값이 들어올 경우 자동으로 설정할 값
  • FOREIGN KEY(외래키) : 두 테이블 간의 관계를 유지하기 위해 사용, 외래키는 다른 테이블의 기본키로 저장된 값을 저장

데이터베이스 생성 및 사용

create database supplement;
use supplement;

NOT NULL 제약조건(Constraint)

create table test_nn(
	a int,
    b int not null
);

insert into test_nn(a,b) values(1,2);
insert into test_nn(b) values(3);
-- 에러발생
insert into test_nn(a) values(4);

null이면 안되는데 b에 아무것도 입력안해서 에러발생


PRIMARY KEY(기본키) 제약조건

create table test_pk(
	a int primary key,
    b int
);
insert into test_pk(a,b) values(1,2);
-- 널 입력 에러
insert into test_pk(b) values(1);
-- 중복값 입력 에러
insert into test_pk(a) values(1);

기본키널이나 중복값 입력하면 안됨


CHECK 제약조건

create table test_ck(
	a int primary key,
    b int check(b>0)
);
insert into test_ck(a,b) values(1,2);
-- 체크 에러
insert into test_ck(a,b) values(1,-2);
create table test_ck2(
	a int primary key,
    b varchar(3) check( b in ('01', '02', '23'))
);
-- 성공
insert into test_ck2 values(3,'02');
-- 에러
insert into test_ck2 values(5,'00');

DEFAULT 제약조건

create table test_default(
	a int primary key,
    b int default 0
);
insert into test_default(a) values(3);
insert into test_default(a,b) values(5,3);
select * from test_default;

FOREIGN KEY 제약조건

create table test_parent(
	a int primary key
);
create table test_child(
	b int primary key,
    a int,
    foreign key(a) references test_parent(a)
);
insert into test_parent(a) values(1);
insert into test_child(b, a) values(1,1);

-- 이때 오류남
-- 이유는? 자식테이블에 값을 입력할때 부모테이블에 2 값이 없기때문에 에러 발생
-- 자식테이블에 값을 입력 시 부모테이블에 값이 없어 발생하는 에러
insert into test_child(b,a) values(2,2);

-- 이때 오류남
-- 이유는? a를 test_child에서 참조하고 있기때문에 
-- 자식테이블에서 부모테이블의 값을 참조하고 있을때 부모의 값을 "수정 또는 삭제할"때 발생하는 에러
update test_parent set a = 10 where a = 1;
delete from test_parent where a = 1;

-- delete from test_parent where a = 1;이게 오류가 났었음
-- <삭제하고 싶으면 어떻게함?>
-- 이 때 부모를 참조하고 있는 것을 지우면 부모를 삭제할 수 있음
-- 즉 자식을 삭제시킴.. 나(=부모)를 참조하는 것이 없으면 부모 삭제 가능.. 
-- 1. 부모를 참조하는 자식의 데이터를 삭제
-- 2. 부모의 데이터 삭제
-- 참조하는거 제거
delete from test_child where a=1;
-- 그래야 부모를 삭제할 수 있음
delete from test_parent where a = 1;

-- update test_parent set a = 10 where a = 1;이게 오류가 났었음
-- <그럼 수정하고싶으면 어떻게함?>
-- 1. 자식의 참조하는 값을 모두 NULL로 변경
-- 2. 부모의 컬럼 값 수정
-- 3. 자식의 컬럼 값 수정
update test_child set a=null where a = 1;
update test_parent set a = 10 where a = 1;
update test_child set a = 10 where a is null;


-- <<<테이블 설정으로 해결>>>


drop table test_child;
drop table test_parent;
-- 근데 이렇게 자식들을 하나하나씩 다 바꾸기엔 힘듦
-- 예를들어 게시판 만들때 댓글, 파일, 조회수 등 하나의 게시글 삭제를 위해 여러번 삭제해야하는 경우 발생
-- 그래서 부모를 삭제할 때 나를 참조하는 애들도 같이 삭제하는 옵션을 제공함
create table test_parent(
	a int primary key
);

create table test_child(
	no int primary key,
	a int,
	foreign key(a) references test_parent(a) 
	on delete cascade -- 삭제할 때 같이 삭제해줘on update, 필수!!!!!
	on update cascade -- 부모가 수정되면 나도 같이 수정해줘, 얘는 많이 발생 안함.. 왜냐하면 외래키로 참조하는 경우 대부분 pk임
	-- 사실 pk키는 수정을 잘 안해서 on update cascade보다 on delete를 더 씀!
);

insert into test_parent(a) values(1);
select * from test_parent;
insert into test_child(no, a) values (1,1);
select * from test_child;

-- 이제 이렇게만 해도 test_parent a가 100으로 바뀜
-- test_child도 a가 100으로 바껴있음
update test_parent set a=100 where a=1;

-- 부모테이블,자식테이블에서 a=100인거 다 삭제됨
delete from test_parent where a=100;

select * from test_parent;
select * from test_child;

제약조건 확인하기

테이블에 적용되어있는 Key 특성을 조회

SHOW CREATE TABLE test_child;
SELECT *
 FROM information_schema.table_constraints
 where table_name = 'test_child';
 
 -- primary key는 제약조건의 이름이 무조건 'PRIMARY'으로 등록됨! 기억해둬!!
-- 제약조건을 삭제할 때 constraint_name 이 이름으로 삭제하는데 primary는 우리가 설정한 이름으로 
-- 안하기때문에 이 것을 기억해둘것

0개의 댓글