>>ㅑ~ 어쩌다 가게 됐지?

회사에서 타팀 송년회에 끼어갔다. 끼어간 팀에는 우즈베키스탄에서 온 동료가 있다. 그래서 회식 장소는 '우즈벡 레스토랑'으로 정해진 듯 하다. 동료 분의 원래 우즈벡 음식 단골 맛집은 #사마르칸트 라고 하는데, 예약에 실패했다고 한다. 그래서 #파르투내 에 가게 되었다. (파르투내가 정확히 맞는지 모르겠다. #포츈레스토랑 이라고도 하는 것 같고.. #파르투네 라고 하는 것 같기도 하다.) 

여튼, '사마르칸트'나, '파르투네'나 둘 다 동대문 쪽에 위치해있다

평소에 맛보지 못한 음식이어서 그런지 모두가 신나는 기분이 들었다.(사실 내가 제일 신나서 '신남' 색안경을 끼고 바라보기도 하였다.)

Where is the 파르투내 restaurant?

동대문역사문화공원에서 내려서 이리저리 지나다보면 나온다 ㅎ_ㅎ 일층에는 같은 가게에서 운영하는 빵집이 있다. 여기 빵도 참 어마무시하게 저렴하고 크다. 우리는 모두 이층으로 올라갔다. 

가게는 어땠나요?

가게에 들어서자마자 벽에 걸린 이국적인 그림이 보인다. 또, 손님들과 직원분들도 다 러시아, 우즈벡 분들인 것 같았다. 손님 중 한국 사람은 우리 밖에 없었던 것 같다. 벽에 걸린 그림에는 어떤 명소가 아닐까 생각되는데, 동료분께 물어보고 싶었지만 자리가 멀었던 관계로 못 물어보았다. 어떤 곳이었을까? 🤔

나에게 있는 가게 사진은 이것 뿐 ㅎㅎ

뭔지는 잘 모르겠지만 귀여워서 찍어놨다. ㅎㅎ 저 주전자처럼 생긴 것이 무엇인지 궁금했다. 메뉴판은 찍지 못했지만, 굉장히 많은 메뉴가 있다. 메뉴판에는 다행히 '한글' 도 적혀있다. 귀여운 오타들도 발견할 수 있다. 예를 들면 '간자 튀김?' 같은 ㅎㅎ 

헉헉.. 다 됐고 무엇을 먹었나욧?

모든 음식은 우즈벡에서 온 동료가 결정하고 주문해주었다. 크.. 너무나 든든한 것! 사실 그래서 '무엇'을 먹었는지는 정확히 모른다.. 그래도 그냥 먹은 것을 다 올려본다.

기본 빵

자리에 앉으니 빨간 양념에 버무려진 바게트 크루통 같은 빵이 자리에 놓여있었다. 안타깝게도 사진은 없다. 맛은 딱딱하고 살짝! 라면스프향이 나는 프레츨(과자) 맛이다.
그 다음에는 엄청 커다란 빵이 나왔다.


맛은 딱딱한 베이글? 같았던 것 같다. 담백하고 맛있다. 동료가 주문을 해주다보니 시킨 메뉴인 것인지 기본 에피타이저인지 헷갈리지만.. 아마 기본일 것 같다는 궁예를 해본다.  x_o

당근 샐러드

짠 이것은 당근 샐러드이다. 동료 분의 설명에 따르자면, 재밌게도 이 당근샐러드가 우즈벡에서는 '한국식 샐러드' 라고 불린다고 한다. 흑.. 이런 설명.. 여행온 거 같아서 너무 재밌었다.. 

당근김치 같은 건가 했는데, 김치라는 느낌보다는 무 생채? 같은 맛과 향이다. 뭔가 중독성 있는 맛이었다. 주문한 대부분의 음식들에 고기가 들어가 기름지고 느끼할때마다 자꾸 손이 가서 결국 다 먹어 버렸다. 모든 나라에는 김치같은 존재가 있는 것 같다. 피클, 김치, 짜사이, 당근 샐러드, 쏨탐 같이.. 

짜사이는 쫄깃쫄깃? 한 느낌이 있고 김치는 아삭!한 느낌이 있는데 얘는 오도독오독! 같은 느낌이었다. 

맥주 - 발티카 흑맥, 라거 맥주

여기가 술은 저렴하지 않다고 들었다. 그래서 4명이서 맥주 두병을 노나 마셨는데.. 와 발티카 흑맥주 진짜 맛있었다. ㅠㅠ 원래 나는 흑맥주를 안좋아하고 라거를 좋아한다.(탄산을 좋아해서) 그런데, 흑맥을 먼저 먹고나니까 라거가 아무 감흥이 없었다.흑흑..  얼마나 감명 깊었는지 나중에 사먹기 위해 상표를 찍어놨다. 

크.. 다시보니 또 술 먹고 싶어진다. 음식이 전체적으로 맛이 강하고 다 큼직큼직해서 평소처럼 많이 못마셨는데.. 킁.. 넘나 맛있었던 것.. 집에 쌓아두고 물대신 마시고싶다. ㅎ_ㅎ 물론, 지금도 물을 잘 마시진 않지만.. 

패스츄리 같이 생긴 고기 빵

아마 이 친구도 멋진 이름이 있을테지만.. 나오자마자 전달받아서 이름을 못물어봤다. 블로그에 올릴 심산이 아니어서 내부를 찍지 못했다. 하.. 가장 중한 것인디.. 

패스츄리 같이 겹겹이 쌓여있는 빵으로 되어있고 안에는 고기가 들어있다. 아마 '양고기' 였던 것 같다. 양념이 되어있지 않은 양고기인데, 사실 양고기를 먹을 기회가 그렇게 많지 않아서 양꼬치 향이 살짝 나길래 양고기인가 했다. 잡내가 많이 나지 않고 맛있었다. ^_^
크기는 내 주먹 사이즈만 했다. 내 주먹은.. 아이폰 내 '측정'으로 측정해보니 7cm가 나온다 .(요새 이거 넘 재밌게 잘 쓰고 있당)

야무진 나의 주먹

여튼 이 정도만했다. 소식가라면 이거 먹고 배부를 수 있겠다는 생각을 했다. 물론.. 나는 단 한번도 소식가였던 적은 없지만.. 

우즈벡 만두

This is 우즈벡 만두. 왕크니까 왕맛있따.. 안에는 또 고기가 들어가있는데 양고기였던 것 같다. 맛은 사실 우리가 아는 고기만두랑 크게 다르지 않다. 가운데 하얀색은 마요네즈다. 그리고 빨간색은 무슨 소스인지는 정확히 잘 모르겠다. 사이즈는 온전히 피지 않은 내 한뼘정도.. 였던 것 같다. 엄청 크다.. 아는 맛이 무섭다고 다른 맛은 잘 생각안나는데 아는 맛이라 또 먹고싶다. 특히 이 새벽에 더.. 아까 그 발티카 흑맥주랑 먹음 넘 맛있을텐데..... 크.. 

함박 소고기 요리

내가 한번 지어본 이름이다. 약간 함박 스테이크 같은 소고기였따. 다진 소고기? 위에는 토마토 소스가 뿌려져 있고.. 음.. 맛있었다. 색감이 너무 예뻤당 방토, 쵸록, 노랑, 주황, 그리고 갈색 고오기~

샤슬릭

되게 위협적으로 큰 양고기 꼬치였다. 이 음식을 보자마자 "아! 이 친구가 메인 음식이구나"! 라는 생각이 들 정도로 크고 먹음직스러워 보였다. 꼬치가 넘 무섭게 생겼다. 사진으로는 무슨 그냥 닭꼬치 같이 보이는데 절대 그렇지 않다. 회식에 참석하지 못한 사람에게 이 '샤슬릭'의 크기를 설명하게 되었을때 '와~~ 이만해~~~' 라고 말하면서 의도치 않게 모두가 '주먹감자' 시늉을 하게 만들었다. 그 정도로 정말 왕 크다. 이거 정말 또 먹고 싶다. 

나는 그동안 양꼬치에서 잡내가 난다는게 무슨 말인지 몰랐었다. 그 이유는 그게 그냥 양꼬치의 향이라고 생각했다. 하지만 이 샤슬릭을 먹고는 그런 생각이 사라졌다. 내가 아는 그 향이 없었다. 그리고 뼈도 쏙-쏙- 잘 빠진다. 위에 무슨 향신료가 뿌려져 있다는 것 같던데 나는 잘 모르겠당. 난 그냥 넘나 맛있었다. ^_^

꼬치가 진짜 흉기처럼 생겼당. 또 몹쓸 내 손과 비교하자면 뭐 내 엄지손가락이 육센치인데 한 40-50센치 되는 것같다.  

라그만

크~~ 이것도 너무 맛있었따! 동료분이 설명 해주시길.. "우즈벡 짬뽕같은거예요!" 안에는 우동 면이 들어있고 감자, 당근, 그리고 '고기'가 들어가있다. 같이 가신 분이 '보르쉬'도 맛있다고 했는데 두개가 조금 비슷한 느낌인가 보다. 우리 테이블은 이것을 너무 맛있게 먹어서 계속 퍼묵퍼묵 했다. 첨에는 뭔가 밍밍한 느낌이었는데 자꾸 퍼먹고 싶은 중독성이 있다. 약간 토마토 스튜 느낌도 나는데 향신료 맛도 나고 맛은 그렇게 강하지 않은! 뭐 그런 음식이었다. 담에 인원이 적어서 메뉴에 제한이 생긴다면 라그만이랑 샤슬릭은 꼭 먹을거다!

총평

크.. 나는 이런 이국적인 식당 넘 좋아서 다음에도 또 오고 싶다! 대신, 향신료에 거부감이 있거나 혀를 때리거나 자극적인 맛을 싫어하면 안좋아할 수도 있을 것 같다. 전체적으로 간이 센 편인 것 같다. 또 음식 하나의 양이 꽤 크다. 근데, 메뉴판도 되게 음식이 많았다. 고로, 이 식당의 모든 음식을 먹어보지는 못할 거 같다. 친구랑 다음에 가게 된다면 꼭 시킬 것은 '발티카 흑맥주', '라그만 혹은 보르쉬?', '샤슬릭' 그리고 안먹어본 다른 메뉴 하나를 끼어서 먹고싶다.^-^


'단조롭고 즐거운 일상 > 먹먹글' 카테고리의 다른 글

삼성중앙역 비어플라주  (0) 2018.09.11
심금을 울리는 엽기떡볶이  (0) 2018.03.10
노량진 겨울 방어  (0) 2018.03.01
굽네 볼케이노 먹먹  (0) 2016.11.27
칠성포차 국물닭발  (0) 2016.11.20

서론

공부 할 내용

도메인 모델을 구현하기 위한 기본 내용

  • 1. 도메인 모델이 뭐지? 엔티티와 밸류
  • 2. 아키텍쳐의 영역, DIP pattern, 도메인 영역의 구성 요소

공부 환경

장소: 동대문 할리스

시간: 월요일 퇴근후

향기: 흡연실 바로 앞 목과 폐가 아플 정도의 담배향기

들었던 음악

본론


1. 도메인 모델 시이작!

도메인이 뭐지? 

소프트웨어로 해결하고자 하는 문제의 영역. 

예를 들어 주겠어요? 

  • 온라인 서점은 도메인이고요! 도메인은 주문, 배송, 결제와 같은 도메인으로 나뉩니다. 도메인을 우리가 구현해야할 필요는 없고 외부 pg 연동같이 구성할 수도 있습니다. 


도메인 모델?

특정 도메인을 개념적으로 표현한 . 도메인 자체를 이해하기 위한 개념 모델.

어떻게 모델로 표현하나?

  • 각자 방법에 맞게끔.
  • 객체 모델(클래스 다이어그램) 일수도 있고. 그럼 객체 지향 언어를 통해서 구현하면 편하구..
  • 상태 다이어그램으로 작성할 수도 있고
  • 계산이 중요하다면 수학 공식을 활용해서 function으로 구현하던지
  • 관계가 중요하면 그래프를 이용해도 되고

이해가기 쉽게 표현하는 거시라고 이해했다 ^_^ 

구현 모델은 또 따로 필요하다. 


도메인 모델 패턴

아키텍처는 표현/응용/도메인/인프라스트럭쳐 4개의 계층으로 구성되어있는 것이 일반적, 여기서의 도메인 모델은 PEAA 책에 따르면, 아키텍처 도메인 계층을 객체 지향 기법으로 구현하는 패턴을 뜻함.

, 계층별로 구현해야하냐 인데, 도메인 모델 패턴은 도메인 계층을 어떻게 구현하는지.

도메인 구현 = 도메인의 핵심 규칙 구현

  • e.g., 출고 전에만 배송지를 변경할 있음. 
  • 주문 취소는 배송 전에만 있음


도메인 모델 도출

    요구사항을 정리해서 도메인 규칙을 만들어 다음에 구현한다.


    엔티티와 밸류

    엔티티

    • 식별자를 갖는다.
    • 삭제할때까지 변경하던 식별자는 유지됨
    • 두개 엔티티의 식별자가 같으면 엔티티는 같다.
      • e.g) 주문번호가 같으면 같은 주문임
    • equals(), hashCode() 메소드를 가짐
    • 생성 시점이나 방법은 도메인 특징 별로 다름
      • 특정 규칙을 쓰거나
      • UUID 클래스를 쓰거나
      • 아이디 같이 직접 입력하거나
      • 일련 번호를 쓰거나(mysql aI key..)
        • 생성하기 전에는 식별자 전달 불가

    밸류 타입

    • 개념적으로 완전한 하나를 표현하고자
    • e.g.) 받는 사람 + 주소를 묶어서 Receiver,
    • e.g.2) price 뜻하는 money 타입
    • 장점: 
      • money 위한 기능을 만들 있음. 돈계산같이..!
    • 어떻게 변경하나?
      • 기존을 변경하는게 아니라 새로운 밸류를 생성함.
      • 이뮤터블(불변)
    • 모든 속성이 같은지 비교해야 밸류 객체가 같은지 있음

    엔티티 식별자와 밸류 타입

    • 식별자를 위한 밸류타입을 사용해서 활용 가능

    도메인 모델에 set 넣지말자? ?

    • set 어떤 의미인지 개념이나 의도가 없어진다
    • 생성할때 완전한 상태가 아닐 수도 있다. (생성한담 셋하는데 하나 빼먹으면 어쩔꺼야? 그냥 생성할떄 받아라)
      • 프라이빗으로 생성할때 set시키도록. 외부에서 set 불가하고.. 

    도메인 용어

    • step1, step2 아닌 payMENT_WAITING, PREPAREING 도메인에서 사용하는 용어를 써라


    2. 아키텍쳐 개요

    네개의 영역

    표현

    • 응용에 변환하여 전달하고 받은 응답을 변환하여 웹브라우저에 보여주고

    응용

    • 표현 영역을 통해 받은 처리하기 위한 기능을 구현
    • 구현하기 위해 도메인 영역의 도메인 모델 사용(도메인 모델에 로직 수행 위임)
    • 주문등록, 주문 취소, 상품 상세 조회

    도메인

    • 도메인 모델 구현(1 내용)
    • 배송지 변경, 결제완료, 주문 총액 계산

    인프라

    • 구현 기술에 대한
    • RDBMS, 메시지 , SMTP, REST API… 

    계층 구조 아키텍처

    전형적인 계층 구조상의 의존 관계를 가지면 생기는 문제들(상위 계층에서 하위 계층으로 의존)

    • 테스트 어려움 (인프라 레벨 룰엔진이 완벽하게 동작해야 응용 영역에서 계산을 있음)
    • 기능확장 어려움(구현 방식을 변경하기 어렵다.) 

    DIP

    고수준: 가격 할인 계산 저수준: RDBMS JPA 구현, Drools 적용

    DIP: 저순준 모듈이 수준 모듈에 의존하도록 바꿈. 어떻게? 추상화한 인터페이스로!


    RuleDiscounter라는 인터페이스를 만들어서 고수준은 ruleDiscounter 활용하고, 저수준은 ruleDiscounter 상속받아 구현. 

    쉬워지는 거지?

    • 테스트해본다면? 
      • 저수준 안만들고 대용 객체를 사용해서 테스트 진행 가능 ( 데이터 활용)
    • 구현 기술이 변경된다면?
      • 고수준쪽은 수정안하고 저수준 구현 객체 생성하는 부분의 코드를 변경한다. (ruleDiscounter 생성하는 애만 바꿈..)

    DIP 아키텍처

    ?? 이해는 안가는 여튼 인프라가 응용 쪽의 인터페이스를 상속 받고 있으니 응용 영역 변경할 필요가 없고 notifier 구현하는 클래스를 인프라에다가 추가하면 되니까 깔끔하다는 같다? 

    도메인 영역의 주요 구성 요소

    • 엔티티
    • 밸류
    • 애그리거트
    • 리포지터리
    • 도메인 서비스

    나는 울 때마다 엄마 얼굴이 된다
    국내도서
    저자 : 이슬아
    출판 : 문학동네 2018.10.25
    상세보기

    나는 울 때마다 엄마 얼굴이 된다 - 이슬아

    엄마 이야기는 조금 반칙인 듯 싶을 정도로 눈물이 나게한다. 

    주말엔 엄마가 말도 없이 자취방에 찾아왔다. 요즈음의 나는 아무 것도 하지않는 주말을 경멸 하면서도, 무언가를 하는게 괴로워서, 아무 것도 하지 않는 것 이외에는 아무 것도 하지 못하고 있다. 어지러운 마음 만큼 내 방도 엉망이었다. 어두운 방에서 오후 서너시에 일어나 화장실에 갔다가 밥과 술을 먹다 지쳐 다시 잠을 자고, 일어나 화장실에 갔다가 밥과 술을 먹고 다시 잠이들고 오후 서너시에 일어난다. 이런 내 모습을 보여주기 싫어 엄마가 오는게 끔찍하게 싫었다.

    엄마는 사과와 귤, 빵을 사왔다. 그리고는 해를 완벽히 차단해 주는 내 암막 커튼(별모양 구멍이 뽕뽕 뚫려있어 해가 떠야 별이 뜨는) 을 걷어주었다. 동묘 바닥같이 널부러져있는 옷을 개어주었다. 함께 청소를 하였다. 요새 귀가 잘 들리지 않는 할머니와 통화하는 엄마를 보며 서글퍼졌다. 엄마가 내 방에 잠시 왔을 뿐인데 공간은 포근해지고 편해졌다. 엄마가 돌아가고나서 또 술을 먹고 잠들긴 했지만 말이다. 

    엄마는 점점 늙어가고 함께 보낼 수 있는 시간은 점점 줄어든다. 나는 언젠가부터 자라지않는 것 같은데 엄마는 사라지고 있는 것 같아 무섭기만 하다. 아, 그런걸 생각하면 눈물이 계속 나면서도 혼자만의 시간을 가지고 싶다. 

    순간은 지나가야만 의미가 생기는 걸까? 순간을 그 자체로 소중히 여길 순 없을까? 엄마가 우는 순간. 엄마가 웃는 순간. 엄마가 귀여운 순간. 그 모든 순간이 영원 했음 좋겠다.

    엄마의 롱 원피스 그 다리 사이의 나. 엄마가 업어주던 순간 일부러 잔뜩 묻히곤 했었던 콧물. 

    시간 여행을 한다면 내 나이의 엄마를 보러 가고싶다.


    '단조롭고 즐거운 일상 > 독후감' 카테고리의 다른 글

    애도 일기  (0) 2019.03.18
    아침의 피아노  (0) 2019.03.18
    소년을 위로해줘 - 은희경  (0) 2018.03.05
    혼자서 완전하게 - 이숙명  (0) 2018.03.03
    82년생 김지영  (0) 2017.09.17

    서론

    사내에서 DDD Start! 책으로 스터디를 진행하기로 했다. 정리하지 않으면 또 아무곳에 남지않을 것 같아 블로그에다가 정리해보려고 한다. 

    우선 DDD는 무엇이고 왜 공부하기로 마음 먹었는지부터 정리해본다.


    What, Why and How

    What is DDD(Domain Driven Design)?

    Domain-driven design (DDD) is an approach to software development for complex needs by connecting the implementation to an evolving model.[1] The premise of domain-driven design is the following:

    • placing the project's primary focus on the core domain and domain logic;
    • basing complex designs on a model of the domain;
    • initiating a creative collaboration between technical and domain experts to iteratively refine a conceptual model that addresses particular domain problems.


    왜 DDD를 공부하기로 맘 먹었는가?

    1. 회사에서 MSA할거라고 팀을 도메인별로 나누어 버렸다. 도메인 별 구현을 하려면 알면 좋겠다고 생각했다.
    2. 그냥 공부를 요새 너무 안해서 공부가 필요했다. (뭐든 상관 없다. 일단 공부 좀 해야겠다.)
    3. 선배들이랑 공부해보고 싶어서. 항상 주니어 위주의 스터디를 해왔는데, 답을 내리지 못하는 경우들이 있었다. 시니어들이 많은 스터디여서 어떤 점이 다를까 조금 궁금하기도 했다. 


      어떻게 DDD를 공부할 것인가?

      회사에서는 화, 목 점심시간에 모든 구성원이 세션을 읽어오고, 발표 담당자가 내용을 요약하여 발표한다. 나는 발표담당자가 아녀서 맘이 편하긴 하지만, 편한 맘 만큼 공부를 많이 안할 수 있으니 매주, 내가 공부한 내용들을 정리할 예정이다.  스터디에서 오간 내용들을 모두 올리면 철컹철컹 할 수 있으니.. 대략적인 논쟁거리, 의문사항이 있으면 추가로 작성해볼까 한다. 
      회사에서는 한 시간마다 두 챕터를 나가기로 했는데, 잘 지켜지지 않고는 있다. 
      책의 서론에 보니 책의 내용이 다음과 같이 구성되어있다. 책이 말하는 대로 꼭지를 잡아서 업로드를 올릴까 한다. 올리는 주기는 주에 1회!

      1장, 2장: 도메인 모델을 구현하기 위한 기본 내용

      • 도메인 모델이 뭐지? 엔티티와 밸류
      • 아키텍쳐의 네 영역, DIP pattern, 도메인 영역의 구성 요소


      3장, 4장: 애그리거트와 리포지터리: 애그리거트가 뭐지? 어떻게 구현하지?

      • 리포지터리는 어떻게 구현하지?
      • 리포지터리의 조회 기능을 우리 다같이 구현해볼까?

      5장: 응용 서비스와 표현 영역

      • 지금 까지 만든 도메인 모델은 어떤 역할인데? 응용 서비스가 어떻게 사용할꺼야? 표현 영역이랑 응용 서비스를 어떻게 연결할꺼야?

      6장: 도메인 서비스의 이유와 구현방법

      • 도메인 서비스가 왜 필요하지? 어떻게 구현할꺼지?

      7장, 8장: 애그리거트의 트랜잭션 범위에 따른 구현

      • 선점잠금과 비선점 잠금 구현법

      9장: Bounded context

      • Bounded context가 뭐지? 어떻게 통합하고 관계가 있지?

      10장: 도메인 이벤트와 CQRS

      • 도메인 이벤트 활용법, 처리법 등
      • CQRS가 무엇이고 어떤 효과를 얻을 수 있을까??



      내가 술이 다시 먹고싶어질까봐 기록을 남긴다. 

      어제는 과음을 했다. 요새 빈번히 필름이 끊긴다. 알콜성 치매를 조심해야한다는데 앞으로는 더 줄여야겠다.

      어제는 곱창을 먹었다. 한라산을 곁들였고 나는 딱 거기서 그만뒀어야 하는 것 같다. 두명이서 한라산 한병을 사이좋게 나누어 마셨다.

      그리고 홍대로 넘어가서 소주를 많이 마셨다. 기억이 잘 나지 않는다. 그때부터는..

      기억이 잘 나지 않을때 일어난 일들을 말하자면,

      우선 몸을 가누지 못했다. 몸을 가누지 못하니 자꾸 넘어지고, 동료가 부축해주는데 이상한 사람들을 쫓아내느라 고생했다. 방을 잡아준다나 뭐다나 하면서 그러던 아저씨들..

      근데 그런 아저씨중 한명이 자기는 이상한 의도 없었담서 경찰을 불러서 파출소에 갔다. 보호자가 필요하다고 해서 동료의 언니가 파출소로와서 싸인을 했다.

      그리고 택시를 타고 가는 내내 술을 먹으면서 들었던 충격적인 이야기때문에, 그 사람을 계속 욕하면서 울었다고 한다. 그리고 나는 택시에 토를했다. 그래서 10만원을 물어줬다고 한다. 

      그리고 나는 집앞에서 동료를 안고서는 고래고래 소리를 질렀다. ㅇㅇㅇ 개새끼!!!!!! 하면서.

      그리고나서 잤다. 아침에 일어나니 정신은 없고 정신이 없고 정신이 없다. 커피를 하나 꺼내마셨는데 겁나 토했다. 머리에는 토가 묻어있고 씻고싶은데 씻다가 토할거같아서 계속 누워있다가 토기가 올라오면 토를하고를 계속 반복했다. 

      그래서 병원에 갔다. 링거를 한시간 반동안 맞았다. 6만원이 깨졌다. 그리고 어제 넘어지면서 머리를 부딪혀서 혹이 나버렸는데 동료분이 걱정해주어서 외과도 들렸다. 다행히 후시딘만 잘 바르라고 한다. 머쓱했지만 다행이었다. 

      제일 미안한거는 동료의 언니분, 그리고 동료. 동료는 내가 물었다고 한다. 미친거 아닌가.. 동료가 나를 부축해주느라 멍이 많이 들었다. 아, 그리고 원피스 끈도 끊어졌다. 나도 멍이 많이 들었다. 한참 자고있을 시간인데 언니분을 깨워서 정말 죄송했다. 그리고 이제 동료분에게도 너무 미안하구 창피하다. 

      아직도 정신을 덜 차린것은 그 사람이 신고했다는게 너무 짜증난다. 흑역사 덜만들수있었는데 파출소를 보내버리다니.. 

      이제는 술을 마시지 말아야겠다. 먹더라도 잔수를 세면서 마셔야겠다. 어제는 6-7병을 둘이서 먹었다고 하니까. 한병 정도가 나의 맥스치인거같다. 앞으로는 소주를 마시지 말아야겠다. 맥주 정도만. 소주를 먹더라면 1병까지만.. 

      어떤 값이 나와야되는데 안나온다고 오류 수정 요청이 있었다. 수정했는데 되게 어이없는 이유였다. 

      원인은 이거였다.


      테이블 이름이 keyboard이고, qwerty라는 컬럼이 있다고 가정하고, 다음의 쿼리를 날려본다.

      SELECT qwerty FROM Keyboard;

      이렇게 하면 qwerty 칼럼의 내용들을 잘 가지고 올테다. 하지만 만약 다음과 같은 쿼리를 날리면 어떻게 될까?

      SELECT QWERTY FROM keyboard;


      정답은 mysql 대소문자 설정에 따라 다르다. 다음과 같은 쿼리를 날려 보았을때

      SHOW variables LIKE 'lower_case_table_names';

      값이 0인 경우 대소문자를 구분하고, 값이 1인 경우 대소문자를 무시하고, 값이 2인 경우에는 대소문자를 구분하지만 이름 비교에서는 구분하지 않는다. 

      구체적은 설명은 다음과 같다. mysql 가이드에서 그대로 긁어왔다. https://dev.mysql.com/doc/refman/5.6/en/identifier-case-sensitivity.html

      ValueMeaning
      0

      Table and database names are stored on disk using the lettercase specified in the CREATE TABLE or CREATE DATABASE statement. Name comparisons are case sensitive. You should not set this variable to 0 if you are running MySQL on a system that has case-insensitive file names (such as Windows or macOS). If you force this variable to 0 with --lower-case-table-names=0 on a case-insensitive file system and access MyISAM tablenames using different lettercases, index corruption may result.

      CREATE TABLE 혹은 CREATE DATABASE문에서 명시된 대소문자로 데이터베이스명과 테이블명이 디스크에 저장된다. 이름 비교는 대소문자를 구분한다. 만약 우리가 대소문자를 구분하지 않는 파일명을 가지고 있는 시스템(윈도우나 맥 OS) 에서 Mysql을 돌리고 있다면 이 값을 0으로 설정하지 않는 것이 좋다. 만약 우리가 대소문자를 구분하지 않는 파일시스템에서 --lower-case-table-names=0으로 값을 강제로 0으로 만들어 버리고, 다른 대소문자를 사용해서 MyISAM 테이블명에 접근한다면, 인덱스 충돌이 일어날 수도 있다.

      1

      Table names are stored in lowercase on disk and name comparisons are not case-sensitive. MySQL converts all table names to lowercase on storage and lookup. This behavior also applies to database names and table aliases.

      테이블명이 디스크에 소문자로 저장되며 이름 비교는 대소문자를 구분하지 않는다. MySQL은 스토리지와 lookup에 모든 테이블명을 소문자로 전환한다. 이 전환은 데이터베이스명과 테이블 aliase(별칭)에도 적용된다.  

      2Table and database names are stored on disk using the lettercase specified in the CREATE TABLE or CREATE DATABASE statement, but MySQL converts them to lowercase on lookup. Name comparisons are not case sensitive. This works only on file systems that are not case-sensitive! InnoDB table names are stored in lowercase, as for lower_case_table_names=1

      CREATE TABLE 혹은 CREATE DATABASE문에서 명시된 대소문자로 데이터베이스명과 테이블명이 디스크에 저장되나, MySQL이 룩업에 소문자로 전환한다. 이름비교는 대소문자를 구분하지 않는다. 이 값은 대소문자를 구분하지 않는 파일 시스템에서만 동작한다! InnoDB 테이블명은 lower_case_table_names=1 조건처럼 소문자로 저장된다. 

      여튼 나같은 경우에는 대소문자를 구분하지 않도록 설정은 되어있었지만은, 결과를 가지고올때는 qwerty칼럼이 아니라 QWERTY 칼럼으로 값을 가지고 와서, 키매핑을 잘못 시켜준 상황이었다. (나를 qwerty일거라고 생각하고 코드를 짰는데 QWERTY였던..)


      서론

      지금까지 별생각없이 insert statement를 써왔다. 되게 오래걸리는 작업, 크론에서 돌아가야할 애들인 경우에만 의식적으로 bulk insert를 썼다.('bulk' 라는 말 때문이었을까? 뭔가 대용량인 경우에만 써야할 것 처럼 느껴졌다.)

      최근 내가 만든 부분에서 에러로그가 자주 올라오면서 우리 센터장이신 분이 나에게 찾아와 질문하시길... 

      for문 돌면서 insert해요, 아니면 statement 만들어서 insert 해요?

      나는 당당하게! for 돌면서 insert하고 있슴디다^-^ 문제 없습니다. 했는데 문제가 있다고 한다. '엔지니어'라는 직함을 달고있다면 어떤 원리인지 찾아보아야 했을텐데 잘 몰랐어서, 그리고 찾아볼 생각도 없었어서 ㅠ 이제라도 다시 찾아본다. 


      본론

      역시 가장 정확한 정보는 만든 사람들의 가이드가 아니겠는가. insert vs bulk insert와 같은 키워드로 googling을 해보니 쉽게 찾을 수 있는 링크! 내용 중 중요하다고 생각되어지는 부분들을 가지고와 번역해본다. 

      https://dev.mysql.com/doc/refman/8.0/en/insert-optimization.html


      Optimizing INSERT Statements 

      insert 문을 최적화 하기

      To optimize insert speed, combine many small operations into a single large operation. Ideally, you make a single connection, send the data for many new rows at once, and delay all index updates and consistency checking until the very end.

      insert속도를 최적화하기 위해서는, 여러개의 작은 연산을 하나의 큰 연산으로 합쳐라. 이론상으로, 하나의 커넥션을 만들고, 한번에 다수의 행에대한 데이터를 보내고, 모든 index 업데이트,  consistency checking(무결성 체크?)를 끝날때까지 지연시킨다. 


      The time required for inserting a row is determined by the following factors, where the numbers indicate approximate proportions:

      한 행을 insert하는데 필요한 시간은 다음과 같은 요인들에 의해서 결정된다. 숫자는 대락적인 비율을 뜻한다. 

      Connecting: (3)

      Sending query to server: (2)

      Parsing query: (2)

      Inserting row: (1 × size of row)

      Inserting indexes: (1 × number of indexes)

      Closing: (1)

      If you are inserting many rows from the same client at the same time, use INSERT statements with multiple VALUES lists to insert several rows at a time. 

      만약 동일한 클라이언트에서 동시에 여러 행들을 insert하고 있다면, 한번에 여러 행을 insert하도록 insert문을 VALUES 리스트랑 같이 사용해라.

      This is considerably faster (many times faster in some cases) than using separate single-row INSERT statements. 

      이것은 분리된 한행의 insert문을 사용하는 것보다 상당히 빠르다. 



      결론

      사소한 것일지라도, 내가 만든 것이 어떻게 되어있는지 알고 넘어가야겠다는 생각이 들었다. 내가 만든 부분은 한 클라이언트에서 동시에 약 10번의 insert가 개인당 이뤄졌었다. 5000명이 들어왔다고 하면 50000번의 insert가 있었던 거였는데 이걸 2번의 insert로 줄일 수 있었다. 그러면 총 10000번의 insert로 오분의 일로 커넥션을 줄일 수 있었따. 히이익. 자주 몰리는 부분들에 대해 조금 더 고민해 볼 것. 그리고 트랜잭션 레벨에 대해서도 고민해볼 것. 고민할 것이 투성이다. 


      '개발개발 > mySql' 카테고리의 다른 글

      DB를 쿼리로 업데이트 할때  (0) 2018.09.16
      mysql 월/주차 구하기  (1) 2018.01.06
      left join 시 속도 문제  (0) 2016.12.20
      SELECT 정렬하기 정리  (0) 2016.12.13
      order by varchar to int  (0) 2016.11.24

      뺄셈을 이제 막 배우던 때였다. 

      오빠를 따라 재능 스스로 학습지 과외를 받았다. 

      "작은 수에서 큰 수를 빼면 어떻게 되나요?"

      선생님의 대답은 

      "그런 경우는 없어"


      미술 시간이었다. 

      내 그림 실력만으로는 충분히 표현할 수 없다는 걸 알았다. 그래서 사람들 위에 덧붙이려던 말풍선. 

      그 때 선생님이 말하기를 

      "그림에는 글자가 들어가면 안돼."


      나의 수학 시간과 미술 시간. 

      옛날 기억이지만, 요새 자주 떠오르는 기억들이다. 

      하지말라 했던 것들, 더 구체적으로 말하자면 그냥 하지말라 했었던 일들이.


      그냥/당연하게/원래 라는 단어가 사라졌음 좋겠다.

      서로가 서로를 납득 시켰음 좋겠다. 

      내가 말하는 것들이 납득이 가지 않으니 설명해달라 했음 좋겠다.

      내가 납득이 가지 않는다고 말하는 것이, 딴지를 걸거나 시비를 거는 것처럼 느껴지지 않았음 좋겠다.





      '단조롭고 즐거운 일상 > 요새 하는 생각' 카테고리의 다른 글

      예의  (0) 2019.03.18
      미를 추구하는 것은 고등한 영역같다.  (0) 2019.01.23
      Let me not be me.  (0) 2018.08.29
      평가와 피드백  (0) 2018.06.14
      늦은 2017 회고와 2018 다짐  (0) 2018.03.01

      일을 하다보면.. 그러기 싫지만 강제로 DB에 접속해서 쿼리로 업데이트를 해야할때가 많다.

      그럴때마다 나는 그냥 쫄아있는 상태로 손을 벌벌 떨면서 ... update table set column = 0 where flag = 1; 과 같은걸 날리고 데이터를 확인하고는 했다.

      하지만 그럴때 덜 쫄 수 있는 방법이 있다. 방법은 트랜잭션을 사용하는 것이다. 

      R을 제외한 CUD를 칠때는 다음과 같은 방법을 쓴다.

      1. 정상적으로 작업했을 때 나오는 카운트 수를 본다. 

      select count(*) as c from table where flag = 1;

      그럼 쿼리가 실행되면서 몇건인지가 나온다. 그 몇 건을 봐둔다. 

      2. 다음과 같은 문구를 미리 작성해둔다. 주석도 포함해서

      # start transaction;

      # update table set column = 0 where flag = 1; 

      # rollback;

      # commit;

      3. 주석을 하나씩 풀어가면서 진행한다. 우선 트랜잭션을 실행시킨다. 

      start transaction; (실행)

      # update table set column = 0 where flag = 1; 

      # rollback;

      # commit;

      4. 원래 돌리려고 했던 업데이트 문 실행
      update table set column = 0 where flag = 1; 

      5. 이때 affected rows가 맨 첨에 날린 카운트수와 일치하는지 본다. 시간 차이가 있겠으나 뭐 얼추 비슷한 값이 나올것이다. 

      6. 만약 이상함을 감지했다면 당황하지 않아도 된다. rollback 시키기

      rollback;

      이렇게 하면 내가 update문을 치기 전으로 돌아간다. 트랜잭션을 걸어놓았으니까 말이다. 

      7. 정상적이었다면? commit하기!

      commit;을 실행시켜준다. 그러면 끝이당.

      '개발개발 > mySql' 카테고리의 다른 글

      insert와 bulk insert 무엇을 써야할까요?  (1) 2018.10.04
      mysql 월/주차 구하기  (1) 2018.01.06
      left join 시 속도 문제  (0) 2016.12.20
      SELECT 정렬하기 정리  (0) 2016.12.13
      order by varchar to int  (0) 2016.11.24

      + Recent posts