게임 DBA 를 하다보면 이벤트 관련한 쿼리 제작을 많이 하게 됩니다. 

보통의  [이벤트 대상자 추출] -> [대상자 들에게 상품 지급]  구조로 쿼리를 작성 하시게 되는데요 

이벤트 대상자를 산정하는 로직이 복잡 하거나 상품 지급 로직이 복잡 해지게 되면 쿼리가 길어지게 되고 그로인해 버그가 발생할 확률이 올라 갑니다.

그걸 방지하기 위해서 쿼리도 모듈화를 많이 하게 됩니다.

위 경우는 크게 [이벤트 대상자 추출] , [아이템 지급] 두개의 sp로 나눌 수 있습니다. 그때 sp간 자료 공유를 위해  쿼리에서 select into로 물리 테이블을 만들어 사용하시는데 그럴 필요 없이 지역 임시 테이블을 사용 해도 동일하게 구성할 수 있습니다.


대상자 추출 sp 입니다.


  CREATE proc [dbo].[sp_temptable_send] (  

@command Varchar(5)

  , @o_ret int out

  )

  as

set @o_ret = -1;

--다른 sp와 공유할 임시 테이블 생성 

create table #tmp_user( name varchar(30));

insert into #tmp_user(name) values (CONVERT(varchar(30),GETDATE(),21));

exec dbo.sp_temptable_receive 'test', @o_ret output; --호출 당한 sp에서 임시테이블의 정보를 select 

--지역 임시 테이블은 Procedure가 종료되면 자동으로 삭제됨 

--drop table #tmp_user;

return; 



상품 지급 sp


  CREATE proc [dbo].[sp_temptable_receive] (

  @command Varchar(5)

  , @o_ret int out

  )

  as

  set @o_ret = -1;

  --호출측 과 약속한 임시테이블에서 데이터를 꺼냄

  insert into [dbo].[tbl_test](cname) select name from #tmp_user;

  set @o_ret = @@ROWCOUNT;

  return;

 


대상자 추출 sp에서 대상자와 상품을 매칭 시켜 임시테이블에 담아 놓으면

상품 지급 sp에서는 해당 명칭의 임시테이블에서 정보를 가져와 실제로 상품을 지급하는 동작을 수행 합니다.

상품지급 sp를 생성할 때 임시테이블의 유무는 검사하지 않기 때문에 

상품지급 sp를 미리 만들어 놓고 약속된 임시테이블을 대상자 추출 sp에서 생성한 후 상품 지급 sp를 호출하여

정상적으로 상품을 지급할 수 있습니다.


위와 같이 하면 변하지 않는 상품 지급 sp는 한번만 만들어 놓고 검증까지 완료해 놓으면 매번 이벤트 때마다 상품 지급이 정상적으로 되었는지 

검증할 필요가 없어 집니다.

읽어 주셔서 감사합니다.



위 주제 관련 혹은 DB에 관련하여 토의하고 싶으신 내용이 있으시면 댓글 남겨 주세요.^^

요즘 Dremel 8220 을 눈여겨 보고 있습니다. 그러면서 자연스레 많은 액세서리를 보게 되네요.

보면서 정리해 봅니다.


드레멜 액세서리는 종류에 따라 생각으로 구분되는데, 절단 액세서리는 붉은색 으로 표시 됩니다.

절단 비트별 사용처는 아래와 같습니다. 

최저가 금액은 

560 : 4,000 원     /     561 : 6,000 원     /     562 : 15,200 원     /     569: 17,300 원     /     570: 17,300 원  

정도 입니다



'기타 > 공구' 카테고리의 다른 글

[DeWalt] 퀵 체인지 드릴 드라이버  (0) 2023.03.12
Dewalt (디월트) 클램프 규격표  (0) 2020.07.18

DMV(동적관리뷰) 중 dm_exec_query_stats 에 대해서 알아 보겠습니다.


MSDN의 설명을 빌리자면   https://msdn.microsoft.com/ko-kr/library/ms189741.aspx


SQL Server에서 캐시된 쿼리 계획에 대한 집계 성능 통계를 반환합니다. 이 뷰에는 캐시된 계획 내의 쿼리 문당 하나의 행이 포함되어 있습니다. 


라고 설명 되어 있습니다. 


이 중 '캐시된 계획 내의 쿼리 문당 하나의 행' 에 대하여 테스트를 진행하였습니다.



테스트에 쓰인 SP 입니다. 

입력 변수의 값에 따라 총 3가지의 실행 계획이 생성 됩니다.

1번 IF 문만 실행,  2번 IF 문만 실행,   3번 IF 문만 실행



실행 계획이 3개가 생기니

뷰의 ROW로 실행에 맞춰 3개의 ROW가 생성 되었습니다.




자세한 내용은 아래 동영상을 참고해 주시길 바랍니다. 




오늘은 우연히 알게된  DB#5의 리버스 가능을 사용하여

MSSQL DB 스키마를  ORACLE 스키마로 변경해 보겠습니다.


변경하고자 하는 DB의 물리 모델을 생성 합니다.



리버스를 통하여 대상 MSSQL DB를 리버스 합니다.




VARCHAR 는 VARCHAR2로 변경된것을 확인할 수 있습니다.


아래는 시연 동영상 입니다.



베타 테스트 중인 DA#5 를 이용하여 MSSQL 을 리버스 하고 변경된 내용을 스크립트를 생성하여 DB에 적용해 보았습니다.



DA#5는 많은 종류의 DB에 대하여 리버스를 실행할 수 있습니다.

ORACLE, SQLSERVER, MYSQL, SYBASEASE, SYBASEIQ, INFORMIX, DB2, CUBRID 등등 - 만물상이 따로 없네요 .


리버스 옵션에서 인상적인건 '코멘트로 엔터티명 지정', '코멘트로 속성명 지정' 기능을 사용하면  논리 물리 모델을 충실하게 관리할 수 있겠습니다.


          아래는 리버스 및 스크립트 생성을 동영상으로 제작해 보았습니다.




      

       DA#5 인상적이고 편리한 기능들 도 많이 있는데, 


       버전 5까지 온 지금에 와서도 아직 사용에 거칠거칠 함이 있는 이유가 


       사용을 망설여지게 합니다. - 저만 그렇게 느끼는걸 까요 ?

       

       좋은 기능이 참 많은데, 쓰는건 좀 불변하고...

MSSQL에서 mdf 파일만 가지고 DB을 생성할 수 있습니다.


하지만 이상하게 운영체제 오류, 오류:5120 오류가 발생 하는데, 설명은 부실하고, 몇번을 해봐도 똑같습니다.


해결 방법은 아주 간단 합니다. Ssms.exe Management Studio 응용프로그램을 관리자 권한으로 실행 시켜 주고


연결을 수행하면, 아~무~런 오류 없이 DB가 연결 됩니다.




모델링의 기본이 되는 도메인 사전의 작성을 위해서 DA#은 먼저 표준 단어를 등록해야 합니다. 


표준 단어를 바탕으로 표준 용어를 등록할 수 있기 때문 입니다.(이 부분이 쉬운 작업을 어렵게 만드는 요인 이기도 합니다.)


앞 강좌 에서는 적은 수의 용어를 등록 했지만, 본격적인 프로젝트에서는 보통 200개 이상의 용어를 사용하기에 일일이 등록 하기는 


효율이 떨어 집니다. 


그래서 오늘은 엑셀 파일로 표준 단어를 작성하고 DA#으로 불러들이는 방법을 설명하겠습니다.


---------------------------------------------


동영 상으로 대체 합니다.-----------------------


--------------------------------------------




저의 초간단 설계방법은 아래와 같습니다. 


1. 도메인(용어) 사전을 엑셀로 작성 합니다.

: 일단 어떤 업무 형태이 DB를 설계하는지에 대한 바향이 결정되면, 해당 업무에 필요한 속성들을 엑셀로 정리 합니다.

2. 도메인 사전 엑셀파일을 ERD툴에 입력 합니다.

3. 업무 흐름에 맞게 테이블을 생성하고 도메인을 테이블에 Drag & Drop 합니다.

4. 정규화를 진행 합니다. 

5. 관계선을 그립니다.

6. 진행에 맞춰 테이블을 수정해 갑니다.


오늘은 DA#을 이용하여 초 간단 DB 설계에 대해서 설명하겠습니다.


* 먼저 DA#을 실행 합니다 



* 상단의 데이터 / 사전 을 클릭하여 DA Worict 프로그램을 실행 합니다.




* DB연결 을 클릭하고 "AR 데이터베이스 접속" 화면에서 프로그램 설치시 제공되는 샘들 db파일을 연결 합니다. 

 파일명은 아래와 같습니다.




* 표준 분류 체계 관리 버튼을 클릭하고 내가 사용할 새로운 부류체계를 등록 합니다.




*내가 만든 표준분류체게 를 선택 합니다.                                                                                                                                                                                                                                                                                                                                                                                                                        



* 용어 만 테이블의 속성명 으로 사용 가능 합니다.

* 용어는 단어들의 결합으로 이루어 집니다.

* 용어에는 데이터 형이 설정되어 있기 않기 때문에 용어에 도메인을 등록하여 데이터 타입을 설정 합니다. 


* 추후 용어 등록의 편의성을 위해   분류어: 엔터티, 속성 에는 반듯이 체크 표시를 한니다.

* 중복 확인을 완료하고 등록 버튼을 눌러 단어들을 등록 합니다.


* 단어 등록이 완료 되었으면 , 용어등록 버튼을 눌러 용어 등록을 시작 합니다.

* 등록한 용어를 검색명 에 입력 후 검색 버튼을 누르면, 해당 용어를 이루는 최소한의 단어 목록을 표시 합니다.

* 도메인의 조회/추가 버튼을 눌러 적절한 도메인을 등록 및 선택 합니다.



* 알맞은 도메인이 없다면 새로운 도메인을 등록 합니다. 



** 이로서 테이블에 끌어다 놓을 수 있는 용어 사전이 작성 완료 되었습니다.

* DA Wordict을 종료하여 변경 사항을 DB에 반영 합니다.



* 이제 DA ModelerS 프로그램에서 새로운 모델을 등록한 후 AR연결을 수행하고 "분류체계 선택"을 통해 내가 만든 분류 체계를 선택 합니다.



* 엔터티 를 생성한 후 우측의 "표준 관리" 의 용어를 끌어다 엔터티에 추가합니다. 



** 이로서 가장 간단하게 데이블을 생성할수 있는 방법을 설명 드렸습니다.


위 내용에 대하여 동영상으로도 게시하였습니다. 



건의사항 있으시면 언제든 덧글로 알려 주시길 바랍니다. ^^
























엔코아 컨설팅에서 만든 ERD Tool 인 DA# 이 어느덧 5 까지 왔네요.

DA#  의 발자취 입니다. 벌써 12년이나 되었네요. 

제 DBA 인생을 밝혀준 조광원님 께서 계셨던 곳이 엔코아 였기 때문에 호기심으로 출시되자 마자 다운받아 사용해 보았습니다. 

하지만 ER-Win 에 익숙한 저에게는 익숙함을 넘어설 만큼 큰 기능은 없었기에 맛만 보고 스킵.


DA#5의 베타테스터 모집 소식에 냉큼 참가 신청을 하였습니다. -뽑힐줄 몰랐는데..

이 사회자 분을 3번 정도 보는것 같은데 .. 볼때마다 느끼는 거지만 진행을 참~ 조리있게 잘 ~ 합니다.

세미나 자료는 첨부하였으니 살펴 보시면 좋을것 같고,


DA#5 모델링 툴이긴 하지만 기존 ER Win / ER Studio 와 는 방향이 다른 툴이다.

모델링 툴이라고 하기에는 부가적인 기능이 50% 이상을 차지하고 있다.

ER Win / ER Studio가 DA 만을 위한 툴 이라고 한다면, DA#5 는 Database 와 연관된 모든 사람들이 사용할 수 있는 사용하면 좋을 툴 이라고 하겠다.


개인적으로는 너무 많은것을 담으려고 했다는 느낌에 어지럼증이 느껴지도 했지만. 후반부 발표부터 참석자들 로 부터 함성도 들리는걸 보면 

다른 분들은 만족하는 듯 하다.

전체적으로 기능들을 서열정리 좀 하고 배치좀 바꾸고 , 그렇게 정리만 조금 하면 꽤 괜찮은 툴이 될것 같기는 하다.


요건 세미나 끝나고 선물로 받은 마우스+키보드 셋 , 점심도 챙겨줬으나 세미나 후반부에 밀려온 멀미 때문에 식사는 패스

엔코아에서 주최하는 세미나에 가끔 참가 하는데, 매 행사마다 아끼지 않고 준비해주는 모습이 매번 다시 참석하게 만든다.


마지막으로 ... DA# 개발팀에게 바라는게 있다면, 더이상의 기능 추가는 당분간은 없었으면 한다.

물론 기능추가의 장본인이 개발팀은 아니고 .. [옹] 님 이겠지만. 

얼마전 면접을 보다가, 아래 그림과 같은 데이터 구조에서의 탐색 방법에 대한 DB 설계 및 쿼리 작성을 하시오 라는 질문에

최적의 답변을 하지 못해. 집에 와서 테스트 하였다.

 

질문의 핵심은 특정 node 를 선택했을때, 최상위 부모까지 올라가는 흐름을 한줄로 표현하는 것이었다.

 

ex) 그림20 > 그림17 > 그림13 > 그림10 > 그림9 > 그림3 > 그림1

 

데이터의 구조는 아래와 같다.


테이블로 옮기면,


일반적인 재귀호출 용 테이블의 구조가 된다. 여기에 아래 쿼리를 실행하면 


1
2
3
4
5
6
7
8
9
set @id := 26;        -- node id
set @L := 0;
 
 
SELECT @r AS _ID
    , (SELECT @r := pid FROM t_test WHERE id = _ID) AS _PARENT_ID
    , (@L := @L + 1) AS level
FROM ( SELECT @r := @id) AS vars, (SELECT * FROM t_test WHERE id < @id) AS h
WHERE @r <> 0;
cs


그림과 같이 우리가 원하는 결과를 얻을 수 있다.

약간만 수정하면 두루 두루 쓸모가 많을것 같다.

이래서 실무자 면접은 참 재미있는것 같다. 내 실력을 평가받는 자리도 되고 그로인해 공부도 되고.




---------------------------------------------------------- ID , PID 가 문자형인경우 ----------------------------------------------------------

ID , PID 문자형일 경우 어떻게 수정해야 하는지에 대한 문의가 있어 관련 내용 공유 드립니다.

위 데이터에서 각 컬럼을 문자형으로 변경 후 앞에 a를 붙여 a1, a2, a3 형식으로 변경 하였습니다.


1
2
3
4
5
6
7
8
9
set @id := 'a26';         -- node id
set @L := 0;              -- level 컬럼의 시작 값, 0 입력시 1부터 1씩 증가된 값이 표시 됨
 
SELECT @r AS _ID
    , (SELECT @r := pid FROM t_test WHERE id = @r limit 1) AS _PARENT_ID
    , (@L := @L + 1) AS level
FROM ( SELECT @r := @id) AS vars, (SELECT * FROM t_test WHERE id != @id) AS h
WHERE @r <> 'a0';          -- > root node를 만나면 탐색을 중지하기 위함
-- WHERE @r <> '-';        -- > null 이 아닌 임이의 값 (예 : '-') 입력
cs


출력 결과 : 


MSSQL 로 구현하면 >> https://devse.tistory.com/69



2015년 AD Mob과 같은 광고 솔루션을 개발하면서 유여곡절 끝에 수행한 테스트 입니다.


서버 및 DB 개발이 완료되고 급하게 실제 모바일 게임(1000만 다운로드)에서 테스트를 겸하여 적용한 시점부터

Node.js 가 하수들 이나 쓰는 허접한 기술 이라며  까기 시작했고 Node.js 가 현재 우리의 급 에서는 적정 기술임을

어필 하였지만 결국 들어먹지는 아니하였다.

그 와중에 Node.js 의 고성능을 확인시켜 주기 위해 실제 환경에서 테스트를 진행 하였다.


구조는 아래와 같다.

본인은 테스트를 진행할 때 서버 상태정보와 DB 상태정보 등을 동영상으로 촬영하여 분석 및 보관하는것을 좋아한다.

두고 두고 보면서 각 서버들의 상태를 비교하여 병목지점을 찾는것에도 유용하게 쓰인다.


https://www.microsoft.com/ko-kr/download/details.aspx?id=42299  << 로그인 없이 다운로드 가능

구글이나 네이버에서 검색하면 대부분 로그인을 해야하는 곳으로 안내한다. 



SQLEXPRADV 라고 되어있는 것이 Management Studio  가 함께 설치되는 파일이다. 

https://www.microsoft.com/ko-kr/download/details.aspx?id=42299  다운로그 경로 다시한번.


삭제시 에는


Microsoft SQL Server 2014(64비트) 를 클릭하여 삭제를 진행 합니다.




mysql 5.6 이후 버전에서는 셀이나 커맨드 라인에서 계정정보를 그대로 노출하면 경고가 발생한다.


Waring: Using a password on the command line interface can be insecure.




작업은 성공하니 문제는 없으나  나중 버전에서는 -p 옵션을 사용할 수 없다는 얘기도 있으니..

그걸 제외 하더라도 스크립트에 계정 정보를 모두가 볼수 있게 적어주는건 좋지 않기 때문에 (보안만 확실하면 큰 문제는 되지 않지만.. 어찌되었건..)

mysql_config_editor 를 사용하여 로그인파일을 생성해 놓고 설정명만을 명시하여 사용할 수 있다.

구문도 짧아지니 이것도 이점이라 할수 있겠다.


ex-1) # mysql_config_editor set --login-path=[접속명칭] --host=[host 정보] --user=[계정명] --password --socket=/tmp/mysql.sock --port=3306

ex-2) # mysql_config_editor set --login-path=[접속명칭] --host=[host 정보] --user=[계정명] --password --port=3306

대부분의 블로그 에서는 ex-1 로 소개하고 있으나 ex-2 처럼 작성 하여도 특별한 문제는 없어 보인다. 

(오늘 처음 써봤고, --socket 옵션에 대해서 특별한 설명은 못 찾겠다 꾀꼬리~)


등록이 완료되면 계정 폴더에 .mylogin.cnf 파일이 생성된다.

열어봐야 읽을수도 없으니 아래 이미지를 보고 궁금증만 푸시길 바란다.

 참고: # chmod 666 .mylogin.cnf 로 권한정보를 수정하게 되면 mysql --login-path=dump_usr 했을때 오류가 발생한다.

        이런 궁금증은 제가 풀어 드릴테니 괜한 시간 낭비는 하지 않기를 바랍니다.


등록 내역을 보고 싶을때는 # mysql_config_editor print --all


mysql 에 접속               # mysql --login-path=dump_usr

특정 접속 정보만 삭제   # mysql_config_editor remove --login-path=dump_usr

전체 정보를 삭제           # mysql_config_editor remove 


이상 궁금증을 해결하다보니 .. 내용이 길어 졌습니다. 이해하고 넘어가 주세요

MySQL 의 binary_log 를 분석하기 위해  more / cat 등으로 열어 보면 글자가 깨져서 표시됩니다.

정상적으로 읽기 위해서는 변환 작업이 필요합니다.

- 로그파일 전체를 변환             : #mysqlbinlog [log 파일명] > [파일명].sql

- 특정 기간의 로그내용만 변환  : 

     #mysqlbinlog --start-datetime='2016-03-01 00:00:00' --stop-datetime='2016-03-21 23:59:59' [log 파일명]  > [파일명].sql

- 특정 형식의 쿼리 내용만 변환 : 

     #mysqlbinlog [log 파일명] | grep -i -e "^create" -e "^update" | more      // 콘솔로 출력

     #mysqlbinlog [log 파일명] | grep -i -e "^create" -e "^update"  >   [파일명].sql   // 파일로 출력

   * 기타 다양한 조건을 적용할 수 있다 (구글신께 물어 보세요)


하지만 변환 중 아래와 같이 오류가 발생하는 경우가 있습니다.

              -원인은 mysqlbinlog 가 실행될 때 /etc/my.cnf 파일을 읽어 들이는데 mysqlbinlog가  default-character-set 설정을 

                인식할 수 없어 발생한다.

                해결책은 my.cnf 파일에서 [client] 섹션에 있는 default-character-set = utf8 을 주석처리 후 mysqlbinlog 명령을 실행한다.

                작업이 완료된 후 my.cnf 의 default-character-set의 주석은 해제 한다. 

                                 (일부 블로그에서는 mysql을 재 시작하라고 하는데 그럴 필요는 없다.)

                 my.cnf 는 mysql 이 구동시 한번만 읽기 때문에 중간에 변경을 하여도 현재 서비스에는 영향이 없다.

                 mysqlbinlog 또한 구동시에 my.cnf 읽는다.




mysql 에서 분석을 위해 Slow Query log 파일을 초기화 해야할 필요가 있을 때 mysql 을 재시작 하지 않고 초기화 할 수 있는 방법이다.


1. 로그를 다른 이름으로 복사

~]# cp slow.log 20160315.slow.log

2. 원본 로그 파일의 내용을 초기화 한다.

~]# cat /dev/null > slow.log


mysql 서버의 재시작 없이 log 파일의 내용을 초기화 할 수 있다.



Mac 용 PowerPoint 및 Word의 탭 사이즈가 기본 4 가 아니라 불편함이 많다. Word 보다는 PowerPoint의 탭 사이즈가 더 크다.

변경방법: 우클릭 > 단락 > 탭.... (맨 하단) > "기본 위치" 변경 및 저장 

하지만 새로운 문서를 열면 다시 탭 크기는 초기화 된다. 패키지 파일을 수정하면  바꿀수도 있을것 같은데 시도는 엄두가 안난다.


왼쪽이 기본 탭 사이즈 ,  오른쪽이 변경된 탭 사이즈


위 이미지는 Word에서 찍은것이며 PowerPoint 도 변경 방법은 동일하다.




mysql 실행 계획을 어떻게 분석해야 하는지에 대한 정리 입니다. 

PDF 파일도 첨부 합니다. 

실행 계획을 출력하는방법은 

EXPLAIN

SELECT * FROM t_table WHERE col='val';

입니다.



윈도우 환경에서 맥 환경으로 변경 하면서 기존에 쓰던 기계식 키보드(저렴한, GO187 LED)가 불필요해 졌다.

일반적인 맥 키보드를 사용해 보았으나 풀배열 키보드 이니 불편하기도 하고 , 집에서 놀고 있는 기계식 키보드가 아깝기도 하고 맥용 기계식 키보드를 새로

구매 하기에는 비용도 부담이 되어 자판 배열을 바꿔서 사용하기로 마음 먹었다.

 

-       맥과 윈도우 의 키보드 키배열 비교


윈도용 키보드를 맥에 꼽으면 Win = Command, Alt = Alt, Ctrl = Ctrl로 설정된다.

이중 윈도용 키보드에서 좌/우 측의 WinAlt키의 위치만 바꾸어 주면 윈도우용 기계식 키보드를 맥에서 사용하는것에 전혀 불편함이 없다.

 

그러기 위해서 다음과 같은 몇가지의 방법이 있다.

1.    Mac 응용프로그램인 Karabiner를 사용한 방법

-       장점: 프로그램에서 설정만 하면 바로 적용된다.

-       단점: 맥용 기계식 키보드를 연결하면 윈도우 윈도우 키위치로 변경이 되는 식이다.

     노트북 사용자라면 정말 비추

2.    기계식 키보드가 게이밍용 이거나, 모든 키를 사용자 설정할 수 있는 프로그램이 적용된다면 해당 프로그램에서 키 위치를 변경후 키보드에 설정을 저정하는 방법

-       장점: 편하다.

-       단점: 해당 기능이 있는 키보드만 가능하다. Win 키는 다른 키로 설정 변경이 불가능 하다.


3.    키보드의 패턴을 변경하다.

-       장점: 맥북 의 자체 키보드와 본 기계식 키보드를 동시에 연결하여 사용할 수 있다.

-       단점: 작업이 어렵다.

이중 3번 방법의 장점은 본인이 해결할 수 있기에 3번 방법을 사용하기로 했다.

 

l  개조 절차

1.    키보드 준비 : 한성 GO187 LED 기계식 키보드

        -       윈도우 환경에서 맥 환경으로 변화하면서 가지고 있던 2개중 하나는 지인에거 선물하고 나머지 하나로 개조를 시도했다. 이미 키 스위치 하나가 망가져 

               있어서 가벼운 마음으로 개조 시도

2.    바꿀 키의 위치와 자를 패턴 및 위치를 선택 한다.

        -       4군대의 패턴을 절단 한다. 주변의 패턴이 손상되지 않도록 조심히 작업한다.

작업 후 테스터키로 도통테스트를 실시하여 절단 결과를 확인한다.


3.    키의 위치가 바뀌도록 패턴을 새로 연결한다.

-       노란색 과 초록색 패턴쪽을 사포로 갈아 납이 묻을 수 있도록 작업한다.

-       각 색의 선들끼리 래핑 와이어로 땜질한다.

 

4.    모든 작업이 완료 되었으니 조립 후 테스트를 진행한다.

 

본인은 2번 방법과 3번 방법을 혼용 하였다.

이상 3일정도 사용해 본 결과 아주 편하게 잘 사용하고 있다.


집에 AS가 지난 기계식 키보드가 있다면 혹은 인두기가 있다면 저렴한 기계식 키보드를 구매하여 도전해 보시길 바란다.


mysqldump 로 DB 및 프로시저 백업시 백업 파일에는 주석이 정상적으로 입력되어 있는데 복원시 주석이 제거된다.


복원시 다음과 같이 옵션을 주고 복원하게 되면 주석도 정상적으로 복원 된다. 


mysql -uroot -p -c < dumpfile.sql

OR

mysql -uroot -p --comments < dumpfile.sql



MySQL 의 꽤 괜찮은 Cluster인 Galera Cluster의 테스트 보고서 입니다.


장비사양: MacBook Pro (Retina, 15-inch, Mid 2014), 프로세스:2.5 GHz Intel Core i7, 메모리: 16GB 1600 MHz DDR3

Virtual Box 로 Linux 2대를 구성하여 MySQL Galera Cluster 를 구성하였습니다.

편의상 Master(최초 Cluster 의 Group을 생성하는 머신, service mysql start --wsrep-new-cluster 로 구동) 가 되는 서버를 galera1 이라 하겠습니다.

다른 하나는 galera2 라고 하고요.


테스트 상황:

1. Galera1 / Galera2 가 동작중인 상황에서 Galera2에 장애 발생  >>  Galera1 에서 Insert 발생  >> Galera2 에서 service mysql start 실행

위 그림과 같이 오류 발생 하지만 다시한번  service mysql start 를 하게되면 정상적으로 접속이 가능하다.

만약 이렇게 해도 해결되지 않으면  cd /var/lib/mysql 로 MySQL 데이터 폴더로 가서 rm -f galera.cache ib_* 하여 총 3개의 파일을 삭제 해준 후

Linux를 Reboot 하고 다시한번 mysql 서비스를 실행해 준다.


2. Galera1 / Galera2 가 동작중인 상황에서 Galera1 에 장애 발생  >>  Galera2 에서 Insert 발생  >> Galera1 을 실행

  Galera1 을 재구동 할때는 Galera1이 Master 였다고 하여   service mysql start --wsrep-new-cluster 로 실행하면 않된다.

  만약 위와 같이 실행하게 되면 Galera1이 새로운 Cluster Group을 생성하게 된다.

  이런 경우 Galera1 에서 service mysql start 로 서비스를 실행하게 되면 Galera2 의 Cluster Group에 들어가게 되고 데이터 동기화도 수행 된다.


내 노트북이 좋아서 인지는 모르겠지만 예전에 사용해본 NDB Cluster에 비해서 성능, 장애처리 부분에서 Galera Cluster가 월등히 좋은것 같다.


다만 한가지 약간의 문제점이라면 ... Auto Increment Column 이 있는 테이블에서 Insert 작업이 이루어질 경우

Galera1 은 1,3,5,7,9 로 Insert가 되고 Galera2에서는 2,4,6,8,10 순으로 증가가 된다. 

예로 Galera1 에서 3건을 insert 하면 1,3,5 가 되고 후에 Galera2 에서 2건을 insert 하면 6,8이 된다.

해보진 않았지만 Node가 3개라면.. 각각의 Node 는 3씩 증가시키는 것으로 알고 있다.


이것은 Auto Increment 의 값을 동기화 시키느라 발생하는 Lock 및 성능저하 문제를 해결하기 위한 Galera만의 방법이고

내 기억으로 NDB Cluster 에서는 Auto Increment Column 에서 값이 비는 경우는 없었던 것으로 알고있다.



DB와 연관되는 프로젝트를 성공적으로 진행하려면 Test Data의 양과 질이 절대적으로 좋아야 한다.

그래야만 개발 단계에서 많은 문제를 찾아낼 수 있고 수정할 수 있게 된다.

하지만 현실은 가가가,나나나,다다다,~~~  형식의 그것도 대략 100건 안쪽의 Test Data 만 넣어놓은 상태에서 개발을 진행하는 경우가 흔하다.

그러다 보니 실제 서비스 하는 환경에서는 Data 가 쌓이면서 Query 시간이 길어지고 Data가 오염되면서 각종 문제가 발생하게 된다.

그것을 줄여 보고자 이 글을 쓴다.

아래의 방법은 가장 일반적인 방법이며 응용을 통하여 더 다양하고 많은 양의 Test Data를 만들어 낼수가 있다.

1. 복제의 대상이 되는 기준 집합을 선택 – MySQL 버전에 따라서 아래 3개중 1개의 집합을 사용할 수 있음

 SELECT count(*) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES;       #기준집합 277 Row , MySQL 5.6 이하

 SELECT count(*) FROM performance_schema.global_variables;                    #기준집합:486 Row , MySQL 5.7 이상


2. 단순 집합 복제 예 – 1 ~  40000 까지의  1개 Column 을 갖는 집합 생성


SELECT @rownum := @rownum +1 AS NUM

FROM (select 1 from performance_schema.global_variables limit 200) as A,

             (select 1 from performance_schema.global_variables limit 200) as B,

             (select @rownum := 0) as tmp

LIMIT 100000;                                                                                              #4만 Row로 복제 (200 * 200)

<수행시간: 40000 row(s) returned  0.0011 sec / 0.0060 sec(Duration / Fetch Time)>


◈ MariaDB 의 경우 performance_schema 환경 변수가 off 되어 있으면 performance_schema.global_variables 테이블에 접근할 수 없습니다.

   INFORMATION_SCHEMA.GLOBAL_VARIABLES 테이블을 사용해 주시길 바랍니다.

결과 집합: 


3. 4만개의 겹치지 않는 12자리 코드 집합을 생성하는 쿼리

SELECT CONCAT(

        SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@rownum)*4294967296))*36+1, 1)

       ,SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1)

       ,SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1)

       ,SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1)

       ,SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1)

       ,SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1)

       ,SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1)

       ,SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1)

       ,SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1)

       ,SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1)

       ,SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1)

       ,SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed)*36+1, 1)) AS RAND_CD

       ,@rownum := @rownum +1 AS NUM

FROM (SELECT 1 FROM performance_schema.global_variables LIMIT 200) as A

            ,(SELECT 1 FROM performance_schema.global_variables LIMIT 200) as B

WHERE (@rownum:=0)=0

LIMIT 100000; 

<수행시간: 40000 row(s) returned  0.0035 sec / 0.131 sec (Duration / Fetch Time)>

결과 집합: 


Insert Query에 위의 결과 집합만 적용해 주면 몇십만건의 Data도  바로 생성해 넣을 수 있다.

PHP 로 개발을 하면서 DB관련 작업을 컴포넌트(cakephp3)를 사용해서 하게되면

테이블 생성시 자동으로 모든 테이블에 Autoincrement 인 컬럼을 PK로 테이블을 생성하게 된다.

그럴경우 구조가 아주 엉망이다...


그럴경우에 유용하게 사용할 수 있는 쿼리 이다.


CREATE TABLE `t_test` ( 

    `idx` int(10) unsigned zerofill NOT NULL AUTO_INCREMENT, 

    `name` varchar(40) NOT NULL COMMENT '코멘트', 

PRIMARY KEY (`idx`)) ENGINE=InnoDB DEFAULT CHARSET=euckr;


쿼리 구조 : REPLACE INTO DB.t_test VALUES([id],[값])

- AutoIncrement 의 자동 증가와는 별도로 값을 입력 수정 할수 있다.  순차적으로 증가하던 ID 값을 몇단계 건너뛰고 지정할 수 있다.


아래는 퀴리 수행시 Table의 변경 사항을 보여준다.




# 계정 정보 확인

--MySQL 5.6 이하

SELECT user,host,password FROM mysql.user;

-- MySQL 5.7 이상

SELECT user,host,authentication_string FROM mysql.user;

* password 라는 Column 이 authentication_string 으로 명칭이 변경 되었다.


#패스워드 변경

-- MySQL 5.6 이하

UPDATE mysql.user SET password = PASSWORD('패스워드') WHERE user = '계정명' AND host = 'host명';

FLUSH PRIVILEGES;

-- MySQL 5.7 이상

SET PASSWORD FOR '계정명'@'host명' = PASSWORD('패스워드');

FLUSH PRIVILEGES;


#계정 등록 및 권한 설정 (모든 버전 동일)

GRANT ALL PRIVILEGES ON *.* TO '계정명'@'host명' IDENTIFIED BY '패스워드'; 

FLUSH PRIVILEGES;



Node.js에서 사용하던 가중치 적용 함수를 SQL Query로 구현 보았습니다.

결론은 로직으로 구현하는것 보다는 Query로 구현하는것이 간단하다 입니다.


------ 테이블 ------ 

t_item 

 

t_weight 

 item_cd

 item_nm

weight 

 weight

a

 장미

2

 1

b

 튤립

5

 2

c

 백합

8

 2

d

 호박꽃

3

 3

e

 무궁화

9

 3


 3

 4

 4

 4

 4


****************** 가중치 함수 - Node.js 구현 ******************

rows1[] = SELECT * FROM t_item 집합

var rownum = weightcheck(rows1[0]); //가중치로 선택된 Row의 번호 Get

var selrow = rows1[0][rownum]; //가중치로 선택된 Row Value


/** -----------------------------------------------------------------

 * 가중치 계산, 배열의 크기를 작게하기 위하여 weight 은 1~9 까지만 사용

 ----------------------------------------------------------------- */

function weightcheck(rows){

var point = 0; //가중치

var beforePoint = 0; //이전 가중치

var totalweightn = totalweigh(rows,'weight');             //가중치 Column

var ran = Math.floor((Math.random() * totalweightn)+1);   //1~가중치총합 사이의 랜덤한수

var i = 0;



//직전 가중치 + 현재 row의 가중치는 Band

for(i=0;i < rows.length;i++){

point = beforePoint + rows[i].adweight; 

if(ran > beforePoint && ran <= point ){

break;

};

beforePoint = point; //현재 위치를 이전 위치로 저장 합니다.

};

return i;

};

/** -----------------------------------------------------------------

 * 총 가중치 계산 (배열,가중치값 이름)

 ------------------------------------------------------------------- */

function totalweigh(list,weightnm){

var total=0; //총 가중치

for(var i = 0;i < list.length;i++){

total = total + list[i].adweight;

}

return total;

};


****************** 가중치 계산 - Query 로 구현 ******************

SELECT C.*

FROM (

SELECT A.* FROM t_item as A INNER JOIN t_weight as B

ON A.weight = B.weight                                       //가중치 숫자만큼 Row 복제

) as C

ORDER BY rand() LIMIT 1;                                         //복제된 Row 중 랜덤하게 하나의 Row를 반환



Node.js 에서 코드로 처리하는 것 보다 RDB에서 처리하는것이 더 깔끔합니다.


안드로이드용 바로가기APP https://goo.gl/LjcQgi -- 바로가기G




'Node.js' 카테고리의 다른 글

Node.js Windows 10 에서 jsdom 3 설치 오류 해결  (0) 2015.09.05
node.js로 GooglePlay Crawling  (0) 2015.08.31
시작합니다  (0) 2015.08.07


개발시 문자열을 조작할 일이 많아 제작 하였습니다


사용처:

- 데이터 값으로 대량 Insert Query 생성

- 트래커 작업(중복 트래커 제거)

- 텍스트 로그에서 IP,시간 만 추출


 


개발언어: C#, .Net Framework 3.5 이상 필요


기타 건의사항 있으시면 댓글로 남겨 주세요.

요구 사항을 자세히 적어 주시면 빠르게 반영토록 하겠습니다.

TRT-Control.exe

command.json

Text_Formatter.zip

text_formatter.jar


-- 프로그램 화면





www.dbguide.net 의 DA가이드 페이지들을 PDF로 변환해 보았습니다.

출력해서 시험 전날 요약본으로 봐야겠습니다.


DA가이드-1_전사아키텍처 이해.pdf


DA가이드-2_데이터 요건 분석.pdf


DA가이드-3_데이터 표준화.pdf


DA가이드-4_데이터 모델링.pdf


DA가이드-5_DB설계와 이용.pdf


DA가이드-6_데이터 품질관리 이해.pdf


바로가기 앱: https://play.google.com/store/apps/details?id=com.orengineer.android.a209.floatingshotcut

[세미나] 최적 데이터 구조 설계

목차: 

1강현행 데이터 모델 구축 전략 [1] 46분 
2강현행 데이터 모델 구축 전략 [2] 56분 
3강최적 파티션 설계 및 운영기법 사례 [1] 41분 
4강최적 파티션 설계 및 운영기법 사례 [2] 45분 
5강최적 데이터 구조 설계 1편 [1] 60분 
6강최적 데이터 구조 설계 1편 [2] 52분 
7강최적의 대용량 데이터 처리 기법 및 사례 [1] 39분 
8강최적의 대용량 데이처 처리 기법 및 사례 [2] 42분 
9강최적 데이터 구조 설계 2편 [1] 54분 
10강최적 데이터 구조 설계 2편 [2] 60분 
11강최적 인덱스 설계 기법 [1] 40분 
12강최적 인덱스 설계 기법 [2] 42분 
13강최적 데이터 구조 설계 3편 [1] 57분 
14강최적 데이터 구조 설계 3편 [2] 61분 
15강최적 인덱스 활용 사례 [1] 38분 
16강최적 인덱스 활용 사례 [2] 43분 



http://cyber.dbguide.net 사이트에서 회원 가입후 무료로 시청 가능한 자료 입니다.

개인적으로 스마트폰에 넣어 가지고 다니면서 틈틈히 보는걸 좋아해 다운받았다가.

공유하게 되었습니다.


아래 링크 통해서 바로 보거나 다운 받으실 수 있습니다.

https://drive.google.com/folderview?id=0BzfE8slPbOvbaWZ2cTRYY0xuMlk&usp=sharing



바로가기 앱: https://play.google.com/store/apps/details?id=com.orengineer.android.a209.floatingshotcut

VirtualBox에 Centos를 설치하여 설정을 모두 잡고 로드밸런스 및 기타 테스트를 위하여 가상 머신을 복제 하였다.



- 스냅샷 항목의 가상머신 복제 사용


위와 같이 복제한 후 복제된 OS의 MAC Address를 변경하면 eth0이 활성화 되지 않는다.

#ifconfig -a 하면 eth1 이나 eth2가 표시된다.

그럴경우 다음과 같이한다.

1. # vi /etc/sysconfig/network-scripts/ifcfg-eth0

   ifcfg-eth0 에서 HWADDR="" 부분의 기존 주소를 지우고 새로 변경된 주소를 입력한다.

  * MAC 주소는  설정/네트워크 에서 확인 가능하다.

2. # rm -f /etc/udev/rules.d/70-persistent-net.rules      //해당 파일 삭제

3. # reboot                                                                //재부팅


그럼 정상적으로 eth0 이 활성화 되며 네트워크가 동작한다.


바로가기 앱: https://play.google.com/store/apps/details?id=com.orengineer.android.a209.floatingshotcut



Windows 10 에 Node.js 설치 후 jsdom 3 버전을 설치중 아래와 같은 오류가 발생

>npm install jsdom@3

https://www.visualstudio.com/ko-kr/products/visual-studio-express-vs

 - 필자는 위 링크의 Visual-studio-express를 설치하여 위 오류를 해결하였다. 어차피 C# 도 하니 겸사 겸사 깔았다.


https://www.microsoft.com/ko-kr/download/details.aspx?id=40784

위 재배포 가능 패키지를 설치해도 될것같기는 하다. 하지만 테스트는 못함


바로가기 앱: https://play.google.com/store/apps/details?id=com.orengineer.android.a209.floatingshotcut



'Node.js' 카테고리의 다른 글

가중치 구현 (DB,Node.js)  (0) 2015.10.23
node.js로 GooglePlay Crawling  (0) 2015.08.31
시작합니다  (0) 2015.08.07

node.js를 이용하 구글플레이 Crawling 방법 입니다.


Crawling을 위해서는 jsdom 이라는 모듈이 필요하며 설치 위치는 https://github.com/tmpvar/jsdom/tree/3.x 입니다.

(node.js에는 jsdom 3.x 버전만 설치 사용 가능 합니다.)


아래는 실제 코드 이며 사용법은 주석으로 되어 있습니다.


var jsdom = require('jsdom');

// ------ 중략 -----

app.get('/marketSeh',function(req,res){

var url_parts = url.parse(req.url,true);
var query = url_parts.query;
var gm_url;

gm_url = 'https://play.google.com/store/search?c=apps&q=' + escape(query.appname);
console.log(gm_url);

jsdom.env({
url:gm_url,
scripts: ['http://code.jquery.com/jquery.js'],
done: function (err, window) {           //페이지 호출이 완료되면 CallBack
var $ = window.jQuery;
var cards = $('.card-list .card'); //"card"로 시작하는 클래스를 포함하는 "card-list" 클래스 집합

// "." 은 클래스명 검색임을 "."이 없으면 태그명 검색임을 표시

var cardlen = cards.length;
var retvalue = []; //리턴값
var ii;

if(cardlen == 0){
res.json([{cover:'',title:'',subtitle:'',link:''}]);
return;
}

$.each(cards,function(i,card){        //세부 클래스들을 검색
var $card = $(this);
var _cover = $card.find('.cover-image').attr('src'); //이미지 url
var _title = $card.find('.title').attr('title'); //타이틀
var _subtitle = $card.find('.subtitle').text(); //서브타이틀
var _link = $card.find('h2 a').attr('href'); //링크
++i;
ii = i;


var obj = {cover:_cover.trim(),title:_title.trim(),subtitle:_subtitle.trim(),link:_link.trim() };

retvalue.push(obj);
});

if(cardlen = ii){
res.json(retvalue);
};
}
})

});


바로가기 앱: https://play.google.com/store/apps/details?id=com.orengineer.android.a209.floatingshotcut

'Node.js' 카테고리의 다른 글

가중치 구현 (DB,Node.js)  (0) 2015.10.23
Node.js Windows 10 에서 jsdom 3 설치 오류 해결  (0) 2015.09.05
시작합니다  (0) 2015.08.07

+ Recent posts