클린코드 서적스터디를 완료한 후, 더 실용적이고 현재 교육과정에 적합한 책을 찾고 있었다.
그 결과, DB 관련 서적(업무에 바로 쓰는 SQL 튜닝)을 두 번째 서적 스터디로 선택하게 되었다.
이번 스터디를 통해 mySQL에 대한 깊이 있는 이해와 실무 적용 능력을 향상시키는 것이 목표이다.
자 그럼 각설하고 1장으로 넘어가보자.
일부 기능과 옵티마이저의 성능 차이, 시스템 변수, 상태 등에서 점점 차이가 나고 있긴 하지만 SQL문의 주요 뼈대는 크게 다르지 않다.
해당 챕터에서는 MySQL로 실습을 진행한다.
show variables like 'version';
-- 또는
SELECT @@version;
2024년 기준 Oracle과 MySQL이 1, 2위를 다투고 있다.
상용 DB인 오라클과 MySQL과 MariaDB의 구조와 기능, SQL문을 비교한다.
GPL 라이선스 누구나 소프트웨어를 자유롭게 사용하고, 수정하고, 배포할 수 있도록 하는 오픈소스 소프트웨어 버전
핵심 조항
- 자유로운 사용: 누구나 소프트웨어를 어떤 목적으로든 자유롭게 사용할 수 있습니다.
- 소스 코드 공개: 소프트웨어를 배포할 때 소스 코드도 함께 제공해야 합니다.
- 변경 및 배포: 소프트웨어를 수정하고 변경된 버전을 배포할 수 있지만, 변경된 소프트웨어도 원래의 GPL 라이선스 하에 배포되어야 합니다.
- 동일 라이선스 적용: GPL로 배포된 소프트웨어를 기반으로 한 파생물도 GPL로 배포되어야 합니다. 이는 "카피레프트" 원칙이라고 불립니다.
다만 GPL 라이선스라고 하더라도 이미 고객 장비에 MySQL 이 설치된 상태에서는 소스코드 공개는 의무사항이 아님
이를 이중화하기 위해 클러스터나 복제 구성을 사용
마스터-슬레이브 구조:
- 마스터 노드: 데이터의 읽기와 쓰기 작업을 모두 처리
- 슬레이브 노드: 읽기 작업만 처리
즉, 여러 서버가 있더라도 각 서버의 역할이 다를 수 있음. 예를 들어, 마스터 서버는 데이터 추가나 수정 작업을 처리하고, 슬레이브 서버는 데이터 조회 작업만 처리함.
이러한 구조는 SQL 튜닝(쿼리 최적화)에도 영향을 미칠 수 있음.
쿼리가 실행되는 서버의 위치를 알고 튜닝을 하면, 물리적인 위치 특성을 고려한 최적화를 할 수 있다는 의미
애플리케이션 단에서 쿼리 오프로딩을 적용되므로 마스터노드에서는 보통 쓰기 트랜잭션을 진행하고 슬레이브노드에서는 읽기 트랜잭션을 시행한다.만약 쓰기 트랜잭션을 슬레이브 노드에 접속해서 수행한다면? 정상적인 쿼리 튜닝 결과가 도출되지 않을 것 이다.
DB 서버의 구조를 충분히 이해하고 적합한 서버에 접근하여 쿼리 튜닝을 수행하는 일은 매우 중요하다.
쿼리 오프로딩: DB 서버의 트랜잭션에서 쓰기 트랜잭션과 읽기 트랜잭션을 분리하여 DB 처리량을 증가시키는 성능 향상 기법입니다.
- 쓰기 트랜잭션: UPDATE, INSERT, DELETE
- 읽기 트랜잭션: SELECT
예시
- 새로운 사용자 추가:
- 애플리케이션에서 새로운 사용자를 추가하는 요청이 들어옴.
- SQL 쿼리 예시:
INSERT INTO users (name, email) VALUES ('John Doe', 'john@example.com');
- 슬레이브 노드에서 실행 시:
- 슬레이브 노드는 읽기 전용 작업을 처리하도록 설계됨.
- 쿼리가 실패하거나 데이터베이스에 예기치 않은 문제가 발생할 수 있음.
- 슬레이브 노드는 데이터 쓰기 작업을 처리하지 않음.
- 사용자 정보 조회:
- 애플리케이션에서 특정 사용자의 정보를 조회하는 요청이 들어옴.
- SQL 쿼리 예시:
SELECT * FROM users WHERE email = 'john@example.com';
- 마스터 노드에서 실행 시:
- 읽기 작업이 마스터 노드에 부하를 줄 수 있음.
- 마스터 노드는 주로 쓰기 작업을 처리하도록 설계됨.
- 읽기 작업이 많아지면 마스터 노드의 성능이 저하될 수 있음.
MySQL 과 오라클 DB에서 Join 알고리즘 기능에는 차이가 있음.
MySQL/MariaDB
-- 문법
IFNULL(열명, '대체값')
-- 예제
SELECT IFNULL(Col1, 'N/A') AS coll FROM tab;
Oracle
-- 문법
NVL(열명, '대체값')
-- 예제
SELECT NVL(Col1, 'N/A') AS coll FROM tab;
MySQL/MariaDB
-- 문법
LIMIT 숫자
-- 예제
SELECT col1 FROM tab LIMIT 5;
Oracle
-- 문법
ROWNUM < 숫자
-- 예제
SELECT col1 FROM tab WHERE ROWNUM <= 5;
MySQL/MariaDB
-- 문법
NOW()
-- 예제
SELECT NOW() AS date;
Oracle
-- 문법
SYSDATE
-- 예제
SELECT SYSDATE AS date FROM dual;
MySQL/MariaDB
-- 문법
IF(조건식, '참값', '거짓값')
-- 예제
SELECT IF(col1='A', 'apple', '-') AS coll FROM tab;
Oracle
-- 문법
DECODE(열명, '값', '참값', '거짓값')
-- 예제
SELECT DECODE(col1, 'A', 'apple', '-') AS coll FROM tab;
MySQL/MariaDB
-- 문법
DATE_FORMAT(날짜열, '형식')
-- 예제
SELECT DATE_FORMAT(NOW(),'%Y%m%d %H%i%s') AS date;
Oracle
-- 문법
TO_CHAR(날짜열, '형식')
-- 예제
SELECT TO_CHAR(SYSDATE, 'YYYYMMDD HH24MISS') AS date FROM dual;
MySQL/MariaDB
sql코드 복사
-- 문법 (AUTO INCREMENT)
-- 예제
CREATE TABLE tab (
seq INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(20) NOT NULL
);
-- 문법 (MariaDB 10.3 이상, 시퀀스)
CREATE SEQUENCE [시퀀스명] INCREMENT BY [증감숫자] START WITH [시작숫자] NOMINVALUE OR MINVALUE [최솟값] NOMAXVALUE OR MAXVALUE [최댓값] CYCLE OR NOCYCLE CACHE OR NOCACHE;
-- 예제
CREATE SEQUENCE MARIA_SEQ_SAMPLE INCREMENT BY 1 START WITH 1 MINVALUE 1 MAXVALUE 99999999999 CYCLE CACHE;
SELECT NEXTVAL(MARIA_SEQ_SAMPLE);
Oracle
sql코드 복사
-- 문법
CREATE SEQUENCE [시퀀스명] INCREMENT BY [증감숫자] START WITH [시작숫자] NOMINVALUE OR MINVALUE [최솟값] NOMAXVALUE OR MAXVALUE [최댓값] CYCLE OR NOCYCLE CACHE OR NOCACHE;
-- 예제
CREATE SEQUENCE ORACLE_SEQ_SAMPLE INCREMENT BY 1 START WITH 1 MINVALUE 1 MAXVALUE 99999999999 CYCLE CACHE;
SELECT ORACLE_SEQ_SAMPLE.NEXTVAL FROM dual;
참고.
- MySQL/MariaDB: AUTO_INCREMENT 속성을 테이블 열에 직접 적용하거나, MariaDB 10.3 이상에서는 시퀀스 오브젝트를 사용할 수 있음.
- AUTO_INCREMENT는 테이블당 하나의 열에만 적용 가능하며, 시퀀스 오브젝트는 MariaDB 10.3 이상에서만 사용 가능.
- Oracle: 시퀀스 오브젝트를 사용하여 자동 증가 값을 설정함.
- 시퀀스 오브젝트를 여러 테이블과 컬럼에서 공유 가능하며, 다양한 옵션을 통해 더 유연하게 사용 가능.
MySQL/MariaDB
-- 문법
CONCAT(열값 또는 문자열, 열값 또는 문자열)
-- 예제
SELECT CONCAT('A', 'B') AS TEXT;
Oracle
-- 문법
열값 또는 문자열 || 열값 또는 문자열
CONCAT(열값 또는 문자열, 열값 또는 문자열)
-- 예제
SELECT 'A' || 'B' AS TEXT FROM dual;
SELECT CONCAT('A', 'B') AS TEXT FROM dual;
MySQL/MariaDB
-- 문법
SUBSTRING(열값 또는 문자열, 시작 위치, 추출하려는 문자 개수)
-- 예제
SELECT SUBSTRING('ABCDE', 2, 3) AS sub_string;
Oracle
-- 문법
SUBSTR(열값 또는 문자열, 시작 위치, 추출하려는 문자 개수)
-- 예제
SELECT SUBSTR('ABCDE', 2, 3) AS sub_string FROM dual;
최근 많은 서비스들이 MySQL 으로 여러 노드 구조를 채택하여 진행하고 있지만 내부를 들여다 보면 MySQL의 Shared Nothing Storage 구조를 신경쓰지 않은 쿼리들을 볼 수 있음.
→ 일반적인 쿼리 작성 및 튜닝이 통하지 않을 수 있음
그러므로 이러한 문제를 잘 이해하고 MySQL DBMS에 적용해보는 훈련이 필요하다!
또한 MySQL 과 MariaDB 로 서비스를 진행 시 이러한 SWOT 분석을 인지하고.
약점과 기회를 SQL 튜닝을 통해 헤쳐나갈 수 있을 것.
[스터디에 물어봤던 이슈 정리]
저는 오라클 db 와 MySQL 의 구조적 차이를 설명하면서 마스터 슬레이브 패턴의 예시를 들었는데 해당 부분이 잘 이해가 안갑니다!
스프링 애플리케이션이라면
spring:
datasource:
master:
url: jdbc:mysql://master-db-url:3306/mydb
username: username
password: password
slave:
url: jdbc:mysql://slave-db-url:3306/mydb
username: username
password: password
이런식으로 따로 2개의 DB를 만들어 진행해서 읽기 작업과 쓰기 작업의 차이를 둔다는 것 맞나요?
슬레이브 DB는 마스터 DB 의 데이터를 복제해서 최신상태를 계속 유지한다는 거라고 이해했습니다.
해당 부분에 GaHee99님이 이해하기 쉽게 설명을 해주셨다.
관련 아티클
Mysql Replication 구성하기