본문 바로가기

TIL

TIL) TINYINT/BIT, Spring Content-type, 코드를 DB 에서 읽어와서 처리할 때 resource

1. TinyInt / bit

 

[TINYINT]

  • numeric 데이터일 뿐, boolean 이 아니다.
  • 개발자들이 에플리케이션에서 boolean 처럼 동작하게 한 것 뿐이다.
  • 1byte (8bits) 를 차지한다.
  • SIGNED TINYINT = -128 ~ 128 / UNSIGNED TINYINT = 0 ~ 255

 

[BIT]

  • 2진 데이터일 뿐, boolean 이 아니다. (Mysql 에서)
  • 개발자들이 에플리케이션에서 boolean 처럼 동작하게 한 것 뿐이다.
  • bit(1) 이면 1 bit 의 저장용량을 차지할 것 같지만, bit(1) ~ bit(64) 모두 1byte 를 차지하며, 만약 bit(1) 타입의 column 이 3개라면 각각 1byte 씩 3bytes 의 용량을 차지한다. => tinyint 와 똑같다.
  • tinyInt 에는 2라는 (boolean 이 될 수 없는) 값이 들어갈 수 있지만, bit(1) 에는 0 과 1 임을 보장할 수 있긴 하다.

 

Mysql 에서 tinyInt 와 bit(1) 모두 boolean 을 표현하기 위한 데이터는 아니다.

둘 모두 차지하는 저장공간은 같다.

결론은, 정답은 없는 문제이다는 것이다.

 

그럼에도 bit 대신 대부분 tinyint 를 쓰는 이유는,

  1. java Mysql 드라이버에서 COALESCE() 메서드에서 bit 가 사용될 때, 2진 데이터로 사용하기 때문에 따로 캐스팅을 해야한다.
  2. bit 라는 것을 프로그램마다 의미하는게 약간 다른 경우가 있어서, 이런 경우에 같다 착각하고 시행착오를 겪을 수 있다.

이런 이유로 많이들 속편한 느낌(?) 으로 tinyInt 를 사용한다고 한다.

 

https://www.bennadel.com/blog/3845-why-i-use-tinyint-columns-instead-of-bit-columns-for-boolean-data-in-a-mysql-application.htm

 

Why I Use TINYINT Columns Instead Of BIT Columns For Boolean Data In A

Ben Nadel looks at the imperfect use of BIT and TINYINT fields as representations of a Boolean value in a MySQL database; and, why he prefers to use the TINYINT column-type since the trade-offs make m

www.bennadel.com

 

 

 

 

 

2. Spring content-type

[대표적인 컨텐츠 타입]

  • Text : text/css, text/html, text/plain
  • File : mutipart/formed-data
  • Json : application/json, application/json
  • 폼 데이터 : application/x-www-form-urlencode

request 에 실어 보내는 데이터 (body 에만 해당) 의 type 정보를 의미한다.

request 를 보내는 클라이언트는 여러가지일 수 있다. 브라우저, postman, curl 등등..

 

대부분의 브라우저는 요청을 보낼 때, body 를 인코딩해서 잘 보내 주지만,

브라우저가 아닌 클라이언트의 요청을 처리할 때에는 이 컨텐츠 타입을 잘 지정해주는게 좋다.

 

 

[Spring 의 content-type]

 

스프링에서는 FormHttpMessageConverter 가 해당 request 의 컨텐츠 타입을 정하고 컨버트해주는 역할을 한다.

AnnotationMethodHandlerAdapter 에 의해 자동으로 골라져서 등록된다.

@RequestBody 가 붙었다면 => application/json

@ModelAttribute => application/x-www-form-urlencode

이런 식으로.

하지만 아래 방식을 사용하면, 기본으로 위 처럼 정해진 방식에 고정되지 않고 유연하게 (form 데이터를 @RequestBody 로 받는 등) 데이터를 받을 수 있다. (consumes 사용)

 

그리고, @RequestMapping 에서 반환하는 컨텐츠의 타입을 옵션이 있고 (produces)

body 의 데이터의 content-type 인 만큼, @GetMapping 에는 없는 @PostMapping 의 특별한 옵션(consumes)이 있다.

 

@PostMapping(
    path = "/login"
    consumes = {"text/plain", "application/*"},
    produces = [MediaType.MULTIPART_FORM_DATA_VALUE]
)

 

  • produces : String 리스트를 받는다. 이를 지정하면 response 의 컨텐츠 타입을 설정할 수 있다. 생략시 자동으로 정해진다.
  • consumes : String 리스트를 받는다. 이를 지정하면 request 의 content-type 이 명시한 요청만을 받을 수 있다. content-type 이 명시한 것과 다르면 HttpMediaTypeNotSupportedException 를 발생시킨다.

 

https://www.baeldung.com/spring-url-encoded-form-data

 

https://gist.github.com/jays1204/703297eb0da1facdc454

 

Http Method는 POST, Content-Type이 application/x-www-form-urlencoded인 경우 body를 encoding하는게 맞을까?

Http Method는 POST, Content-Type이 application/x-www-form-urlencoded인 경우 body를 encoding하는게 맞을까? - postbodyEnc.md

gist.github.com

 

https://2ham-s.tistory.com/292

 

@RequestMapping의 produces,Content-Type,Consumes란?

| @RequestMapping의 produces 속성을 이용하여 Response의 Content-Type을 제어할 수 있다. @Consumes : 수신 하고자하는 데이터 포맷을 정의한다. @Produces : 출력하고자 하는 데이터 포맷을 정의한다. 1.요청..

2ham-s.tistory.com

 

 

 

 

3. DB 에서 쿼리를 읽어와서 데이터를 처리할 때 컴퓨터의 resource

(application 서버와 DB 서버가 다른 서버라고 가정)

  1. DB 에 쿼리를 날린다. -> io lock , 메모리와 cpu 논다.
  2. 쿼리 결과를 받는다. -> 메모리 많이, cpu 조금
  3. 처리한다. -> 메모리 많이, cpu 많이
  4. DB 에 쿼리 결과를 날린다. - > io lock, 메모리와 cpu 논다.

싱글 스레드로 하면, 1번과 2번 4번에서 cpu 와 memory 가 남는다.

chunking 해서 비동기로 여러 스레드로 돌리면 처음에야 모두 1,2 번이 놀겠지만 각 스레드에서 속도가 다 다르기 때문에 결국에 조화를 찾아가서 실행시간 동안 적절하게 컴퓨터의 한도를 잘 쓰게 된다.

 

 

멀티 스레드 환경에서는 CPU 가 터진다거나, 메모리가 터지는 일을 잘 계산해야하는데

이는 아직 경험이 부족해서 가늠이 되지 않는다...

이런 작업을 할 때에 컴퓨팅 리소스 사용을 모니터링하면서 경험을 쌓아야할 것 같다.

 

[참고] 아래 블로그에서 몽고 DB 를 사용하는데,

1000만건씩 조회하면 Memory 를 2~3GB 사용한다고 한다.

CPU 는 낮게 사용하는 것으로 보이긴 하지만, 이는 코드가 뭘 실행하느냐에 따라 다를 듯 하다.

https://lts0606.tistory.com/136

 

Java를 활용한 MongoDB 대용량 집계, 억단위

Mongotemplate를 통해서 데이터를 집계하는 방법은 aggregate라는 함수를 호출하여 실시 한다. aggregate함수를 적은량의 데이터를 대상으로 실행하면 사실 문제가 되지 않는데, 데이터량이 많아진 경우

lts0606.tistory.com