Database/MySQL

MySQL) DML, DDL, DCL, TCL 개념 및 활용 / table copy, auto_increment 사용법

pogun 2025. 2. 9. 15:45

Table(테이블)이란?

: 데이터를 저정하는 구조화된 공간

Column(컬럼) : 데이터의 속성을 정의(예: 이름, 나이, 주소 등)

Row(행) : 하나의 데이터 레코드(예: 특정 회원의 정보)

ex)

회원관리 테이블 - 컬럼 : id, password, name ...

게시판 테이블 - 컬럼 : seq, id, title, content ...

 

Column 데이터 타입

- 문자형(String)            : VARCHAR(길이) → 영어(1Byte), 한글(3Byte)

- 정수형(integer)           : INT, DECIMAL(자릿수)

- 실수형(float, doule)    : FLOAT, DOUBLE, DECIMAL(전체 자릿수, 소수점 자릿수)

- 날짜형(date)               : DATE, TIMESTAMP

SQL 문장 명령어의 종류

DML DDL DCL TCL
select 데이터 조회 create 테이블, 뷰, 인덱스 등을 생성 grant 사용자에게 특정 권한을 부여 commit 변경 사항을 영구 반영
insert 데이터 삽입 drop 테이블, 뷰, 인덱스 등을 삭제 revoke 사용자에게 특정 권한을 회수 rollback 변경 사항을 취소
update 데이터 수정 alter 테이블 구조를 변경     savepoint 트랜잭션 내에서 특정 지점(저장점)을 생성
delete 데이터 삭제 truncate 테이블의 모든 데이터를 삭제 (초기화)        
    rename 테이블, 컬럼, DB 이름 변경        

** 쉽게 생각하면 데이터를 조작하는 건 DML **

** 오브젝트(테이블, 뷰 등등) 조작하는 건 DDL **


쿼리로 이해하기 : DML / DDL / DCL / TCL

select @@SQL_SAFE_UPDATES; -- 확인
set SQL_SAFE_UPDATES = 0;  -- 설정, 기본값이 1로 되어있음(1이면 update랑 delete 막아둔거)

select @@autocommit;       -- MySQL 자체에서 쿼리 작성하자마자 자동 커밋하도록 되어있음
set autocommit = 0;        -- TCL을 써볼꺼면 꺼야함

**들어가기 앞서 MySQL에서 코드 확인 **

create table tb_test(
    num int,
    name varchar(30),
    address varchar(50),     -- 1byte 3byte ->(버전업) char로 변경 즉,
    birth timestamp          --  varchar(50)이면 글자 갯수 50개 넣기 가능
    -- size double        -- size단어 oracle 에서는 사용 불가
);

: 한글은 3byte라고 했었지만, 버전업이 이루어지고 나서 varchar(30)이면,

: 글자 갯수 30까지 넣기 가능하다고 보면 된다.

: 원래는 한 글자에 3byte라서 varchar(30)이면 10글자까지 넣을 수 있는 것이라고 함

INSERT (데이터 삽입)

insert into tb_test(num, nume, address, birth)
values(1, '홍길동', '부산시', '2001-03-17');
insert into tb_test(num, nume, address, birth)
values(2, '성춘향', '남원시', '2010-10-12');
insert into tb_test
values(3, '일지매', '춘천시', '2004-04-19');
insert into tb_test(nume, address, num, birth)
values('삼삼이', '대구시', 4, '2020-02-28');   -- 순서가 바뀌어도 삽입은 된다 
insert into tb_test(num, nume, birth)
values(5, '뚝딱이', '2010-10-12');             -- 이렇게하면 address에 null값 들어감

: 뚝딱이가 null값으로 들어갈 수 있는 이유는 테이블 생성 시 not null 조건을 주지않아서 가능함

: 삼삼이처럼 순서가 바뀌어도 삽입은 되지만 굳이 헷갈리게 저렇게 삽입할 필요는 없음

: 일지매처럼 컬럼을 안넣어줘도 삽입 됨

DELETE (데이터 삭제)

delete from tb_test
where num = 2;

: 이러면 성춘향 데이터 삭제

COMMIT & ROLLBACK (저장  & 되돌림)

delete from tb_test
where num = 2;             

commit;

insert into tb_test(num, nume, birth)
values(6, '두친구', '2002-09-12'); 

rollback;

: 이렇게하면 성춘향 데이터가 삭제된 후 commit 진행

: 그리고 두친구 데이터 삽입 후 rollback 진행

결과 : 가장 마지막으로 커밋한 지점으로 돌아감

: 즉, 두친구 데이터 삽입하기 전으로 돌아감

UPDATE (데이터 수정)

insert into tb_test(num, nume, birth)
values(6, '두친구', '2002-09-12');

update tb_test
set address = '대구시'
where num = 6;

: 두친구 데이터를 다시 넣고 현재 address를 삽입하지 않았기 때문에 null값임

: num가 6인 데이터를 조건으로 걸고 address에 '대구시' 삽입

: (6, '두친구', '대구시', '2002-09-12') -> 이렇게 데이터가 수정됨

TABLE COPY (데이터 포함)

create table tb_job
as select * from jobs;

: jobs 테이블에 모든 데이터를 가지고 있는 tb_job테이블 생성

insert into tb_job(job_id, job_title, min_salary, max_salary)
values('ADD', 'ADDRESS_AC', 3000, 13000);

: 카피한 테이블에 데이터 삽입 가능

create table tb_job
as select job_id as jid, 
          job_title as jtitle, 
          min_salary as miasl, 
          max_salary as mxsal
from jobs;

: 이렇게 원하는 컬럼명으로 바꾸어 카피할 수 있다.

테이블 카피가 유용한 이유

create table emp_dept
as select employee_id as id, 
          first_name as name, 
          salary as sal,
		  e.department_id as dnum, 
          department_name as dname
from employees e join departments d
on e.department_id = d.department_id;

select * from emp_dept;

: 테이블을 조인시켜 하나의 테이블로 만들 수 있다.

: 자주 조인시켜서 확인하는 데이터가 있을 시 매번 조인 쿼리문을 작성할 필요가 없음

: 테이블 복사나 뷰를 사용하는건 본인 판인

DROP (테이블 삭제)

drop table tb_job;
drop table emp_dept;

TABLE COPY (데이터 미포함)

create table if not exists tb_job
like jobs;

create table tb_job
as select *
from jobs
where 1=2;

: 두 코드 모두 데이터 미포함 테이블 카피하는 방법

: 실무에선 아래 코드로 보통 씀

: 왜냐하면 그냥 봐도 select절이나 from절을 활용할 용도가 넓음(확장성이 큼)

insert into tb_job(job_id, job_title, min_salary, max_salary)
values('IT_PROG', '프로그래머', 10000, 20000);

: 마찬가지로 데이터 삽입 가능

GRANT & REVOKE (권한 회수 & 부여)

예제 : user1에게 employees 테이블의 조회(SELECT) 권한을 부여

GRANT SELECT ON employees TO 'user1'@'localhost';

: 'user1'@'localhost' → user1이 로컬(현재 서버)에서 접속할 때만 적용

: employees 테이블에 대해 SELECT(조회) 권한만 부여

 

예제 : user2에게 employees 테이블에서 SELECT, INSERT, UPDATE 권한을 부여

GRANT SELECT, INSERT, UPDATE ON employees TO 'user2'@'localhost';

: user2는 employees 테이블에서 데이터를 조회, 삽입, 수정 가능

: 하지만 DELETE 권한은 없으므로 데이터를 삭제할 수 없음

 

예제 : admin_user에게 전체 데이터베이스(mydb)의 모든 권한을 부여

GRANT ALL PRIVILEGES ON mydb.* TO 'admin_user'@'%';

: 'admin_user'@'%' → 모든 IP에서 접속 가능

: mydb.* → mydb 데이터베이스 내 모든 테이블에 적용

: ALL PRIVILEGES → 모든 권한 부여 (관리자급 사용자)

 

예제 : user1의 employees 테이블 SELECT 권한을 회수

REVOKE SELECT ON employees FROM 'user1'@'localhost';

: GRANT와 반대로 특정 권한을 제거

 

예제 : user2의 모든 권한을 제거

REVOKE ALL PRIVILEGES ON mydb.* FROM 'user2'@'localhost';

: user2는 이제 mydb 데이터베이스의 어떤 테이블도 사용할 수 없음

ALTER : rename / add / modify / drop

테이블명 수정

alter table tb_job
rename to my_job;

 

컬럼을 추가

alter table my_job
add new_col int;

 

컬럼을 다중 추가

alter table my_job
add (job_memo varchar(50), job_content date);

 

컬럼을 수정

alter table my_job
modify job_memo decimal(3, 1);

 

컬럼을 삭제

alter table my_job
drop column job_content;

auto_increment : sequence - 자동으로 값을 증가 + 1

: auto_increment를 하면 PK선언을 무조건 해줘야함

create table tb_test(
    seq int auto_increment primary key, 
    name varchar(30),
    height double
);

-- auto_increment 초기화
alter table tb_test
auto_increment = 100; -- 테이블 만들자마자 초기화 시켜주는 게 정석

: 이렇게하면 seq 컬럼이 데이터를 삽입할 때 100부터 1씩 증가하면서 추가 됨

insert into tb_test(name, height)
values('홍길동', 172.1);
insert into tb_test(name, height)
values('성춘향', 158.1);
insert into tb_test(name, height)
values('일지매', 183.5);

select * from tb_test;

: 의외로 자주 사용하는 방법

create table tb_test(
    seq int auto_increment primary key,  
    name varchar(30),
    height double
) auto_increment = 100;

: 이렇게하면 테이블 생성과 동시에 100으로 초기화 시켜줌

** 알아둘것!! **