You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
두개 이상의 테이블 합칠 때 join on 여러번 쓰는 대신 from 에서 테이블 이름을 comma로 연결하면 inner join
union: 쿼리 결과를 하나로 합쳐준다. 기본적으로는 중복을 제거하지만 제거하지 않으려면 union all을 사용한다.
union으로 full outer join 만들기
left join한 후 right join을 union한다.
selectuser.user_id, user.name, addr.addr_namefrom user
left join addr
onuser.user_id=addr.user_idunionselectaddr.user_id, user.name, addr.addr_namefrom user
right join addr
onuser.user_id=addr.user_id;
Sub Query
Query안에 Query를 작성
select, from, where절에서 사용이 가능
SELECT 절에서의 Sub Query
select에서 column명을 넣어주는 대신 Sub Query를 넣어준다.
# 전체 나라 수, 전체 도시 수, 전체 언어 수를 하나의 row로 출력
use world;
select
(selectcount(name) from country) as country_count,
(selectcount(name) from city) as city_count,
(selectcount(distinct(language)) from countrylanguage) as language_count
from dual;
원래 MySQL에서는 select와 함께 반드시 from이 와야하는데 딱히 쓸 게 없으면 dual을 써서 from dual을 써줘야 하지만 workbench에서는 안써도 동작
FROM 절에서의 Sub Query
8백만 이상 인구를 가진 도시의 국가 코드, 국가 이름, 도시 이름, 도시 인구 수 출력
join을 사용한 방식: 모든 데이터를 합친 후 필터링한다.
selectcountry.code, country.name, city.name, city.populationfrom country
join city
oncountry.code=city.countrycodehavingcity.population>=800*10000order bycity.populationdesc;
800만 이상이 되는 city를 받는 subquery를 만든 후 join하면 작업할 데이터 양이 훨씬 적어진다.
# 우리가 필요한 sub query(800만 이상이 되는 city)를 먼저 뽑자select countrycode, name, population
from city
where population >=800*10000;
# 이 쿼리를 city라는 이름으로 넣는다.selectcountry.code, country.name, city.name, city.populationfrom country
join (
select countrycode, name, population
from city
where population >=800*10000
) as city
oncountry.code=city.countrycodeorder bycity.populationdesc;
WHERE 절에서의 Sub Query
800만 이상 인구를 가진 도시의 국가 코드, 국가 이름, 국가 인구수, 대통령 이름 출력하기
# 800만이 넘는 인구를 가진 도시의 국가 코드 Sub Query 먼저 뽑기select distinct countrycode
from city
where population >=800*10000;
# SubQuery 넣기select code, name, population, headofstate
from country
where code in (
select distinct countrycode
from city
where population >=800*10000
)
distinct는 함수로도 쓸 수 있지만(distinct()) 예약어로 쓸 수도 있다.
where code in ()으로 이 조건에 부합하는 값만 필터링 할 수 있다.
select code, name, population, headofstate
from country
where code in ("BRA", "KOR", "IND");
or (any) 과 and ('all')
하나의 조건만 충족해도 되는 경우 any로 or을 나타낸다.
모든 조건을 충족해야 하는 경우 all로 and를 나타낸다.
한국(KOR)이나 브라질(BRA)보다 인구가 많은 국가의 국가코드, 국가명, 인구수 출력
select code, name, population
from country
where population > any (
select population
from country
where code in ("KOR", "BRA")
);
VIEW
가상의 테이블로, 실제 데이터를 저장하고 있지 않다.
특정 데이터를 보여주는 역할만 하므로 수정 및 설정이 불가능하다.
from 절에서 테이블 이름 쓰듯이 쓰면서 쿼리문을 줄여주는 장점이 있다.
# view 생성createviewcountry_10000asselect code, name
from country
where population >=10000*10000;
# view 사용selectcountry.code, country.name, city.name, city.populationfrom city
join country_10000 as country
oncountry.code=city.countrycode;
INDEX
tree 알고리즘을 통해 테이블에서 데이터를 검색할 때 빠르게 검색하게 해준다.
앞에서부터 쭉 찾는 것이 아니라 index를 보고 빨리 찾게끔
장점: 검색속도
단점: 저장공간을 추가로 사용. select를 제외한 쿼리는 느려진다.
where절에 들어가는 컬럼을 index로 설정하면 좋다.
select를 많이 쓰는 데이터에서 사용하는 것이 좋다.
c.f. 로그데이터 등은 select할 일이 없으니 쓰면 안된다.
cluster형 인덱스와 보조(secondary) index로 나뉜다
일반적으로 말하는 인덱스는 secondary를 가리킨다.
클러스터형은 데이터 자체가 인덱스로 사용되며, 정렬에 관련된 것일뿐 검색 성능에는 영향이 없다. 행 데이터를 자신의 열을 기준으로 정렬해주는 기능
INDEX 만들기와 EXPLAIN
explain: 쿼리에 대한 실행계획을 출력해준다.
createindextdateon salaries(to_date);
explain
select*from salaries
where to_date <"1986-01-01";
rows: filtered만큼 걸러내준 예측치
Extra: Using where는 full search, Using index condition은 인덱스 사용
쿼리 속도를 예측해 볼 수 있다.
인덱스 삭제
dropindex tdate on salaries;
TRIGGER
누군가 delete from을 한다거나 where절을 안 쓰고 업데이트 치는 등 사고칠 경우를 대비하는 기능
update나 delete는 과거 데이터가 보존이 안 되므로 이를 상쇄할 수 있는 백업기능
하루나 3일 등 특정 날짜 단위로 특정 테이블에서 update나 delete 쿼리가 실행되면 현재 작성 중인 테이블을 다른 곳에 insert하는 쿼리가 실행되어 과거 데이터를 보존하도록 한다.
먼저 수정할 채팅 목록을 생성해보자
createdatabasetr;
use tr;
createtablechat(
chat_id intprimary key auto_increment,
msg varchar(200) not null,
rdate timestamp default current_timestamp
);
insert into chat(msg)
values ("hello"), ("hi"), ("hello"), ("mysql is fun");
delimiter |
createtriggerbackup_tr
before deleteon chat
for each row begininsert into backup(chat_id, msg, rdate)
values(old.chat_id, old.msg, old.rdate);
end |
show triggers;
가장 앞에 있는 hello 메시지를 삭제해야 하는데 모든 hello 메시지 삭제한 경우 backup table에서 가져와 다시 insert를 할 수 있다.
# 실수로 모든 메시지 삭제deletefrom chat
where msg="hello";
# 다시 복구select*from back_up;
insert into chat(chat_id, msg, rdate)
select chat_id, msg, rdate from backup;
Back-up
백업 시 서비스가 운영중인지의 여부(Hot vs. Cold), 백업 방식에 따른 구분(Logical vs. Physical) 등으로 종류를 나눈다.
Hot vs. Cold Backup
Hot Backup: 백업 순간에 DB가 실행중
장점: 서비스를 계속할 수 있다
단점: 데이터 변경 시 동기화가 안 될 수 있다.
Cold Backup: 백업 시 DB 중단
장점: 안정적으로 백업이 가능
단점: 서비스 운영이 중단. 따라서 사용량 낮은 시간에 실행한다.
Logical vs. Physical Backup
Logical: SQL 쿼리문으로 DB를 변환
장점: 실제 DB가 아니라 쿼리문만 가지고 있으면 되므로 적은 용량으로 백업이 가능하며, 문제 발생 시 에러메시지로 파악이 쉽다. OS 호환도 잘 된다.
단점: 문자열 데이터로 변환하는 시간이 소요된다. 시스템 자원을 많이 사용한다.
Physical: 실제 데이터 binary file을 그대로 복사
장점: 백업과 복원이 빠르다. 시스템 자원을 적게 사용한다.
단점: 디스크용량을 많이 사용하며, 파일시스템이 다른 OS끼리 호환 X, 에러가 났을 때 이유를 알기 어렵다.
TMUX
터미널 멀티플렉서
$ tmux new -s {세션이름}으로 새로 만들고, ctrl+B 떼고 1초 안에 c를 누르면 윈도우가 생긴다.
$ tmux attach -t {세션이름}으로 같은 세션에 두 컴퓨터가 접속하여 페어프로그래밍이 가능하다.
나가려면 $ logout
Oauth
모든 API는 Oauth의 표준 프롴토콜을 기반으로 한다.
(1)service provider(인스타그램)와 (2)user/client(나)와 (3)3rd-party ocnsumer(인스타 사진 출력 서비스)가 있다고 해보자
2가 따로 다운받아서 보내줄 필요 없이, 3이 1의 DB에서 바로 받을 수 있도록 1, 2에게 허락을 받는 것
1에게는 DB에 대한 request token을, 1, 2에게는 저작권 허락을 위한 access token을 받는다.