DDL로 테이블을 만들고, DML로 데이터를 다뤘다면, 마지막으로 남은 건 "누가 이 데이터를 다룰 수 있는가"다. 이걸 관리하는 게 DCL(Data Control Language)이다.
혼자 로컬에서 MySQL을 쓸 때는 이 개념이 크게 와닿지 않는다. 어차피 혼자 쓰는 DB니까. 그런데 여러 사람이 같은 DB를 쓰는 상황이 되면 얘기가 달라진다. 개발자한테 운영 데이터 삭제 권한까지 줄 필요는 없고, 읽기만 해야 하는 서비스 계정에 테이블 수정 권한을 줘서도 안 된다.
DCL은 그 경계를 만드는 명령어다.
권한을 부여하기 전에 먼저 사용자를 만들어야 한다.
-- 'devuser'라는 이름의 사용자를 로컬호스트에서 접속 가능하게 생성
CREATE USER 'devuser'@'localhost' IDENTIFIED BY 'password123';
'devuser'@'localhost'에서 @ 뒤는 어디서 접속할 수 있는지를 뜻한다. localhost는 같은 컴퓨터에서만 접속 가능, %는 어디서든 접속 가능이다.
사용자에게 특정 권한을 준다.
-- devuser에게 shopdb의 모든 테이블에 대해 SELECT 권한만 부여
GRANT SELECT ON shopdb.* TO 'devuser'@'localhost';
shopdb.*는 shopdb 데이터베이스의 모든 테이블을 뜻한다. 특정 테이블만 지정할 수도 있다.
-- members 테이블에 대해서만 SELECT, INSERT 권한 부여
GRANT SELECT, INSERT ON shopdb.members TO 'devuser'@'localhost';
줄 수 있는 권한의 종류는 이런 것들이 있다.
| 권한 | 설명 |
|---|---|
SELECT | 데이터 조회 |
INSERT | 데이터 삽입 |
UPDATE | 데이터 수정 |
DELETE | 데이터 삭제 |
CREATE | 테이블 생성 |
DROP | 테이블 삭제 |
ALL PRIVILEGES | 모든 권한 |
-- 모든 권한 부여
GRANT ALL PRIVILEGES ON shopdb.* TO 'devuser'@'localhost';

부여했던 권한을 다시 가져온다.
-- devuser의 DELETE 권한 회수
REVOKE DELETE ON shopdb.* FROM 'devuser'@'localhost';
GRANT와 문법 구조가 거의 같다. TO 대신 FROM만 바뀐다.
권한을 변경한 뒤에는 변경 사항을 즉시 반영하기 위해 아래 명령어를 실행해두는 게 좋다.
FLUSH PRIVILEGES;
MySQL은 권한 정보를 메모리에 캐시해두는데, FLUSH PRIVILEGES는 그 캐시를 다시 읽어오는 명령이다. GRANT / REVOKE를 직접 쓸 때는 자동으로 반영되기도 하지만, 명시적으로 실행해두면 확실하다.
특정 사용자에게 어떤 권한이 있는지 확인할 수 있다.
SHOW GRANTS FOR 'devuser'@'localhost';
| 명령어 | 하는 일 |
|---|---|
CREATE USER | 사용자 생성 |
GRANT | 권한 부여 |
REVOKE | 권한 회수 |
FLUSH PRIVILEGES | 권한 변경 사항 즉시 반영 |
DDL, DML, DCL을 묶어서 보면 SQL 명령어의 역할이 명확하게 나뉜다. 구조를 만들고(DDL), 데이터를 다루고(DML), 접근을 통제한다(DCL). 이 세 가지가 데이터베이스를 운영하는 기본 틀이다.