반응형

 

쓰기와 쓰기가 동시에 작업하는 것이 불가능

읽기와 읽기는 동시에 언제든 가능

 

문제 부분은 쓰기 트랜잭션읽기 트랜잭션이 동시에 일어날 때

 

하나의 트랜잭션은 발생 시점부터 데이터 일관성을 가져야 한다.

 

 

 

Read uncommited - 오손 읽기(Dirty read) 

commit되지않은 데이터를 읽는 문제

 

 

Read commited - 반복 불가능 읽기(Non repeatable read)

update -> commit된 데이터를 읽어, 데이터 일관성이 깨진다.

 

 

Repeatable read - 유령 데이터 읽기(Phantom read)

트랜잭션 시작 전 commit 된 데이터만 undo영역을 이용하여 읽는다. 일관성이 깨지지 않는다.

insert -> commit 된 데이터를 읽어, 데이터를 추가로 읽어 데이터 일관성이 깨진다.

 

 

Serializable - 모든 문제 해결

트랜잭션이 다른 트랜잭션으로 부터 완전히 독립

 

 

 

 

MySQL은 Repeatable read를 사용하므로 유령 데이터 읽기가 발생할 수 있지만,

inno db 넥스트 키락으로 row에 락을걸어 insert 트랜잭션을 막기때문에, 유령 데이터 읽기가 발생하지 않는다.

 


 

https://idea-sketch.tistory.com/46

 

[MySQL]MySQL 벼락치기(5) - 갭락(Gap Lock)과 넥스트 키 락(Next-Key Lock)

이번 포스팅은 사내에서 MySQL 관련 내용 발표를 위해 Real MySQL(http://wikibook.co.kr/real-mysql/) 서적을 기반으로 학습하고 이해한 내용을 정리하는 포스팅이다. 포스팅에서는 주로 InnoDB 스토리지 엔진

idea-sketch.tistory.com

 

반응형
반응형

 

 

Mysql은 Oracle과는 다르게 rownum을 지원하지 않아서 커스텀으로 만들어서 사용해줘야 한다. 

함수를 사용하여 rownum을 지정해줄 수도 있다.

 

  • 커스텀 rownum
  • 함수 row_number()

 

 


 

커스텀 rownum

 

select @rownum:= @rownum + 1 as rownum, t.* 
from table1 t, (select @rownum := 0) r;

 



select rt.* 

from (
select @rownum:= @rownum +1 as rownum, t.* 
from table1 as t, (select @rownum := 0) as r 

) as rt
where rt.rownum between 2 and 4;

 

 


 

select rt.* 

from (
select @rownum:= @rownum +1 as rownum, t.* 
from table1 as t, (select @rownum := 0) as r

) as rt
order by rt.age;

 

 

부속질의로 사용 시 rownum을 만들고 order by를 하면 순서가 뒤바뀔 수 있다.

 


 

select @rownum:= @rownum +1 as rownum, t1.* 
from (
select t.* 
from table1 as t
    order by age desc
) t1, (select @rownum := 0) as r
order by t1.age;

 

 

order by 이후에 rownum을 만들어 주자.

 


row_number() 함수 (Mysql 8버전 이상)

 

select row_number() over (order by t.age desc) as rownum, t.*
from table1 t;

 

 


 

select row_number() over (order by t.age desc) as rownum, t.*
from table1 t
where t.rownum between 3 and 10;

 

해당 쿼리는 동작하지 않는다.

from -> where -> select 순서로 동작하므로 where 에서 select에서 동작하는 rownum을 알아볼 수 없다.

 


 

select rt.* 
from (
select row_number() over (order by t.age desc) as rownum, t.*
from table1 t
) as rt
where rt.rownum between 3 and 10;

 

부속질의를 활용해서 rownum이 생성된 이후에 사용해야 한다.

반응형
반응형

 

도메인 무결성 제약조건

 

각 속성의 도메인에 지정된 값만을 가져야 한다는 조건이다.

ex) 주문 일자 속성 -> 날짜 값만을 가져야 함

 


 

개체 무결성 제약조건

 

기본키는 NULL이면 안되며, 유일해야 한다.

 


 

참조 무결성 제약조건

 

부모 릴레이션에서 튜플을 삭제할 경우

 

RESTRICTED : 자식에서 참조하고 있다면 삭제를 거부

CASCADE : 자식의 튜플까지 삭제

DEFAULT : 자식의 외래 키 값을 DEFAULT 값으로 변경

NULL : 자식의 외래키 값을 NULL로 변경

 

 

 


 

반응형
반응형

 

제4 정규형

 

1 대 N 다치 종속의 제거이다.

하나의 결정자가  다른 속성에서 여러 종속자를 결정할 때 다치 종속한다고 한다.

 

한 릴레이션에서 1 대 N으로 관계가 나타나도 되지만, 문제가 되는 부분은 1 : N, 1: N 두 개 이상으로

다치 종속이 구성되어있을 때 이상현상이 발생하므로 중심이 되는 속성을 기준으로 릴레이션을 분리해주어야 한다.

 

이름 과목 동아리
홍길동 데이터베이스 농구
홍길동 보안 축구
홍길동 데이터베이스 야구

 

해당 테이블에서 과목을 추가하게 되면, 동아리도 추가를 해줘야 하는 문제가 발생한다.

그러므로 이름, 과목 / 이름, 동아리로 분리해줘야 한다.

 


 

제 5 정규형

 

조인 종속성이 존재하면 제5 정규형 대상이다.

조인 종속성이란 마치 조인을 한 것과 같은 릴레이션의 중복을 제거해주는 것을 말한다.

 

이름 과목 동아리
홍길동 데이터베이스 농구
홍길동 데이터베이스 야구
홍길동 보안 농구
홍길동 보안 야구
홍길동 자바 농구
홍길동 자바 야구

 

해당 테이블만 놓고 보면 이름과 과목은 연관성이 있고, 이름과 동아리 또한 연관성이 존재한다.

즉, 이름 속성을 기준으로 연관성을 가지므로 조인 종속성이 존재한다고 볼 수 있다.

 

조인 종속성을 제거하여 분리하면

이름, 과목 / 과목, 동아리 / 이름, 동아리 3개의 테이블이 나오게 된다.

 

이름, 과목

홍길동 데이터베이스
홍길동 보안
홍길동 자바

 

과목, 동아리

데이터베이스 농구
데이터베이스 야구
보안 농구
보안 야구
자바 농구
자바 야구

 

이름 동아리

홍길동 농구
홍길동 야구

 

 

2개의 테이블을 조인하면 본래의 릴레이션을 형성할 수 없다.

3개의 테이블을 전부 사용하여 조인해야 본래 테이블로 복구가 가능하다.

 

 

 

반응형

'CS > Database' 카테고리의 다른 글

[Mysql] rownum 활용  (0) 2022.07.20
[데이터베이스] 무결성 제약 조건  (0) 2022.06.15
[Database] MYSQL SQL 총정리  (0) 2022.05.03
[MYSQL] 각종 도구 사용 명령어  (0) 2022.05.03
[데이터베이스] 자연 키 vs 대리 키  (0) 2022.04.22
반응형

문자열 함수

 

문자열 함수에서 인자가 여러 개일 때 적용대상 @column 위치는 거의 맨 앞이다.

 

concat

select concat(@column, " ", @column) from books;

 

concat_ws

select concat("구분자", @column, @column) from books;

 

substr

substring

substring(@column, start, end) 앞 ~ 뒤 [모두 포함]

substring(@column, start) 앞부터 count

substring(@column, -start) 뒤부터 count

 

replace

replace(@column, "바뀌기 전 문자", "바뀐 후 문자")

 

reverse

reverse(@column)

 

char_length

char_length(@column)

 

upper

대문자로 변경

 

lower

소문자로 변경

 

LPAD

lpad(@column, 총길이, 채울 문자)

 

RPAD

rpad(@column, 총길이, 채울 문자)

 

Binary

binary(@column)  대소문자를 구분한다.

@sql 

where binary(name) like "%C%"

 

 


 

형 변환

cast(@column as type)

type - unsigned, signed, decimal, char, date, datetime

 


숫자 함수

 

ABS(숫자) : 절댓값

 

CEIL(숫자) : 값보다 큰 정수 중 가장 작은 정수 // 4.7 -> 5

FLOOR(숫자) : 값보다 작은 정수 중 가장 큰 정수 // 4.7 -> 4

ROUND(숫자, 자릿수) : 자릿수 기준 반올림 

TRUNCATE(숫자, 자릿수) : 자릿수 기준 버림

 

POW(X, Y)  : 제곱

SQRT(숫자) : 제곱근

MOD(분자, 분모) : 나머지

 

GREATEST(숫자1, 숫자2, ...) : 가장 큰 수

LEAST(숫자1, 숫자2, ...) : 가장 작은 수

 


날짜 함수

 

year(), month(), day(), hour(), minute(), second()

 

date(), time()

 

date_format(@column , '% H')

문자를 얻을 땐 % 대문자

숫자를 얻을 땐 % 소문자

 

date_diff(@column , INTERVAL 1 MONTH)

date_add(@column , INTERVAL 1 MONTH)

 

 

datetime +- INTERVAL expr unit

 

@sql

  • SELECT DATE_ADD(birthdt, INTERVAL 1 MONTH) FROM people
  • SELECT DATE_ADD(birthdt, INTERVAL 10 SECOND) FROM people;
  • SELECT DATE_ADD(birthdt, INTERVAL 3 QUARTER) FROM people;
  • SELECT birthday + INTERVAL 1 MONTH FROM people;
  • SELECT birthday - INTERVAL 5 MONTH FROM people;

 

https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format

 

MySQL :: MySQL 8.0 Reference Manual :: 12.7 Date and Time Functions

12.7 Date and Time Functions This section describes the functions that can be used to manipulate temporal values. See Section 11.2, “Date and Time Data Types”, for a description of the range of values each date and time type has and the valid formats

dev.mysql.com

 

 

 


랭크

 

rank() over (order by @column [asc or desc]) // 중복, 순위 밀림 => 1, 1, 1, 4 ...

dense_rank() over (order by @column [asc or desc]) // 중복, 순위 밀리지 않음 => 1, 1, 1, 2, 2 ...

row_number() over (order by @column [asc or desc])  //  순서대로

select 절에서 만들어지기 때문에 Oracle rownum처럼 추가로 view로 만들어서 정렬할 필요가 없다.

 


문법

 

distinct 

중복 행 제거 (컬럼이 아닌, 행 전체 기준)

 

order by

[option] asc, desc 

 

limit

0부터 N까지 조회

특이한 점은 전체를 조회할 때 N을 큰 숫자로 지정함

ex) limit 0, 19221032181328091

 

like, not like

where @column like '% 문자%' // 모든 문자, % 자리에 어떠한 문자도 없어도 조회

where @column like '_문자' // 한 개, 숫자 자릿수도 가능

 

between

@column between 3 and 15 // 3 이상 15 이하

 

if(조건식, true일 경우, false일 경우)

 

ifnull(@column, null일 경우)

 


집계 group by

 

mysql5 -> mysql8 변경사항

 

 

select min(stock_quantity), title

from books

group by released_year;

min(stock_quantity)는 집계 함수인 반면

title은 집계 함수의 결과가 아니고, group by의 대상도 아니라서

여러 값이 존재해서 오류를 일으키거나, 임의의 값을 가져오게 된다.

 

 

select min(stock_quantity)title 

from books

group by title;

title이 group by의 대상이라서, 대표 값이 명확히 있기 때문에 가능하다.

 

 

group by 이후에 min(stock_quantitiy) 행을 보고자 할 때 서브 쿼리를 활용

select * 

from books 

where stock_quantity 

in  (select min(stock_quantity)

       from books

       group by released_year);

 

 

group by 

select집계 함수, group by 대상만 사용 가능

 

집계 함수

count(), min(), max(), avg(), sum()

집계함수는 중첩할 수 없다. max(count(@Column)) 불가능

 

 

null 값을 집계 함수에 포함시키려면 IFNULL, CASE를 사용하면 된다.

EX) SUM(IFNULL(<COLUMN>, 1)

 


분기문

 

if (조건식) then

     명령문

elseif (조건식) then

     명령문

else

     명령문

end if

 


 

case

      when (조건식) then 명령문

      when (조건식) then 명령문

      when (조건식) then 명령문

      else

end case

 


 

while(조건식) do

    명령문

end while

 

 

 


조인

 

join(기본 조인), inner join(내부 조인), equi join(동등 조인)은 전부 다 같다.

natural join - join을 수행한다. (단, 조인에 사용한 열은 한 번만 추출)

 

마찬가지로

left outer join과 left join의 차이는 없다.

 

명시하는 방법 때문에 종류가 많아 보이지만 사실 같은 것이 많다. 헷갈리지 말자.

 

조인 종류 

inner join

 

left join

right join

full outer join [mysql 에선 지원하지 않는다.]

 

self join

 

cross join

 


@sql

SELECT g1.pg, g1.af, b.title FROM
(select max(pages) as pg, author_fname as af
 from books group by author_fname) g1
JOIN books b
ON g1.pg = b.pages AND g1.af = b.author_fname;

 

  • from 부속 질의로 필요한 테이블을 만들고 조인하면 유용하다.
  • join 조건에 and를 사용하여 더 분명하게 join 해줄 수 있다.

 

ON table.col BETWEEN 10 AND 20

 

  • join 조건에 between으로 범위 조인도 가능하다.

 


 

UNION

관계없는 테이블을 합칠 수 있음

필드명(as 가능)과 데이터 타입이 같아야 함

중복 값은 기본적으로 제거되지만 필요한 경우 UNION ALL

 

@sql

(select city, char_length(city) from station order by char_length(city) asc, city asc limit 1)
union
(select city, char_length(city) from station order by char_length(city) desc, city asc limit 1);

 


부속 질의

 

select

scalar 부속 질의 (단일행, 단일열)

 

from

inline-view (가상의 테이블을 일시적 생성)

 

where

중첩 부속 질의 

단일 행 단일 열 - 비교 연산자

다중 행 단일 열 - all, any

다중 행 다중 열 - in, exists

 

 


 

단일 행 단일 열 

비교 연산자, select에서도 사용 가능한 scalar 부속 질의

 

다중 행 단일 열   ALL, ANY

any는 부속 질의의 결과가 하나라도 만족하면 true가 된다.

단일 열 이어야 한다.

 

다중 행 다중 열  IN, EXISTS

select * from students s 
join papers p 
on s.id = p.student_id 
where (p.grade, p.student_id) in ( (60, 1), (75, 1) );    # 괄호 필수

 

 

 

 

 

 

 

 

 

 

 

 


 

SQL 프로그래밍

 

delimiter를 변경해주는 이유는 선언 시에 세미콜론이 문장의 끝이 아님을 알려줘야 하므로 변경을 해준다.

 

변수 선언과 대입

set @변수명 = 대입값;

 

 

프로시저

프로시저를 create할 때는 종료 문자 delimiter 변경해주어야 한다.

프로시저 안에서 사용되는 변수 선언 declare 변수명 타입 [default n]

변수의 값 변경은 set

 

 

drop procedure if exists testProcedure;
delimiter $$
create procedure testProcedure(
    in num1 int,           // input
    in num2 int,
    out num3 int,       // output
    out num4 int

)
begin 

   declare num5 int default 5;    // 변수 선언

   set @num10 = 10;    // 변수 선언 대입


    set num3 = num1 + num2;        // 값 변경
    set num4 = num1 - num2;
end $$
delimiter ;

set @add = 0;
set @sub = 0;


call testProcedure(5, 10, @add, @sub);

 

 

 


 

함수

프로시저와의 차이점은 파라미터 in, out 이 없다. 입력만 가능하다.

return 에 반환 데이터 형식을 지정해야 한다.

함수 호출은 select 문장 안에서 호출한다.

함수 내부에서 select 사용이 불가능하다.

 

 


 

커서

 

# 프로시저 내부

 

declare EOR boolean default false;   // 행의 끝을 알릴 변수 

declare 커서명 cursor for (select sql)   // 커서 선언

declare CONTINUE HANDLER for not found set EOR = true;   // 더 읽을 행이 없을 때 동작할 명령어

 

open 커서명

 

cursor_loop  : loop

    fetch 커서명 into 저장할 변수 // 커서 선언 -> 결과 sql 칼럼 개수에 맞게 변수 설정

 

    if EOR then leave cursor_loop   // 더 읽을 행이 없으면 true

    end if

 

    set sum = sum + 결과 변수

end loop cursor_loop

 

close 커서명

 

 

mysql, rownum 만들기
select @rownum:= @rownum +1 as rownum, t.* 
from table1 t, (select @rownum := 0) r;

 

 


 

트리거

삽입, 삭제, 갱신이 일어나면 자동으로 작동되는 개체

삽입, 삭제, 갱신 이전 테이터를 저장 등을 할 수 있다.

after 트리거와 before 트리거 가 있다.

 

create trigger 트리거명 

    after DELETE // 삭제 이후

    on 테이블 // 트리거를 부착할 테이블

    for each row // 각 행마다 적용

begin

    동작할 명령어

end 

 

 

 


create view 뷰네임 as 쿼리

필요한 정보만 노출시켜 보안에 도움이 된다.

복잡한 쿼리를 뷰로 미리 생성해놓고 단순한 쿼리로 조회, 사용할 수 있다.

 

 


인덱스

 

검색 속도가 향상된다.

추가적인 공간이 10% 정도 필요하다.

변경 작업이 자주 발생할 경우 오히려 성능이 낮아진다.

 

 

클러스터드 인덱스 

테이블당 하나만 생성 가능

영어사전처럼 정렬을 인덱스에 맞춰서 해놓는다.

기본키를 지정하면 기본키 정렬에 맞게 클러스터드 인덱스가 자동 생성된다.

클러스터드 인덱스는 기본키에 unique not null 칼럼보다 우선 적용된다.

 

보조 인덱스 (비 클러스터드 인덱스와 비슷한 개념)

여러 개 생성 가능

책의 찾아보기처럼 별도로 존재한다.

칼럼을 unique null로 지정하면 보조 인덱스가 자동 생성된다.

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

반응형
반응형

[GOORM.IDE]

 

경로이동 : cd node_modules/mysql/sqls
mysql 실행 : mysql
sql file 실행 : source 파일명.sql

 

 

오류: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'

명령어 : sudo service mysql restart

 

 


[WORK BENCH]

 

reverse engineer / table -> erd

forward engineer / erd -> table

 

반응형
반응형

데이터 베이스 설계시 기본키 설정 조건

 

  • null값은 허용하지 않는다.
  • 유일해야 한다.
  • 변해선 안 된다.

 

 

과거에는 자연 키를 기본 키로 설정하는 것이 정석이었지만, 최근에는 변할 가능성이 적은 대리 키 방식을 선호

 


 

https://www.inflearn.com/questions/27694

 

테이블 설계 관련 문의 및 MongoDB JPA 관련 - 인프런 | 질문 & 답변

안녕하세요 영한님, 며칠 전 복합키 관련 질문을 올렸고,  원하는 답변을 얻을 수 있었습니다. 그리고 추가 질문이 있어서 다시 문의드립니다. 1. 테이블 PK 관련.. 설계를 진행하면서 사수 분 생

www.inflearn.com

 

 


 

반응형
반응형

[데이터베이스] SQL 순서 (문법과 실행 순서)


SQL 문법 순서

 

  • SELECT
  • FROM
  • JOIN
  • WHERE
  • GROUP BY
  • HAVING
  • ORDER BY

 

 


SQL 실행 순서

 

  • FROM
  • JOIN
  • WHERE
  • GROUP BY
  • HAVING
  • SELECT
  • ORDER BY

 

DISTINCT, ORDER BY, LIMIT 등 을 제외하면 SELECT의 실행은 최종적으로 이루어진다.

 

JOIN으로 테이블을 결합하고, WHERE 조건을 적용, 그룹화를 진행한다.

 

그후 형성된 테이블을 SELECT 한다.

반응형
반응형

[데이터베이스] 보이스 코드 정규형 BCNF


 

데이터베이스의 정규화를 공부 중 보이스 코드 정규형의 이해가 쉽지 않았어서 정리하고자 글을 작성합니다.

우선 보이스 코드 정규형의 정의는 이렇습니다.

 

모든 결정자가 후보키(유일, 최소)여야 한다.

 

일단 결정자라 함은 릴레이션 내에서 다른 속성을 결정할 수 있는 것입니다.

예를 들면 (이름, 주민등록번호)로 구성된 릴레이션이 있다고 했을 때, 이름 속성은 동명이인이 있을 수 있으므로 주민등록번호 속성을 결정하지 못합니다.

하지만 주민등록번호 속성은 릴레이션에서 유일하기 때문에 이름 속성을 결정할 수 있습니다.

이렇게 한 속성이 다른 속성을 유일하게 결정할 수 있을 때 결정자라 합니다.

자연스럽게 이름은 주민등록번호의 종속자가 됩니다.

* 주민등록번호(결정자) -> 이름(종속자)

 

이러한 결정자의 역할을 주로 하는 것은 보통 기본키라고 할 수 있습니다.

하지만 보이스 코드 정규형에서 문제가 되는 부분은 이러한 결정자의 역할을 할 수 있는 속성이 후보키가 아니란 말입니다.

 

후보키라는 것은 유일성과 최소성을 갖습니다. 유일성은 릴레이션 내에서 유일하다는 것이고, 최소성은 최소 집합 관계로 키를 구성하는 것을 말합니다.

 

다시 보이스 코드 정규형 정의로 돌아가서 보면, 결정자인데 후보키(유일성, 최소성)를 만족하지 못하고 있는 것입니다.

이 말은 릴레이션에서 결정자 속성이 다른 속성을 결정할 수 있음에도 튜플로 여러 번 등장한다는 말입니다.

그리고 이러한 결정자가 결정하는 속성인 종속자가 기본키의 부분 집합인 경우 이를 제거해야 합니다.

 

 

학번 과목 교수
6014 데이터 베이스 브라운
5813 데이터 베이스 브라운
4831 데이터 베이스  블랙
1231 정보 보안 레드

 

학번과 과목이 기본키로 설정돼있고 한명의 교수는 한개의 과목을 가르친다고 가정했을 시 교수 속성은 결정자입니다.

 

결정자 -> 종속자

브라운 -> 데이터 베이스

블랙 -> 데이터 베이스

레드 -> 정보 보안

 

현재 교수만 알면 과목을 알 수 있습니다. 교수 속성은 결정자입니다.

하지만 결정자인데도 불구하고 교수 속성은 현재 후보키가 아닙니다. (유일성을 만족하지 않는다.)

한 릴레이션 내에서 튜플로 2번 등장했기 때문입니다. (브라운)

후보키의 조건인 유일성을 만족시키지 않습니다. 

 

교수 결정자 속성의 종속자는 과목 속성입니다.

현재 종속자인 과목은 기본키의 부분집합이므로 이 부분을 제거해주어야 합니다.

 

결국 이러한 릴레이션은 보이스 코드 정규형을 적용시켜야 하는 조건을 만족합니다. 

 

 


 

무손실 분해

 

한 릴레이션을 분리했을 때 R1, R2 두가지 릴레이션이 나오게 됩니다.

이때 R1, R2 를 교집합 했을 때 나오는 값은 R1의 키 이거나, R2의 키여야 합니다.

 

(학번,과목), (교수, 과목) 은 교집합의 결과가 과목이고, 과목은 한쪽의 키가 아니기 때문에 무손실 분해가 아닙니다.

 

 

보이스 코드 정규화를 적용하여 무손실 분해 결과로 분리된 테이블은

(학번,교수) , (교수, 과목)가 됩니다.

 

(학번,교수), (교수, 과목) 은 교집합의 결과가 교수이고, 교수는 한쪽 테이블의 기본키이기 때문의 무손실 분해입니다.

 

 


REF. 키의 종류

 

슈퍼키 : 유일하게 식별, 단위는 최소가 아니어도 된다.

후보키 : 유일하게 식별, 최소 단위여야 한다.

 

기본키 : 후보키 중 선정된 키

대체키 : 기본키로 선정되지 않은 후보키

 

대리키 : 가상의 키

외래키 : 다른 릴레이션의 기본키를 참조

 

 

반응형

+ Recent posts