배움 __IL/TIL 1기

TIL : 69번째- 230315 [3-2-수]

Mo_bi!e 2023. 3. 15. 18:16

※ Keep in mind

 본 내용은 웹개발과정의 강의 중 내용을 복습을 위해서 메모한 것에 불과한 것입니다. 이러한 연유로 강의내용을 오인한 나머지 오기재 및 불기재가 있을 수 있으니 '참고'만 해주시길 바랍니다. 저의 경우에도 본 내용을 단순하 읽은 것이 결코 저의 것이라고 생각하지 않습니다. 본 내용은 복습를 위한 초기 내지 중간 과정에 불과한 것이고, 이후에 내용을 보충 후 인출 및 설명하기 과정이 있어야 비로소 복습의 단추가 어느정도 마무리 되어간다고 볼 수 있습니다.

 따라서 당초에 본 내용은 비공개였습니다. 그럼에도 불구하고 본 내용을 공개한 점은 함께 공부하는 동료들과 나눔을 바탕으로 배움과 성장의 공진화라는 소기의 목적을 달성에 어느정도 도움이 될수 있기 때문이라고 생각합니다.

I. DB 

1. 제약조건

(1) 들어가며

1)

설계에서 마지막단계에서 챙기는거야!

주체 간 행위들을 기록하는건데, DB에 기록하는것이야

 

개념은 행위를 기반으로하지만, 행위를 기반으로하는것은 주체와 대상으로 나누어져 이것을 찾아가야해

테이블모양이 아니라 행위 주체를 찾았지만, 테이블구조의 모양은 가지지 않았어!

구조를 가지게하기 위해서 몇대몇인지 파악하면 공식적으로 테이블 구조를 만들 수있어

 

2)

테이블구조에서 잘라낼게 있는지 확인하는거야! 정규화는 경험이야 이는 사람에게는 단계를 거치치않아

한번 거치면 느낌적인 느낌으로 테이블을 다 잘라



만들어진 테이블에 자료형이있고, 필수or옵션 등이 있어야해

 

(2) 프로젝트에 투영해보기

1)

우리프로젝트와 관련해서 만들자!

 

테이블만드는 방식은 (쿼리문 create) / (워크벤치 ui) / (Engineering reverse)

 

2) reverse

reverse 방식을 해보자! 테이블을 바탕으로 ERD를 만드는거야!

한편 날짜관련 컬럼은 datetime을 쓰자! 컬럼에 들어갈 값들을 신경써야해

DATE 타입날짜만 포함되는거야 / DATETIME 날짜 시간 모두 포함하는거야

 

이제 제약조건을 신경써 보자

 

(2) 이론

1) 도메인 제약조건 : 속성도메인이 아닌 값이 올 수 없도록 하는 제약조건

올바르게 들어갈수있는지 판단하고 제약하기 위한거야

 

우선 이렇게 3가지가 있어!

도메인이란 우선 컬럼,변량,변수과 같아! 도메인은 유효한값의 범위라고 나와

유효한값의 범위는 사실 값은 다 범위를 가지고있어

 

2) NOT NULL

NN을 체크

컬럼 중 필수컬럼이 있다는 의미야

다시말하면 NULL이여서는 아니된다는 말이야

반드시 값을 받게끔하는 제약을 걸 수 있느냐 의미야

 

3) DEFAULT

NOTNULL의 경우 입력하지 않으면 다른 데이터가 들어오게 하는거야

필수컬럼이 사용자가 입력해도되는 경우 하지 않아도 되는 경우로 나누어져

 

하지않아도 되는 경우기본값 넣어서 사용자가 입력의 불편함 덜어내! 그리고 올바른 값 들어가게끔 기본값을 넣으면돼

 

방법은 2가지야! 쿼리로 하거나 / 워크벤치로 하거나

우측에 디폴트 입력

4)

직접 입력이 어려운 경우 오토인크리먼트 사용하면 돼

Auto Increment

현재 시간을 바로 넣는건 이런방식이야 쿼리문으로는

 

 

5)

forward engineer로 모델방식으로 테이블을 만들기가 가능해!

 

이 방식으로 하면 

member1 테이블이 만들어져

이렇게 신기한데 유료버젼은 더 좋아

다이어그램을 그리고 클릭한번이면다 만들어져

 

테이블을 create하는 DDL은 그래서 외울필요가 없어 안쓰는경우가 많고, 쓴다고 하더라도 어쩌다 써서 create table을 쓸 뿐이야

외우는건 오늘날 보면 시대착오적이야

 

6)

필수컬럼은 완벽하게 NULL이 안오게 했어

not null 에다가 null을 넣거나 안넣으면 오류가 생겨! 두번째는 내가 값을 안넣고 하면은 기본적으로 값이 들어가버려

 

컬럼에 들어갈 내용은 체크할것이 있어 바로 값의 유효범위가 있어

유효범위가 맞아야해

LEVEL에다가 1,2,3 세개 단계인데 10이들어오면 틀려

 

Active는 형식은 정수형인데 실수가들어오면안돼

 

이런것들을 어떻게 제한이 가능할까?

이런경우 필요한게 조건문이야 조건문이 바로 CHECK 제약조건이야

 

7)

제약이라는것에 조건이 달리면 CHK_Perosn이라는 이름으로 조건을 다는거야

제약조건 이름을 지정하지않으면 묵시적이름으로 일련번호가 들어가

 

보통 작명은

체크명 + 테이블명 + 컬럼명 3가지로 패턴을 만들어!

chk_menu_price 

 

wizard에서 제약조건다는게 안보여서 어쩔 수없이 쿼리문에서 직접 달수밖에없어

여기와 같이 level 은 1 ~ 3 사이인데, 5를 입력하면 제약조건 위반이 돼

만약 2를 입력하면 해결이 돼

 

2. 제약조건

(1) 들어가며

도메인단위 제약조건 DB구축시 해야하는 마지막 단추야

컬럼에 데이터 넣으려고할때 올바르게 데이터들어가게하는 제약조건 3가지 NOTNULL, DEFAULT, CHECK 

 

모든 컬럼에 올바른 값이 들어갔다고 했을 때, 엔티티는 올바른값만 채워진걸까? 아니야

각각은 올바를수도 있지만 도플갱어가 들어가면안돼(동일값)

 

같은게 들어가는걸 막아야하는데 이런경우 쓰는게 primary제약조건이야

 

(2) 키의 종류

기본키 / 후보키 /외래키/ 수퍼키 / 대리키 가있어

(3) entity 제약조건 : 기본키, 후보키, 대리키

1) 기본키

레코드를 식별하는 식별자 컬럼을 <기본키 컬럼>이라고 해

식별자 쓸수 있는 컬럼은 뭘까?

식별자로 쓸 녀석을 골라서 해 

 

2)

주민, 폰번, 이메일 은 중복된 값이 안들어가서  PK가 가능해, 이를 후보키 라고 해!

 

주민번호가 PK가 되면, 나머지 휴대폰번호 이메일은 <Alteranteive key (대체키)>라고 해

 

다만 주민번호는 PK 로 쓰면안돼 항상 주민번호로 비교해야해 -> 개인정보는 키로 쓰면안돼

왜냐 PK는 공개해야하기 때문이야

 

이메일도 PK안돼 노출가능하고 프라이빗하지만,

예전에는 가입했다가 탈퇴시 이미 사용중인 아이디라고 해! 왜냐하면 PK로 썻기 때문이야

로그인 시 id를 쓸수있지만 사용자를 식별하기 위해서 login아이디를 쓰는건 좋은게 아니야

 

PK그러면 뭐 써야해? : 개인정보 관련 안돼! 계정이 삭제되면 계정을 식별하던건 남아!

결국 이런경우에는 아이디를 이용하는 <대리키> 라고해

이메일 등을 프라이머리를 쓸 수없다고 할 때 대리키를 써

 

<대리키> : 아이디 / 번호 / 코드 를 쓸거야

 

<슈퍼키>는 유일성을 만족한 애들을 의미하는거야

예로들어서 주민번호, 핸드폰번호, 이메일주소 등이야!

이경우 뿐만아니라 조합해서 이용이 가능한 경우에도 가능해

 

이게 id로 <대리키> 쓴 방식이야

제약조건중 id는 프라머리키라고 쓴적이없어

 

--

pk로 선택한 것은 절대로 중복도 null도 올 수도 없어

주민번호, 이메일, 핸드폰도 PK라고 할수도있지만, PK는 하나의 컬럼만 할거야(대리키를 쓴경우)

 

나머지 중복이 되면 안되는 것은 Unique를 체크 해줘

name에 unique이면 나와 이름이 같으면 안되는 경우야!

unique 위반

--

 

멤버테이블 만들 때 로그인아이디가 있어

 

user_name 이 있을 때 대리키를 primary키로 하는게 좋아  -> 회원탈퇴를 생각하면돼! (id 중복문제!)

pk나 uq는 컬럼에서 도플갱어가 있으면 올바르지않아

 

entity 제약조건은 pk제약조건 uq제약조건이야

 

--

(4) 엔티티 사이 제약조건

1)

엔티티사이 관계끊어질 수있는데 부모없는 자식이 되버릴수도있어

부모없이 태어난경우가 있어

 

2) foreign 제약조건을 고려해보자

메뉴에 대한 댓글간에 관계야

그런데 현재 comment외래키가 없어

 

두개는 서로 1:N 으로 비식별관계

자식을 선택하고 하면 연결을 하면 외래키 아이디가 저절로 들어가

그렇게하면 외래키 제약조건이 포함이 된거야

 

3)

company2 와 employee2외래키 관계

company2 에 존재하지 않는 '회사 id 1' 을 employee2에 넣자

이 경우 데이터를 넣으면 

외래키 제약조건 때문에 입력을 할 수 없게된다.

외래키 제약조건으로 회사id가 존재하지않아.

 

 

4)

외래키 제약조건은 자식키에 붙는거야!

자식 comment 테이블을 기준으로! menu의 id를 참조하게끔 할 수있어!

 

 

2. 트랜잭션 처리과정

(1) 들어가며

트랜잭션 전파속성이란 이미 트랜잭션 진행 중 추가적인 트랜잭션어떻게 처리해야할지를 결정하는 것을 의미한다.

 

(2) 트랜잭션 전파방식 설정

1)

직렬방식이 아니라 병렬동시에 일어나는 방식에 대해서 생각해보자!

 

 

2)

여기서 <DirtyRead>란 다른 트랜잭션에 의해서 실행되었지만, 커밋되지 않은 데이터읽는 행위를 의미한다.

즉 위의 경우 hitUp()이 실행되었지만 커밋되지않았는데, noticeDetatil()로 데이터를 읽는 행위를 의미한다.

 

이런 경우 제대로 하지 않으면 Dirtyread 가 발생할수도 있어!

 

hitup() 은 update, insert문장을 실행하는거야

insert에서 오류가 발생하면 롤백이 돼

 

다시말하면 rollback도 commit 도 일어나기전읽는 이상한현상을 <dirty read>라고해

 

3)

고립화 옵션은 위와같이 총 5가지야 

DBMS마다 디폴트옵션이 달라 (오라클, mysql, mariaDB는 디폴트가 READ_COMMITTED야!)

 

아까전의 문제는 READ_UNCOMMITTED

옵션에서 오라클은 UNCOMMITTED 된것 없어 즉 디폴트로 READ_COMMITTED 이기 때문이

 

dirty read 되는 경우는 잘없어 그런데 옵션을 바꿀수있다고 했잖아 

dirty read 있음에도 옵션바꾸는 이유는 뭘까? 어떤이유가 고립화를 느슨하게 하는걸까?? '성능' 때문이야

 

못읽게한다는건 곧 기다리게 한다는거야

update 한뒤 commit안하면 계속 기다리고있었던경우 기억해보자!

 

성능도 중요하지만 신뢰성도 중요하다고 하면 이런 옵션은 안돼

신뢰성도 딱히중요하지도 않는데, 기다리게 하는것(성능)도 좀 그러면 적절하게 옵션을 바꾸면돼

 

 

4)

- REPEATABLE_READ 더 빡빡한거야 (특정 row만)

NON-REPEATABLE_READ 

왼쪽에서 73번을 조회해 그 사이에, 오른쪽 다른 쓰레드가 삭제를하고 다시 조회하는데 그 결과가 다르게 나타나고, 이뿐만 아니라 UPDATE 문제가 발생하는 경우를 의미해

 

REPEATABLE_READ 는 수정 중에 읽기만 해도 기다리는거야! 다시 읽을 줄 모르니까 그래서 기다리는 범주가 더더 길어져

즉 누군가 읽기만 해도 기다려야해 (내가 73쓰는데 쟤가 읽었다고? 기다려!)

 

 

5)

팬텀리드는 테이블 통째로 나 혼자 쓰는거야! 그 어떤것도 하지마 (로우를 넘어 테이블 통채로)

이 옵션은 테이블 자체를 잠궈버리는 옵션이야! 이런 고립화옵션들을 스프링은 기본적으로 지원해!

 

 

(3) 스프링에서 이용해보기 : for 성능 

고립화동기화(순서)에 대한 옵션이야!

 

1) 

Read Uncommitted : 커밋 상관없이 다 읽기 -> 성능은 좋지만 dirtyRead발생할수있어! (취소될것이 읽혀)

Repeatable Read : 39번째 row 읽을 경우 트랜 끝날때 까지 읽지도 쓰지도 못하게

Serializable Read : 테이블 자체를 손못대게끔

 

 

-> 기본옵션은 READCommit 야

 

 

2) 전파옵션 (propagation)

전파옵션이란 스프링에서 특정 스레드에서 다른 스레드로 참여할 때 '합류조건'을 의미한다. 주로 propagantion옵션으로 이용이 가능하다

Dao 사용 시 수정을 할 때 단일업데이트 가능하고, 

 

전파옵션은 밑단의 애가 전파를 어떻게할지 결정하는거야

3. 트랜잭션 전파모드

나 전파하는데 어떡할꺼야 묻는거야(옵션)

 

- mandatory:

서비스가 트랜잭션 가지고 와서 나를 묶어주어야해

나를 호출한 서비스가 트랜잭션 가지고있지 않으면 화내는거야!

무조건 트랜잭션 필요해!!!

 

서비스가 무조건 트랜을 가지게끔 하는거야!

 

- suppots

지원은 해줄게 나는 딱히 트랜이 필요하지는 않아

 

- required_new

부모 트랜을 나에게 엮지마

나는 부모 트랜 원자성에 나를 넣지말라는 말이야

부모 트랜 유무 상관없이 자식만 가져가

 

- required:

현재 트랜이 있으면 지원해주는거야

나 자체로 필요하거든 몰고왔으면 지원하는등으로 Dao 처리하는거야

 

- not supported:

난 트랜 안할거야 나보고 하라고 하지마 나는 지원도 안할거야

나는 껴주지 말라는 뜻이야

 

- never:

트랜지원하지않는다는 의미야 

나 실행하라고 나 트랜잭션안한다고 내는거야

 

 

nes:

중첩해서 트랜 한다는게 결국 트랜지원하는거처럼 볼수도 있어

 


1. 보충

(1) 스프링과 트랜잭션

 

 

 

2. 회고 

1) 제약조건을 설정하는 방식이 흥미롭다

특히나 디폴트나 체크방식으로 유용하게 이용이 가능하다

 

 

2)

트랜잭션 전파방식과 전파옵션이 흥미롭다.

 

'배움 __IL > TIL 1기' 카테고리의 다른 글

TIL : 71번째- 230317 [3-2-금]  (0) 2023.03.17
TIL : 70번째- 230316 [3-2-목]  (0) 2023.03.16
TIL : 68번째- 230314 [3-2-화]  (0) 2023.03.14
TIL : 67번째- 230313 [3-2-월]  (0) 2023.03.13
TIL : 66번째- 230310 [3-1-금]  (0) 2023.03.10