ㅅㅇ

SQL : 10 DDL 본문

SW_STUDY/SQL

SQL : 10 DDL

SO__OS 2022. 6. 2. 18:22
_플레이데이터 빅데이터캠프 공부 내용 _ 6/2

MySQL : 10 DDL

1.  테이블 생성

1.1 구문

create table 테이블 이름(

  -- 컬럼 설정
  컬럼명   데이터타입    [default 값]    [제약조건] 

)

 

1.1.1 컬럼 설정

- 컬럼명   데이터타입    [default 값]    [제약조건] 

- 컬럼명

- 데이터타입 ex) int   varchar(30)
- default : 기본값. 값을 입력하지 않을 때 넣어줄 기본값. 값을 입력하면 입력한 값이 들어간다.

- 제약 조건

1.1.2 제약조건 설정 

not null은 컬럼레벨에서만 가능. 나머지는 컬럼레벨, 테이블레벨 둘다 가능.

 

- primary key (pk): 행식별 컬럼. NOT NULL, 유일값(Unique)
- unique Key (uk) : 유일값을 가지는 컬럼(중복x). null을 가질 수있다.
- not null (nn)  : 값이 없어서는 안되는 컬럼. null입력 불가.

                            값을 입력하지 않는 것도 불가(그러나, default 값 설정하면 default 값으로)
- check key (ck)  : 컬럼에 들어갈 수 있는 값의 조건을 직접 설정. check(컬럼명 조건)  

- foreign key (fk): 다른 테이블의 primary key 컬럼의 값만 가질 수 있는 컬럼. 
                              다른 테이블을 참조할 때 사용하는 컬럼.

 

ex) ck 

check(컬럼명 조건)

-- check : gender 컬럼은 m과 f만 올 수 있다는 제약 조건.
gender char(1) not null check(gender in ('M', 'F')),

-- check : age 컬럼의 값은 10-30사이의 정수만 가능하다는 제약 조건. 비교해서 트루가 되는 값만 반환.
age int check(age between 10 and 30)

 

(1) 제약 조건 설정하는 방법

- 컬럼 레벨 설정
    - 컬럼 설정에 같이 설정 .  not null의 경우 무조건 컬럼 레벨 설정에서 해줘야 한다.

    - 제약 조건 이름 지정 불가.
- 테이블 레벨 설정
    - 컬럼 설정 뒤에 따로 설정. 모든 컬럼 정의 후 constraint 으로 설정함.
    - 기본 문법 : constraint 제약조건이름 제약조건타입(지정할컬럼명) 

 

- 제약 조건 이름

   : 정의한 제약 조건을 어겼을 때 어떤 제약 조건을 어겼는지 제약조건이름으로 알 수 있다.

     <관례적인 표기> - 꼭 이렇게 해야 하는 것은 아니지만, 관례적으로 이렇게 표기한다.

       테이블명_컬럼명_제약조건타입  

       제약조건타입_테이블명_컬럼명  

        -- fk 설정

        자식테이블명_컬러명_부모테이블명_컬럼명_fk

 

   - mysql에서는 PK 제약조건이름 입력해도 primary으로 등록이 된다. 다른 db는 지정이름으로 된다.

     

(2) 테이블 제약 조건 조회

select * from information_schema.table_constraints   [where table_name = '테이블명'];

(3) 제약 조건 설정

-- 제약조건 해제
   SET FOREIGN_KEY_CHECKS = 0;
-- 제약조건 설정
   SET FOREIGN_KEY_CHECKS = 1;

  - 자식 테이블들을 먼저 삭제해야 부모테이블 삭제가 가능하다.

    Foreign key check 옵션을 끄고 해야 한다.

 

 

 

1.2 예시 _ 컬럼레벨, 테이블레벨

1.2.1 제약 조건 : 컬럼 레벨. 

create table parent_tb(
    no int primary key, -- no : number  -- pk 제약조건 컬럼레벨.
    name varchar(50) not null,  -- not null 제약 조건 컬럼레벨.
    -- 날짜/시간 타입의 컬럼에 insert 시점의 일시를 기본값으로 넣을 경우 
    join_date timestamp default current_timestamp, 	
    email varchar(100) unique, -- uk 제약조건 컬럼레벨
    gender char(1) not null check(gender in ('M', 'F')), -- ck. gender 컬럼은 m과 f만 올 수 있다는 제약 조건. 
    age int check(age between 10 and 30) -- ck. age 컬럼의 값은 10-30사이의 정수만 가능하다는 제약 조건.
);

 

제약 조건 DEFAULT

  : 컬럼 데이터 삽입 기본값 설정.  (예시. 5줄)
    -- > type : timestamp, default값 : current_timestamp  

    만약 join_date에 값을 넣지 않는다면, default 값이 들어가게 만들어주는 것이다.

    위 예시에는 current_timestamp 현재 날짜 시간이 들어가도록 설정해줌.


    - default 설정은 dbms 마다 다른데 mysql은 이렇게 작성해주면 됨 
    - 생일 등 이러한 등록은 사용자의 입력에 따르지만, 가입한 날짜의 경우 사용자의 입력으로 이뤄지지 않을 것이다.

      등록 버튼을 누른 그 순간을 자동으로 해야 한다. 그때 이렇게 작성한다.

 

- insert시 설정한 제약 조건을 어긴다면 에러가 날 것이다.  

-- 제약 조건 어겼을 때 error--

insert into parent_tb (no, name, email, gender, age) values (104, '유관순','a@a.com','F', 29);
-- Error Code: 1062. Duplicate entry 'a@a.com' for key 'parent_tb.email'
-- 이메일은 uk 제약조건. 중복된 값이 들어 갈 수 없다.

insert into parent_tb (no, name, email, gender, age) values (105, '강감찬','abd@a.com','남', 29);
-- Error Code: 3819. Check constraint 'parent_tb_chk_1' is violated.	
-- gender check 제약 조건.

 

1.2.2  제약 조건 : 테이블 레벨. 

 - 제약 조건 이름 설정 할 수 있음.  not null 빼고 테이블 레벨로 설정 가능.

create table child_tb(
	no int auto_increment,  -- PK.  auto_increment.
    jumin_num char(14),  -- UK  -- 주민번호는 자리수 14 고정('-' 포함 가능성까지)이니 char로 입력
    age int not null, -- CK
    p_no int not null, -- FK (parent_tb.no 참조)    
    constraint child_tb_no_pk primary key(no), -- mysql은 제약조건이름 입력해도 primary으로 등록이 된다. 다른 db는 지정이름으로 됨.
    constraint child_tb_jumin_num_uk unique(jumin_num),
    constraint child_tb_age_ck check(age > 0 and age <= 100),
    constraint child_tb_p_no_parent_tb_no_fk foreign key(p_no) references parent_tb(no) on delete cascade 
    -- 부모삭제 시 자식 해당 행도 같이 삭제 -- on 설정 안 하면 부모 테이블 삭제 불가. -- p_no가 not null이라 delete null 설정 못함.  
);

 

제약 조건 auto_increment

   : 자동증가 컬럼. insert시 1씩 증가하는 정수를 가진다. PK에서 주로 사용.

    - 해당 컬럼은 insert 구문 실패에도 count되기 때문에 에러도 포함하여 insert 쿼리 실행시킨 만큼 인덱스가 증가한다.

-  on delete cascade

   : 부모삭제 시 자식 해당 행도 같이 삭제.

      p_no가 not null이라 delete set null 설정 못함.  

     이를 아무 설정 안 하면 부모 테이블 삭제 불가하다.

 

- insert시 설정한 제약 조건을 어긴다면 에러가 날 것이다.  

insert into child_tb(jumin_num, age, p_no) values ('333333-2222222', 25, 201);
-- Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`testdb`.`child_tb`, CONSTRAINT `child_tb_p_no_parent_tb_no_fk` FOREIGN KEY (`p_no`) REFERENCES `parent_tb` (`no`) ON DELETE CASCADE)	0.000 sec

   - p_no는 fk 로 부모테이블을 참조하는 컬럼이다. 부모테이블에 없는 값을 넣었다면 오류가 날 것이다.
     부모테이블에서 참조할 행 데이터에 맞춰 적어줘야 한다.

2. 테이블 삭제

DROP TABLE 테이블이름;

 

delete from parent_tb where no = 101;

3. 테이블 수정 ALTER

[ 컬럼 관련 수정 ]

3.1 컬럼 추가

ALTER TABLE 테이블이름 ADD COLUMN 추가할 컬럼설정 [,ADD COLUMN 추가할 컬럼설정]

 

  ex) 컬럼 레벨 제약조건 지정하는 것도 테이블 생성할 때와 똑같이 해주면 된다.

alter table cust add column age int default 0 not null;
alter table cust add column age2 int default 0 not null check(age2 > 10);

alter table emp2 add column email varchar(100) not null, 
                 add column jumin_num char(14) unique;

 

3.2 컬럼 수정

  ALTER TABLE 테이블이름 MODIFY COLUMN 수정할컬럼명 변경설정 [, MODIFY COLUMN 수정할컬럼명  변경설정]

- 데이터타입 관련 수정

     - 숫자/문자열 컬럼은 크기를 늘릴 수 있다.

           - 크기를 줄일 수 있는 경우 : 열에 값이 없거나 모든 값이 줄이려는 크기보다 작은 경우

              만약, 열에 있는 데이터 값보다 크기를 작게 설정하면 에러남.

 

    - 데이터가 모두 NULL이면 데이터타입을 변경할 수 있다. (단 CHAR<->VARCHAR2 는 가능.)

 

- NULL 설정 관련 수정

ALTER TABLE 테이블명 MODIFY COLUMN 컬럼명 타입 NOT NULL  
ALTER TABLE 테이블명 MODIFY COLUMN 컬럼명 NULL

 

     - 컬럼명 타입;                      => nollable   # null 생략 가능하기에 안 적어주면 기본값 null 허용됨.
     - 컬럼명 타입 not null ;        => not null 

 

ex) datatype, null 허용 여부 

alter table cust modify column age tinyint not null; -- not null을 지정하지 않으면 기본값 null 허용으로 변경됨.
alter table cust modify column age2 int null; -- 데이터 타입은 그대로 둔다면 그대로 또 적어줌.


-- 데이터 타입 크기를 줄이는 경우에 담겨있는 데이터들의 크기보다 작은 크기를 설정할 수 없다. 에러.
alter table cust modify column address varchar(2) not null;
alter table cust2 modify column address varchar(2) not null; -- 데이터 값들이 이미 2 이상이다. 에러남.

 

3.3 컬럼 삭제

  ALTER TABLE 테이블이름 DROP COLUMN 컬럼이름 [CASCADE CONSTRAINTS]

CASCADE CONSTRAINTS

    : 삭제하는 컬럼이 Primary Key인 경우 그 컬럼을 참조하는 다른 테이블의 Foreign key 설정을 모두 삭제한다.
- 한번에 하나의 컬럼만 삭제 가능.

 

ex)

alter table cust drop column cust_age;

 

3.4 컬럼 이름 바꾸기

  ALTER TABLE 테이블이름 RENAME COLUMN 원래이름 TO 바꿀이름;

- not null을 제외한 제약 조건이 있다면, 이름 변경이 안 된다.

alter table cust rename column age to cust_age; -- age2를 cust_age로 바꿈.

 

 

[ 제약조건 관련 수정 ]

   제약조건은 수정 불가. 삭제하고 다시 만들어야 함.

3.5 제약조건 추가

   ALTER TABLE 테이블명 ADD CONSTRAINT 제약조건 설정

  ex) pk, fk 제약조건 추가

-- pk 설정 추가
alter table cust add constraint cust_pk primary key(cust_id);
-- alter table cust add primary key(cust_id) -- primary는 이 구문도 가능. 

-- fk 설정 추가
alter table ord add constraint ord_cust_fk foreign key(cust_id) references cust(csut_id)

-- ck 설정 추가
alter table emp2 add constraint emp2_gender_ck check(gender in ('M','F'));

-- uk 설정 추가
alter table emp2 add constraint emp2_email_uk unique(email);

- 사실 primary key는 제약조건 이름 지정해도 primary으로 지정됨.

 

3.6 제약 조건 삭제

  ALTER TABLE 테이블명 DROP CONSTRAINT 제약조건이름

만약, PK를 제거한다면? 

ALTER TABLE 테이블명 DROP PRIMARY KEY 
    ==> CASECADE : 제거하는 Primary Key를 Foreign key 가진 다른 테이블의 Foreign key 설정을 모두 삭제한다.

 ex) 

alter table emp2 drop constraint emp2_email_uk;

 

3.7 NOT NULL <-> NULL 변환

- 위 컬럼 수정에서 보기

ALTER TABLE 테이블명 MODIFY COLUMN 컬럼명 타입 NOT NULL  
ALTER TABLE 테이블명 MODIFY COLUMN 컬럼명 NULL

 

** 테이블 복제

- NOT NULL 조건을 제외한 제약 조건은 복사 되지 않는다.

create table 이름
as
select 문 -- > subquery
-- 복사한 테이블 생성(not null을 제외한 제약 조건은 copy가 안됨)
create table cust2
as
select * from customers;

- 테이블의 구조만 복사

    where 조건 성립 안 하니 데이터는 복사하지 않는다.

    데이터 값은 복사되지 않고 테이블의 구조만(컬럼 설정 ....) 복사됨.  (NOT NULL 조건 빼고 다른 제약조건은 복사안됨.)

create table cust
as
select * from customers where 1 = 0;

 

** 테이블관련 설정 조회 (DDL관련)

1) 해당 DB 내 테이블 조회

show tables; -- 해당 DB 내 테이블 조회

2) 생성한 테이블에 대한 정보

desc 테이블명;

3) 테이블 제약 조건 조회

select * from information_schema.table_constraints;
select * from information_schema.table_constraints where table_name = '테이블명';

 

'SW_STUDY > SQL' 카테고리의 다른 글

SQL : 08 집합 연산자  (0) 2022.05.31
SQL : 07 서브쿼리  (0) 2022.05.31
SQL : 06 조인  (0) 2022.05.29
SQL : 05 함수 (2) 집계함수  (0) 2022.05.26
SQL : 05 함수 (1)  (0) 2022.05.26