danbibibi
article thumbnail
Published 2023. 2. 13. 01:24
MySQL 정리 CS/데이터베이스

1. MySQL

 

  • 세계에서 가장 많이 쓰이는 오픈 소스의 관계형 데이터베이스 관리 시스템
  • 다양한 운영체제에서 사용할 수 있으며, 여러 가지의 프로그래밍 언어를 지원
  • 크기가 큰 데이터 집합도 빠르고 효과적으로 처리할 수 있음
  • 널리 알려진 표준 SQL 형식을 사용
  • MySQL 응용 프로그램을 사용자의 용도에 맞게 수정할 수 있음
  • 키워드와 구문에서 대소문자를 구분하지 않음
  • DB 서버마다 독립적인 스토리지를 할당하는 방식을 사용

 

2. MySQL 장점

  • 용량 & 처리 : 적은 용량 차지(1MB RAM), 매우 적은 오버 헤드, 빠른 처리 속도로 대용량 데이터 처리에 용이
  • 접근성 : 다른 데이터 관리 툴에 비해 구조가 간단하여 사용이 쉬움
  • 지원 : 다양한 프로그래밍 언어와 통합 가능, 거의 모든 운영체제에서 사용을 지원
  • 유연성 : 유연하고 확장이 가능한 구조
  • 가격 (오픈소스 - 무료 / 상업용 - 유료)

 

3. MySQL 단점

  • 복잡한 쿼리 시 성능 저하
  • 트랜잭션 지원이 완벽하지 않음
  • 사용자정의 함수(UDF)의 사용이 쉽지 않고 유연하지 않음

 

4. MySQL 사용이 적합한 경우

  • 분산 작업이 필요한 경우

        : MySQL의 복제 기능 지원은 Primary-Secondary

          또는 Primary-Primary 구조와 같은 분산 데이터베이스 설정에 적합함

 

  • 웹 사이트 및 웹 애플리케이션

        - MySQL은 인터넷을 통해 많은 웹 사이트와 애플리케이션을 지원함

        - 설치가 쉽고, 속도가 빠르면며, 확장성이 좋음

 

  • 향후 성장이 예상되는 제품

        : MySQL의 복제 기능 지원은 수평적 확장에 도움이 될 수 있음

 

💡 MySQL의 복제 기능

 

5. MySQL 사용이 부적합한 경우

  • SQL 준수가 필요한 경우 

        : MySQL은 표준 SQL을 완전히 준수하지 않음

 

  • 동시성과 대용량 데이터 볼륨이 요구되는 경우

        - MySQL은 일반적으로 읽기가 많은 작업에서 잘 수행되지만,

          동시에 읽기와 쓰기 작업이 일어나는 경우는 문제가 될 수 있음

 

        - 응용프로그램에 한 번에 많은 사용자가 데이터를 쓰는 경우,

          PostgreSQL과 같은 다른 RDBMS가 더 나은 선택이 될 수 있음

 

 

6. 주석

<sql />
# 한줄 주석 -- 한줄 주석 /* 여러줄 주석*/

 

7. 데이터 타입

7.0.1. 1. 숫자 타입

  • 정수 타입 (TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT)
  • 고정 소수점 타입 (DECIMAL)
  • 부동 소수점 타입 (FLOAT, DOUBLE)
  • 비트값 타입 (BIT)

7.0.2. 2. 문자열 타입

  • CHAR (고정 문자열)
  • VARCHAR (가변 길이 문자열)
  • BINARY, VARBINARY
  • BLOB, TEXT
  • ENUM (미리 정의한 집합 안의 요소 중 하나만을 저장 가능)
  • SET (미리 정의한 집합 안의 요소 중 여러 개를 동시에 저장할 수 있는 타입)

7.0.3. 3. 날짜와 시간 타입

  • DATE(날짜, 'YYYY-MM-DD')
  • DATETIME (날짜 + 시간, 'YYYY-MM-DD HH:MM:SS')
  • TIMESTAMP ('1997-01-01 00:00:01' UTC부터 시작하는 초수')
  • TIME (시간, 'HH:MM:SS')
  • YEAR (YEAR(4) : 4자리)

 

8. 연산자

8.0.1. 1. 산술 연산자

 +  -   *   /   DIV  % (or)
 MOD

8.0.2. 2. 대입 연산자

  •  = (SET 문이나 UPDATE 문의 SET 절에서만 대입연산자로 사용)
  • := (비교 연산자로 해석되지 않는 대입 연산자)

8.0.3. 3. 비교 연산자 

 =   != < , > ,  <=, >=
  • IS (왼쪽 피연산자와 오른쪽 피연산자가 같으면 참을 반환)
  • IS NOT
  • IS NULL (피연산자의 값이 NULL이면 참을 반환)
  • IS NOT NULL
  • BETWEEN a AND B (a~b 사이면 참을 반환, a와 b 포함)
  • NOT BETWEEN a AND B
  • IN() (피연산자의 값이 인수로 전달받은 리스트에 존재하면 참을 반환)
  • NOT IN()

8.0.4. 4. 논리 연산자

  AND
 (&&)
 OR
 ( || )
 XOR  NOT
 (!)

8.0.5. 5. 비트 연산자

 AND 연산  OR 연산  XOR 연산 NOT 연산  left shift 연산  right shift 연산
 &  |  ^  ~  <<  >>

* MySQL에서는 '0'과 '1'로만 이루어진 문자열 앞에 'b'를 붙여 2진수를 표현

 

9. 제약 조건

: 데이터의 무결성을 지키기 위해, 데이터를 입력받을 때 실행되는 검사 규칙

  • NOT NULL : NULL 값 저장 불가
  • UNIQUE : 고유한 값을 가져야 함
  • PRIMARY KEY :  NOT NULL + UNIQUE
  • FOREIGN KEY : 하나의 테이블을 다른 테이블에 의존하게 만듦
  • DEFAULT : 필드의 기본값을 설정해야 함

 

* CREATE 문으로 테이블을 생성할 때나 ALTER 문으로 필드를 추가할 때 설정할 수 있음

* 아래와 같은 방식으로 사용

<sql />
# create CREATE TABLE Test( ID INT NOT NULL, Name VARCHAR(30), ReserveDate DATE, RoomNum INT ); # alter ALTER TABLE Reservation MODIFY COLUMN Name VARCHAR(30) NOT NULL;

 

10. SQL 분류

 

11. CREATE

  • 새로운 데이터베이스 생성
  • CREATE TABLE 테이블이름( 필드이름1 필드타입1, 필드이름2 필드타입2, ... )
<sql />
CREATE TABLE Test ( ID INT, Name VARCHAR(30), ReserveDate DATE, RoomNum INT );

 

12. ALTER

  • 데이터베이스와 테이블  내용을 수정
  • ALTER DATABASE 
  • ALTER TABLE
  • ADD, DROP, MODIFY COLUMN
<sql />
-- 새로운 필드 추가 ALTER TABLE Reservation ADD Phone INT; # (ADD COLUMN 컬럼명 타입) - COLUMN 키워드 생략 가능 -- 필드 삭제 ALTER TABLE Reservation DROP RoomNum; -- 필드 타입 변경 ALTER TABLE Reservation MODIFY COLUMN ReserveDate VARCHAR(20);

 

13. DROP

  • 데이터베이스와 테이블 삭제
  • DROP DATABASE 데이터베이스이름
  • DROP TABLE 테이블이름
  • TRUNCATE TABLE (테이블 자체가 아닌 테이블의 데이터만을 지우고 싶은 경우)
<sql />
DROP DATABASE Hotel; DROP TABLE Reservation; TRUNCATE TABLE Reservation; -- 데이터베이스나 테이블이 존재하지 않아서 발생하는 에러 방지 DROP DATABASE IF EXISTS Hotel; DROP TABLE IF EXISTS Reservation;

 

14. INSERT

  • 테이블에 새로운 레코드 추가
  • INSERT INTO 테이블이름(필드이름1, 필드이름2, ...) VALUES (데이터값1, 데이터값2, ...)
  • INSERT INTO 테이블이름 VALUES (데이터값1, 데이터값2, 데이터값3, ...)
* 2번째 경우에는 데이터베이스의 스키마와 같은 순서대로 필드의 값이 자동 대입
* 아래 필드 값은 생략 가능 

1. NULL을 저장할 수 있도록 설정된 필드 
2. DEFAULT 제약 조건이 설정된 필드
3. AUTO_INCREMENT 키워드가 설정된 필드
<sql />
INSERT INTO Reservation(ID, Name, ReserveDate, RoomNum) VALUES(5, '이순신', '2016-02-16', 1108); -- 추가하는 레코드가 반드시 모든 필드의 값을 가져야 할 필요는 없음 -- 비어 있는 필드는 NULL 값을 가짐 INSERT INTO Reservation(ID, Name) VALUES (6, '김유신');

 

15. UPDATE

  • 테이블의 레코드 내용 수정
  • 해당 테이블에서 WHERE 절의 조건을 만족하는 레코드의 값만 수정
  • UPDATE 테이블이름 SET 필드이름1=데이터값1, 필드이름2=데이터값2, ... WHERE 필드이름=데이터값
<sql />
UPDATE Reservation SET RoomNum = 2002 WHERE Name = '홍길동'; -- WHERE 절 생략 -- 모든 레코드의 RoomNum 필드의 값이 2002로 변경됨 UPDATE Reservation SET RoomNum = 2002;

 

16. DELETE

  • 테이블의 레코드 삭제
  • DELETE FROM 테이블이름 WHERE 필드이름=데이터값
<sql />
DELETE FROM Reservation WHERE Name = '홍길동'; -- WHERE절 생략 -- 테이블에 저장된 모든 데이터 삭제 DELETE FROM Reservation

 

17. SELECT

  • 원하는 레코드를 가져옴
  • SELECT 필드이름 FROM 테이블이름 [WHERE 조건]
<sql />
-- 해당 테이블의 모든 필드 선택 (*) SELECT * FROM Reservation; -- WHERE 절을 사용하여 검색할 레코드의 조건을 설정할 수 있음 SELECT * FROM Reservation WHERE Name = '홍길동'; -- AND , OR 을 통해 여러개의 조건을 같이 명시 가능 SELECT * FROM Reservation WHERE ID <= 3 AND ReserveDate > '2016-02-01'; -- 특정 필드만 선택 SELECT Name, RoomNum FROM Reservation; -- 조건을 만족하는 특정 필드만 선택 SELECT Name, ReserveDate FROM Reservation WHERE ID <= 3 AND ReserveDate > '2016-02-01'; -- 중복 값 제거 (DISTINCT) SELECT DISTINCT Name FROM Reservation; -- 선택한 결과 정렬 -- default : ASC (오름차순) SELECT * FROM Reservation ORDER BY ReserveDate DESC; -- 내림차순 -- 쉼표(,)를 사용하여 여러 필드의 데이터를 한 번에 정렬 SELECT * FROM Reservation ORDER BY ReserveDate DESC, RoomNum ASC; -- 별칭(alias) 사용 -- 결과 예 ) -- ReserveDate | ReserveInfo -- 2022-01-05 | 2014 : 홍길동 -- CONCAT() : 인수로 전달받은 문자열을 모두 결합하여 하나의 문자열로 반환하는 함수 SELECT ReserveDate, CONCAT(RoomNum, " : ", Name) AS ReserveInfo FROM Reservation;

 

18. 흐름 제어

18.0.1. 1. CASE 

  • 값 비교
  • 표현식의 논리 값에 따라 다른 값 반환
  • CASE ... WHEN ... THEN ... END
<sql />
select employee_id, first_name, salary, case when salary > 15000 then '고액연봉' when salary > 8000 then '평균연봉' else '저액연봉' end "연봉등급" from employees;
<sql />
SELECT ANIMAL_ID, NAME, CASE WHEN (SEX_UPON_INTAKE LIKE 'Neutered%') OR (SEX_UPON_INTAKE LIKE 'Spayed%')THEN 'O' ELSE 'X' END AS '중성화' FROM ANIMAL_INS ORDER BY ANIMAL_ID;

 

18.0.2. 2. IF()

  • 조건에 따라 다른 값으로 조회하고 싶은 경우
  • IF(조건문, TRUE, FALSE)
<sql />
SELECT ANIMAL_ID, NAME, IF((SEX_UPON_INTAKE LIKE 'Neutered%') OR (SEX_UPON_INTAKE LIKE 'Spayed%'), "O", "X") AS "중성화" FROM ANIMAL_INS ORDER BY ANIMAL_ID;

 

18.0.3. 3. IFNULL()

  • IFNULL(expr1, expr2)
  • expr1이 NULL인 경우, expr2 반환
<sql />
select employee_id 사번, first_name 이름, salary 급여, salary*12 연봉, commission_pct, salary * (1 + ifnull(commission_pct, 0)) *12 "커미션포함 연봉" from employees;

 

18.0.4. 4. NULLIF()

  • NULLIF(expr1, expr2)
  • expr1과 expr2의 값이 서로 같으면 NULL 반환, 같지 않으면 expr1 반환

 

19. 패턴 매칭

19.0.1. 1. LIKE 

  • 원하는 패턴의 문자열 검색
  • % : sub string (0개 이상)
  • _ : 한 글자

* `like`를 `=`으로 사용하지 않도록 주의 

<sql />
-- 이름에 'x'가 들어간 사원의 사번, 이름 select employee_id, first_name from employees where first_name like '%x%'; -- where first_name = '%x%'; # '=' 불가!!!! -- 이름의 끝에서 3번째 자리에 'x'가 들어간 사원의 사번, 이름 select employee_id, first_name from employees where first_name like '%x__';

 

19.0.2. 2. REGEXP

  • LIKE 보다, 더 복잡한 패턴을 검색하는 경우
 패턴   설명
. 줄 바꿈 문자(\n)를 제외한 임의의 한 문자
* 해당 문자 패턴이 0번 이상 반복
+ 해당 문자 패턴이 1번 이상 반복
^ 문자열의 처음
$ 문자열의 끝
| 선택 (OR)
[...] 괄호([]) 안에 있는 어떠한 문자
[^...] 괄호([]) 안에 있지 않은 어떠한 문자
{n} 반복되는 횟수 지정
{m,n} 반복되는 횟수의 최솟값과 최댓값 지정
<sql />
-- 홍'으로 시작하거나, '산'으로 끝나는 이름 SELECT * FROM Reservation WHERE Name REGEXP '^홍|산$';

 

 

20. 타입 변환

20.0.1. 1. BINARY

  • 연산자 뒤에 오는 문자열을 바이너리 문자열로 변환
<sql />
SELECT BINARY 'a' = 'A'; -- false SELECT 'a' = 'A'; -- true

 

20.0.2. 2. CAST()

  • 수로 전달받은 값을 명시된 타입으로 변환
  • 변환하고자 하는 타입을 AS 절을 이용하여 명시
  • CAST(expr AS type)
<sql />
select cast(1 as char) as "cast 문자", cast('23' as signed) as "cast 숫자", cast('20230822' as date) as "cast 날짜";

 

20.0.3. 3. CONVERT()

  • CAST() 함수처럼 인수로 전달받은 값을 명시된 타입으로 변환하여 반환
  • CONVERT(expr, type)
<sql />
SELECT CONVERT(20230822, DATE);

 

 

21. 다중 테이블 연산

21.0.1. 1. JOIN

: 데이터베이스 내의 여러 테이블에서 가져온 레코드를 조합하여 하나의 테이블이나 결과 집합으로 표현해 줌

 

      1) INNER JOIN 

          - 단순히 from 절에 `,`를 사용하는 경우, inner join 으로 연산

          - ON 절과 함께 사용되며, ON 절의 조건을 만족하는 데이터만 가져옴

          - 표준 SQL과는 달리 MySQL에서는 JOIN, INNER JOIN, CROSS JOIN이 모두 같은 의미로 사용됨

          - 테이블1 INNER JOIN(JOIN) 테이블2 ON 조건

<sql />
SELECT * FROM TableA A JOIN TableB B ON A.key = B.key;

 

      2) LEFT JOIN

          - 첫 번째 테이블을 기준으로, 두 번째 테이블을 조합하는 JOIN

          - ON 절의 조건을 만족하지 않는 경우에는 첫 번째 테이블의 필드 값은 그대로 가져옴

            but, 해당 레코드의 두 번째 테이블의 필드 값은 모두 NULL로 표시

          - 테이블1 LEFT JOIN 테이블2 ON 조건

<sql />
-- LEFT OUTER JOIN SELECT * FROM TableA A LEFT JOIN TableB B ON A.key = B.key;

<sql />
-- 순수 A만 구할 때 SELECT * FROM TableA A LEFT JOIN TableB B ON A.key = B.key WHERE B.Key IS NULL;

 

      3) RIGHT JOIN

          - 두 번째 테이블을 기준으로, 첫 번째 테이블을 조합하는 JOIN

          - ON 절의 조건을 만족하지 않는 경우에는 두 번째 테이블의 필드 값은 그대로 가져옴

             but, 해당 레코드의 첫 번째 테이블의 필드 값은 모두 NULL로 표시

          - 테이블1 RIGHT JOIN 테이블2 ON 조건

 

<sql />
-- RIGHT OUTER JOIN SELECT * FROM TableA A RIGHT JOIN TableB B ON A.key = B.key;

<sql />
-- 순수 B만 구할 때 SELECT * FROM TableA A RIGHT JOIN TableB B ON A.key = B.key WHERE A.Key IS NULL;

 

      4) FULL OUTER JOIN

       - MySQL은 FULL OUTER JOIN이 없지만, LEFT JOIN 과 RIGHT JOIN을 이용해 FULL OUTER JOIN 사용 가능

 

<sql />
SELECT * FROM TableA A LEFT JOIN TableB B UNION SELECT * FROM TableA A RIGHT JOIN TableB B

<sql />
-- 교집합 제외 SELECT * FROM TableA A LEFT JOIN TableB B UNION SELECT * FROM TableA A RIGHT JOIN TableB B WHERE A.key IS NULL OR B.key IS NULL

 

21.0.2. 2. UNION

  • 여러 개의 SELECT 문의 결과를 하나의 테이블이나 결과 집합으로 표현할 때 사용
  • SELECT 필드이름 FROM 테이블이름 UNION SELECT 필드이름 FROM 테이블이름

          -  DISTINCT 키워드를 따로 명시하지 않아도 기본적으로 중복되는 레코드를 제거

          - 중복되는 레코드까지 모두 출력하고 싶다면, `ALL` 키워드를 사용

              SELECT 필드이름 FROM 테이블이름 UNION ALL SELECT 필드이름 FROM 테이블이름

 

<sql />
SELECT Name FROM Reservation UNION -- UNION ALL SELECT Name FROM Customer;

 

21.0.3. 3. 서브 쿼리

  • 다른 쿼리 내부에 포함되어 있는 SELETE 문
  • 서브쿼리를 포함하고 있는 쿼리 = 외부쿼리(outer query) / 서브쿼리 = 내부쿼리(inner query)
  • 서브쿼리는 반드시 괄호(())로 감싸져 있어야 함

 

profile

danbibibi

@danbibibi

꿈을 꾸는 시간은 멈춰 있는 것이 아냐 두려워하지 마 멈추지 마 푸른 꿈속으로