몽고디비를 기반으로 개발하다보면 가끔씩 정상적으로 프로세스가 종료되지 않았을때

mongod 명령어가 실행되지 않을때가 있다.


이때는 몽고디비 콘솔에 접속하여 어드민으로 스위칭하고 종료하면 된다.


  1. $ mongo
  2. $ use admin
  3. $ db.shutdownServer()




'DataBase > MongoDB' 카테고리의 다른 글

몽고디비 종료 (already process port 27017)  (0) 2018.07.11

알아두면 매우 유용


  1. Tools
  2. Names
    1. Model Naming Options...


'DataBase' 카테고리의 다른 글

[ERWIN] 오브젝트및 속성 명 일괄적으로 대/소문자 변경  (1) 2018.05.10
[ER-WIN] Names Option  (0) 2016.10.25
memsql  (0) 2013.12.30
FreeSQLFormatter [SQL정렬]  (0) 2012.02.13
NoSQL  (0) 2011.01.14
ERStudio  (0) 2010.08.24
  1. 2018.05.30 17:20

    비밀댓글입니다

MySQL root 패스워드 분실



CentOS 기준


Error Messages

  • Job for mariadb.service failed because the control process exited with error code. See "systemctl status mariadb.service" and "journalctl -xe" for details.
  • Aria engine is not enabled or did not start. The Aria engine must be enabled to continue as mysqld was configured with --with-aria-tmp-tables
위 에러 내용중 하나가 발생하면서, MariaDB 가 기동이 안된다면 다음과 같이 처리한다.


$ systemctl status mariadb

치면  위 메세지중 2번째 메세지를 표시하고 있을것이다.


이제 아래 내용들을 순서대로 처리하면 된다.


1. aria_log_control 파일을 유저경로로 옮기고 삭제.

$ cd /var/lib/mysql
$ mv aria_log_control ~/

2. ib_log 파일들도 동일하게 유저경로로 옮기고 삭제

$ cd /var/lib/mysql
$ mv ib_logfile0 ~/
$ mv ib_logfile1 ~/

$ cd ~/
$ rm ./ib_logfile0 ib_logfile1

3. 위와 같이 완료됬다면

$ systemctl enable mariadb
$ systemctl start mariadb

 

쓰면서 처음 보는 에러 발생;;;


UPDATE 시에 대상 테이블의 값을 대상 테이블에서 직접 접근하여 조회하여 조건에 사용했을 경우 에러 발생.

UPDATE 에서만 발생하는지는 모르겠음.


정리된 내용은 이러함.

SELECT
*
FROM `TABLE`
WHERE ID = 'JKUN.NET'
AND IDX = ( SELECT MAX_IDX FROM (SELECT MAX(IDX) AS MAX_IDX FROM `TABLE` WHERE ID = 'JKUN.NET') ) _dummy )

오라클에서 통계 관련 쿼리를 작성하다보면,

기간성 정보 기준으로 데이터를 도출해야할 경우가 있다. 예를 들자면 (일간, 월간, 년간)


하지만 영업일이 없었던 경우 0 원으로 표시해야하거나 주말같은 경우는 뭔가 표시를 해주어야 하는데,

이게 필요할 때 찾으면 없거나 보통 귀찮은일이 아님.


해서 테이블부터 데이터 등록 PL/SQL 까지 같이 올림. 그냥 바로 돌리시면 됩니다.^^


CREATE TABLE DATE_STANDARD
(	
  YEAR_ID CHAR(4 BYTE), 
	MONTH_ID CHAR(2 BYTE), 
	DAY_ID CHAR(2 BYTE), 
	DATE_ID VARCHAR2(8 BYTE), 
	WEEK_NO CHAR(1 BYTE), 
	WEEK_TXT VARCHAR2(5 BYTE)
)  

CREATE INDEX IDX_DATE_STANDARD ON DATE_STANDARD (YEAR_ID, MONTH_ID, DAY_ID, DATE_ID) ;
COMMIT;

SET SERVEROUTPUT ON;
DECLARE
  i NUMBER := 1;
  yyyy CHAR(4) := '2019';
  mm CHAR(2);
BEGIN
  
  FOR i IN 1..12 LOOP
  
    mm := TO_CHAR(LPAD(i, 2, 0));
    
    INSERT INTO DATE_STANDARD
    SELECT
      SUBSTR(DS.DATE_ID, 0, 4) AS YEAR_ID,
      SUBSTR(SUBSTR(DS.DATE_ID, -4), 1, 2) AS MONTH_ID,
      SUBSTR(DS.DATE_ID, -2) AS DAY_ID,
      DS.DATE_ID,
      TO_CHAR(TO_DATE(DS.DATE_ID), 'd') AS WEEK_NO,
      DECODE( TO_CHAR(TO_DATE(DS.DATE_ID), 'd') , 1, '일', 2, '월', 3, '화', 4, '수', 5, '목', 6, '금', 7, '토') AS WEEK_TXT    
    FROM (
      SELECT      
        TO_CHAR(TO_DATE(yyyy || mm ||'01', 'YYYYMMDD')+LEVEL - 1, 'YYYYMMDD') AS DATE_ID
      FROM DUAL
      CONNECT BY LEVEL <= (LAST_DAY(TO_DATE(yyyy || mm ||'01', 'YYYYMMDD')) - TO_DATE(yyyy || mm ||'01', 'YYYYMMDD') + 1)
    ) DS;
    
    DBMS_OUTPUT.PUT_LINE(mm || ' 월 데이터 등록 완료');
    
  END LOOP;  
  
  COMMIT;
  
END;

오라클 컬럼을 로우로

SELECT DECODE (MOD (ROWNUM - 1, 3) + 1, 
                 1, SUM_TARGET_SALES_AMT, 
                 2, MALL_TARGET_SALE_AMT, 
                 3, MALL_OUT_CHANNEL_TARGET_SALE_AMT) AS TARGET_SALE_AMT
  FROM (SELECT 1
              FROM DUAL
        CONNECT BY LEVEL <= 3), (
          SELECT                        
            TARGET_VAL            AS SUM_TARGET_SALES_AMT,
            TARGET_CLIENT_TBH     AS MALL_TARGET_SALE_AMT,
            TARGET_CLIENT_TBH_OUT - 100 AS MALL_OUT_CHANNEL_TARGET_SALE_AMT    
          FROM TARGET_DATAS
          WHERE TARGET_YEAR = '2017'
          AND TARGET_MONTH = '09'
          AND TARGET_DIVI_CD = '10'  
        ) TT


가끔 데이터 조회 결과를 1:N 인데 1:1 로 합쳐서 표시할때 유용하다.

예제는 다음과 같다.


/* 엘클라시코 포워드 라인업 */
/* 오라클 11g 기준 문자열 연결 예제 (LISTAGG .. ) */
WITH EL_CLASICO_FORWARD_LINE_UP AS (
  SELECT
    '크리스티아누 호날두' AS PLAYER,
    '레알 마드리드' AS CLUB
  FROM DUAL
  UNION ALL
  SELECT
    '가레스 베일',
    '레알 마드리드'
  FROM DUAL
  UNION ALL
  SELECT
    '카림 벤제마',
    '레알 마드리드'
  FROM DUAL
  UNION ALL
  SELECT
    '리오넬 메시',
    'FC 바르셀로나'
  FROM DUAL
  UNION ALL
  SELECT
    '네이마르',
    'FC 바르셀로나'
  FROM DUAL
  UNION ALL
  SELECT
    '루이스 수아레즈',
    'FC 바르셀로나'
  FROM DUAL  
)
SELECT 
  CLUB,
  LISTAGG(PLAYER, '/') WITHIN GROUP(ORDER BY CLUB) AS FORWARDS
FROM EL_CLASICO_FORWARD_LINE_UP
GROUP BY CLUB;


※ 결과


먼저 DIRECT-PATH INSERT 에 대한 구조를 대략적으로나마 이해하면 좋을 듯 싶다.


나도 데이토의 올라온 내용을 따라해보고 까먹을까봐 일단 예제 순서만 메모.

  1. 해당 세션에 패러렐 DML 허용;
  2. 임시 테이블에 로깅해제;
  3. APPENT 힌트 사용
  4. 테이블 로깅;
  5. 다시 패러렐 DML 비허용

여기에 대한 관련 링크들은 다음과 같음.



오라클에서 쿼리 수행계획을 찾다보니 확인하고,
다음과 같이 샘플 예제를 넣어서 확인해버릇 해야겠다.


내가 이해하기로는 크게 3 블럭으로 나눈다.

  1. PLAN_TABLE(플랜계획내용을 저장하는 테이블) 에 STATEMENT_ID 를 부여
  2. 실행할 쿼리
  3. 플랜계획내용 조회
SET SERVEROUTPUT ON;
EXPLAIN PLAN SET statement_id = 'EX1' INTO PLAN_TABLE FOR

SELECT * FROM "대상테이블" /* 수행계획을 확인할 대상쿼리 */

SELECT * FROM PLAN_TABLE
WHERE STATEMENT_ID = 'EX1'

위 쿼리가 실행할 샘플 예제 입니다.


참고링크 : http://najuung.tistory.com/56

Mac OS 에서 sqldeveloper 로 접속시 locale not recognized 에러머세지로 연결불가.

아마 로케일 문제인듯.

설치된 sqldeveloper 는 영문판임.

구글링중 발견.


{sqldeveloper 설치위치}/Contents/Resources/sqldeveloper/sqldeveloper/bin/sqldeveloper.conf


파일을 열고 VMOption 에서 


AddVMOption -Duser.language=ko

AddVMOption -Duser.country=KR 


이분은 친절한 캡쳐포스팅 : http://ending1.tistory.com/49

  1. 소액결제 현금화 2017.12.07 04:19 신고

    감사합니다 ^&^

오라클에서 데이터를 다중 조건에 맞게 업데이트하기 위한 방법중 첫번째.

SET 절과 (WHERE, AND) 조건 절과 동일한 내용으로 업데이트 쿼리를 수행.


샘플 데이터는 다음과 같다.


테이블 : JKUN

위 테이블에서 업데이트 대상은 NUM_1 필드(전체)이다.


이 데이터들을 순번으로 업데이트 할 예정.

다음은 가상 데이터

    SELECT 1 AS RN, 4 AS NUM_SEQ
    FROM DUAL
    UNION ALL
    SELECT 2 AS RN, 5 AS NUM_SEQ
    FROM DUAL
    UNION ALL
    SELECT 3 AS RN, 6 AS NUM_SEQ
    FROM DUAL
    UNION ALL
    SELECT 4 AS RN, 7 AS NUM_SEQ
    FROM DUAL
    UNION ALL
    SELECT 5 AS RN, 8 AS NUM_SEQ
    FROM DUAL

    /* 위 가상 데이터를 지속적으로 인라인 뷰 */

위 데이터들은 NUM_SEQ 를 기준으로 NUM_1 을 수정한다. 이 첫번째 케이스로 업데이트를 수행하기 위해서는 반드시 조건/기준 컬럼이 필요.


UPDATE JKUN
SET NUM_1 = (
  SELECT RN FROM (
    SELECT 1 AS RN, 4 AS NUM_SEQ
    FROM DUAL
    UNION ALL
    SELECT 2 AS RN, 5 AS NUM_SEQ
    FROM DUAL
    UNION ALL
    SELECT 3 AS RN, 6 AS NUM_SEQ
    FROM DUAL
    UNION ALL
    SELECT 4 AS RN, 7 AS NUM_SEQ
    FROM DUAL
    UNION ALL
    SELECT 5 AS RN, 8 AS NUM_SEQ
    FROM DUAL
  ) RRD
  WHERE RRD.NUM_SEQ = JKUN.NUM_SEQ
)
WHERE EXISTS (
  SELECT 1
  FROM (
    SELECT 1 AS RN, 4 AS NUM_SEQ
    FROM DUAL
    UNION ALL
    SELECT 2 AS RN, 5 AS NUM_SEQ
    FROM DUAL
    UNION ALL
    SELECT 3 AS RN, 6 AS NUM_SEQ
    FROM DUAL
    UNION ALL
    SELECT 4 AS RN, 7 AS NUM_SEQ
    FROM DUAL
    UNION ALL
    SELECT 5 AS RN, 8 AS NUM_SEQ
    FROM DUAL
  ) RD
  WHERE NUM_SEQ = JKUN.NUM_SEQ
);

위 쿼리를 서술형으로 풀어서 정리하자면

JKUN 테이블에 있는 NUM_1 컬럼의 값들을 JKUN 테이블의 NUM_SEQ 컬럼과 인라인 뷰의 NUM_SEQ 컬럼과 매칭하여 RN 컬럼 값을 JKUN 테이블의

NUM_1 값들을 일괄적으로 수정.




WITH 구문내의 쿼리 결과를 Alias 를 지정하여 이어서 SELECT 절과 이용.

옵티마이저에서 인라인뷰나 임시테이블로 여김.

WITH WITH_EX AS
(
  SELECT ROWNUM R, 'TEST1' STR, SYSDATE DT FROM DUAL
  UNION ALL
  SELECT ROWNUM, 'TEST2', SYSDATE FROM DUAL
  UNION ALL
  SELECT ROWNUM, 'TEST3', SYSDATE FROM DUAL
)
SELECT * FROM WITH_EX;


조인도 가능

SELECT * FROM WITH_EX A LEFT OUTER JOIN (
  SELECT 1 R, 'TESTSSSSS' STR, SYSDATE DT FROM DUAL
  UNION ALL
  SELECT 2 R, 'TESTSSSSS' STR, SYSDATE DT FROM DUAL
) B
ON A.R = B.R;

오라클 시퀀스 정리


아래 내용은 심플하게 정리된 포스팅입니다.


출처 : 오라클 sequence 의 사용이유와 주의점 ( http://javakorea.tistory.com/175 )

시퀀스 사용이유가 데이터 입력시 동시성 때문에 register가 겹칠때 이를 방지 하기 위해 commit이 완료되지 않더라도 시퀀스를 사용하면 여러사용자가 중복되지않은 register(회원가입번호) 를 얻을수있어서 정상적 으로 회원가입이 가능하다. syntax) create sequence 시퀀스명 minvalue 1 // 최소 생성 시퀀스값 max value 99999999999 // 최대 생성 increment by 1 // 증가값 이값은 max-min보다 작아야함 start with 207 // 시작 시퀀스값 nocache // 시퀀스 생성을 위해 미리 값을 할당하는것, 동시성에 좋은 옵션, no하면 미리 할당X noorder//요청되는 순서대로 값을 생성함, 디폴트값은 no nocycle//생성된 시퀀스값이 최대치 혹은 최소치(감소시)에 다다랐을때 초기값부터 다시 시작할지 물어봄 디폴트값은 no . cycle로 돌아가면 minvalue로 돌아감 시퀀스명 " " 을 넣으면 대소문자 구분을 할 수 있다 근데 문제점은 "aaa" 를 만들고 drop sequence aaa 하면 자동으로 AAA 라고 인식을 해서 지워지지 않는다. 하이 테이블에 a시퀀스를 쓰고 헬로 테이블에 a시퀀스를 사용하면 a시퀀스에 현재 저장된 last_number를 따라가기 때문에 테이블,컬럼,데이터 입력시 원하는 시퀀스를 헷갈리지않게 명칭을 잘 정해야할것


마리아 디비에서 보면 JSON 테이블 형태가 존재하는것 같다.

일단은 테스트를 해봐야하나 ㅋㅋ

차후 로 미루고 메모포스팅을.


Guide : https://mariadb.com/kb/en/mariadb/connect-json-table-type/

Blog Post : http://estenpark.tistory.com/350


위에 포스팅에서 꽤 상세하고 자세하게 포스팅되어있어 그대로 따라해보면 될듯.

MySQL 정규식으로 치환 함수

DELIMITER $$

CREATE FUNCTION  `regex_replace`(pattern VARCHAR(1000),replacement VARCHAR(1000),original VARCHAR(1000))
RETURNS VARCHAR(1000)
DETERMINISTIC
BEGIN 
 DECLARE temp VARCHAR(1000); 
 DECLARE ch VARCHAR(1); 
 DECLARE i INT;
 SET i = 1;
 SET temp = '';
 IF original REGEXP pattern THEN 
  loop_label: LOOP 
   IF i>CHAR_LENGTH(original) THEN
    LEAVE loop_label;  
   END IF;
   SET ch = SUBSTRING(original,i,1);
   IF NOT ch REGEXP pattern THEN
    SET temp = CONCAT(temp,ch);
   ELSE
    SET temp = CONCAT(temp,replacement);
   END IF;
   SET i=i+1;
  END LOOP;
 ELSE
  SET temp = original;
 END IF;
 RETURN temp;
END$$

DELIMITER ;

본문 : https://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/

1. UNIXTIME(타임스탬프) → DATE 

 FROM_UNIXTIME('1485874832', '%Y%m%d %H%i%s') 

2. DATE → UNIXTIME

UNIX_TIMESTAMP()
UNIX_TIMESTAMP('YYYY-MM-DD HH:mm:ss')


ERWIN 을 쓰다보면 가끔 네이밍 설정을 안해줘서,

짜증에 직면할때가 있다.



여기서 해당하는 부분에 Macro Name 을 수정하면 된다.

특히 키 그룹은 반드시 변경 ㅡㅡ^;;


%KeyType_%TableName OR %KeyType_%TableName_%PK()

추가적인 설명은 Macro ToolBox 버튼을 누름 


이와 같이 자세히 확인할 수 있으나... 일단은 키 그룹 빼곤;;;

ㅋㅋ


아 그리고 유용하게 사용되는 엔티티명에 코멘트 적용시키는 스크립트.

Schema Generation 에서 Post-Script 옵션에 체크해준다.

%ForEachTable() {
	COMMENT ON TABLE %TableName IS '%EntityName';
	%ForEachColumn() {
		COMMENT ON COLUMN %TableName.%ColName IS '%AttName';
	}
}


구글링도중에 아주 나이스한 포스트 추가 링크겁니다

http://e2xist.tistory.com/468


더보기


'DataBase' 카테고리의 다른 글

[ERWIN] 오브젝트및 속성 명 일괄적으로 대/소문자 변경  (1) 2018.05.10
[ER-WIN] Names Option  (0) 2016.10.25
memsql  (0) 2013.12.30
FreeSQLFormatter [SQL정렬]  (0) 2012.02.13
NoSQL  (0) 2011.01.14
ERStudio  (0) 2010.08.24


출처 : http://paraffa.tistory.com/47

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

1. MongoDB / C로작성 됨

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


1.1 MongoDB란?

  - MongoDB는 10gen 사에서 개발된 높은 성능과 확장성을 가지고 있는 데이터베이스 입니다.

    NoSQL 데이터베이스에서는 문서형 데이터베이스로 분류됩니다. C언어로 개발되었다.

    공식사이트 : http://www.mongodb.org


1.2 왜 MongoDB를 사용하는가?

  - 스키마를 고정하지않는다.

  - 시리얼라이즈 시키면 문제가 없어질까?

    - json등을 사용하여 시리얼라이즈시킨 데이터를 관계형 데이터베이스에 입력하면된다.

      > 가독성이 떨어진다.

      > 성능저하를 검토하여야한다.

  - 스키마 없는 데이터베이스

    - MongoDB는 스키마가없는 데이터베이스이다.

    - RDB와 마찬가지로 임의의 key값에대한 복잡한 검색이 가능하다.

    - RDB와 비교해 응답속도가 빠르고, 인덱스를 추가하여 처리속도를 더 빠르게 할 수 있다.


1.3 특징

  - MongoDB는 스키마를 정의할 필요가 없음.

  - 문서형 데이터베이스는 데이터를 입력할때 데이터 구조 정보를 포함하여 BSON(JSON을 바이너리화한것)

    형식으로 저장하고, 이것을 value로 key와 짝짓습니다.


1.4 장점

  - 스키마 없이사용이 가장 큰 장점입니다.

  - 스키마가 없기 때문에 프로그램 코드만 수정하면 됩니다.

  - 스키마와 프로그램 코드사이의정합성에 신경쓰지 않아도 된다.

  - 검색조건을 유연하게 지정할 수 있습니다. 

    > 정규표현을 통한 검색부터 배열 데이터에 특정 값이 포함되어 있는지등.


1.5 단점

  - MongoDB에서는 JOIN이나 트랜잭션성 처리가 불가능하다.

  - MongoDB에서는 데이터 갱신 및 입력시 바로 디스크에 쓰지 않는다는 것입니다.

    > 디스크에 쓰기가 비동기식으로 이루어진다. 때문에 경우에 따라 데이터가 유실될 가능성도 있다.

      이것과 트레이드오프로 빠른 응답속도가 가능한 것 입니다만 데이터가 사라질 수 있다는 점에 

      주의해야 한다.

1.6 도입사례

  - 해외의 도입사례

    > foursquare

    > preferred infrastructure

    > 아메바피아


1.7 구체적인 이용 예

1.7.1 샘플1

  - MongoDB의 구체적인 예로 앙케이트 응답 데이터를 다루는 경우를 생각해보겠습니다. 

    MongoMapper라는 라이브러리를 사용해서 구현하도록 하겠습니다. 먼저 앙케이트 응답 데이터를 다룰 answers콜렉션에 대한 모델을 정의합니다.

    클래스 정의 내부에 MongoMapper:Document를 include하고있는것 외에는 특별히 다른 부분은 없습니다.


  - 컬럼을 정의하지 않아도 MongoDB를 사용할 수 있습니다만 이번예에서는 user_id와 enquete_id를 명시적으로 정의해 두었습니다.

    컬럼을 정의하면 validation 가능(이번경우 user_id, enquete_id가 필수 항목이 됨), Accessor 설정, 대응클래서에 매핑됨

    이라는 잇점이 있기 때문입니다. 물론, 단순히 알기쉽고 관리가 편하다는 이유도 있습니다.


  - 여러 데이터 형식 입력 가능

  - 콜렉션을 다른 콜렉션에 추가

  - 응답 데이터를 저장한다.

  - 스키마 변경없이 대응 가능


1.7.2 샘플2

  - 다른 예로 분석 데이터 스토리지로 사용하는 경우에 대해 생각해 보겠습니다.로그 데이터를 분석하여 그 분석 결과를 MongoDB에 저장하는 케이스입니다.

    서비스이용 상태를 조사한다거나 서비스를 개선하기위해 로그데이터를 해서 PV나 UU, 그외 여러가지데이터를 만들어 내는 경우가 있을것 입니다만

    그 데이터를 어떻게 관리하면 좋을까요?

    

    > 관계형 데이터베이스에서의 운용

      - 단,로그 데이터 분석에서는 어떤 컬럼이 필요할지 알 수 없습니다. 이제까지 필요하지 않았던 컬럼도 어떤 분석에서는 필요해질 수 있습니다.

        그러므로 분석용 테이블을만들어서 해당 테이블에 모든 분석 테이터를 보존하고 필요할 경우 새로운 컬럼을 추가한다거나 아니면 다른 테이블을

만들어서 저장하는 방법이 있습니다.


      - 동일한 테이블에 모든 분석 데이터를 저장하고 필요할 때마다 새로운 컬럼을 추가한다면 운영이 번거로워지고 특정 분석에서만 사용하는 불필요한

        컬럼이 많아질 수 있습니다. 그렇다고 해서 분석 데이터만다 별도 테이블을 만든다면 테이블 수가 무척 많아지게 될 것 입니다.


    > MongoDB를 사용한 운용

      - 로그 데이터를 분석하면 여러가지 형식의 데이터가 얻어질 것이라고 생각합니다만, MongoDB라면 스키마에 신경쓰지 않고 여러 데이터를 저장 할 수

        있습니다. 새로운 데이터를 저장해야 할 경우에도 스키마 변경 없이 바로 추가해서 기록할 수 있는 유연함이 MongoDB의 가장 큰 장점입니다.

'이 데이터는 앞으로 이용 할 수도 있다'는 일시적으로 사용할 데이터도 가볍게 저장할 수 있어서 편리합니다.


1.7.3 Tip

  - MongoDB의 지리 공간 인덱스라고 불리는 인덱스를 사용하는 것이 가능합니다. (1.7.0 이상)위도와 경도정보를 인덱스로 사용하여 검색할 수 있습니다.

    최근 GPS를 사용한 서비스가 늘어나고 HTML5에서는 Geolocation  API를 제공하는 등 위치 정보가 점점 더 중요해질 것이라고 생각합니다. 

    

    # 지리 공간 인덱스를 이용하는 컬럼으로 "2d"를 지정

    # 복합 인덱스도 사용 가능

    > db.place.ensureIndex({location:"2d"})


    # 데이터 입력

    > db.place.find({location:{$near:[139.65,35.65]}}).limit(5)


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

2. Cassandra (key-value형 스토어) / 자바기반

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

2.1 Cassandra란?

  - Cassandra는 facebook에서개발하여 현재는 Apache프로젝트로 진행되고 있는 오픈소스 소프트웨어이다.

    NoSQL데이터베이스에서는 key-value형으로 분류된다. Google의 BigTable을 바탕으로 개발되고 

    컬럼 단위로 관리되어 컬럼형으로 분류하기도 한다.


2.2 왜 Cassandra를 사용하는가?

  - 대량의 데이터를 다루는데 효과적

    > 여러장소에 분산된 다수의 저가 서버를 이용하여 대량 데이터를 다루기 위해 만들어진 데이터 스토어로

      대량의데이터를 다루는 데특화되어 있습니다.다량의데이터를 다수의 서버에 분산시키며 분산된 데이터를 여러

      서버에 복제해 두는 방식으로, 읽기와 쓰기가 모두 뛰어나다. 또한 데이터를 메모리에 보관해 두고 일정 조건 후

      디스크에 입력하는 영속성과 휘발성 key-value가 혼합된 방식으로 관계형 데이터베이스에 비해 속도가 크게 빠릅니다.


    > memcached처럼 관계형 데이터베이스의 cache로 사용할 수 있지만, 다수가 이용하는 대랴의 데이터에 특화되어 개발된

      만큼 관계형 데이터베이스와 대등하게 단독 데이터베이스로 사용하는 경우가 많습니다.


2.3 특징과 사용케이스

  - Cassandra는 Row key를 인덱스로가지는 key-value형 스토어입니다. 또한 컬럼을 기본으로 데이터를 다루는 컬럼형 NoSQL

    데이터베이스로 행 중심인 관계형 데이터베이스와는 달리 디스크에 데이터를 컬럼 단위로 연속하여 저장한다.

    컬럼(열)단위로 관리되기 때문에 동일한 데이터라도 행단위로 관리하는 것보다 디스크에 많이 저장할수 있습니다


  - 컬럼이 기본 단위로 컬럼에는 컬럼 이름과 값, time stamp가 포합니다. Row key로 식별되는 한 행에는 여러 개의 

    컬럼이 포함될 수 있으며 한 Row에서 저장할 수 있는 컬럼 개수는 20억개 , 각 Row key의 최대 크기는 64KB이다.

    각 컬럼은 Column family에  속하며 Column family는 Keyspace에 포함됩니다. Column family 중 Super Column family는

    Column family를 자식 column으로 가질 수 있습니다. Keyspace는 관계형 데이터베이스에서 스키마나 테이블 스페이스라

    불리는 것과 유사합니다. Keyspace단위로 복제 및 관련 정책을 관리하여보통 어플리케이션 하나 당 Keyspace를 하나씩 

    생성합니다.


  - 어플리케이션에서 Column family의 정렬 기준을 시간이나 이름으로 지정할 수 있습니다.

    Cassandra의 또다른 특징은 분산된 환경에 적합하며 확장성이 뛰어나다는 것입니다.

    앞에서도 이야기했듯이 동일한 데이터가 여러 서버에 복제되어 있어 단위 서버에 문제가 발생하더라도 가용성이 보장됩니다.

    하지만 확장성과 가용성이 좋은 대신 관계형 데이터베이스에 비해 데이터 신뢰도는 떨어지는 편입니다.

    기본 구성에서는 데이터에 대한 입력이나 변경이 비동기식으로이루어지고 중앙에서 관리하는 서버가 별도로 없기 때문에

    분산된 데이터사이에 정합성이 맞지 않는 경우가 발생할 수 있습니다.

    이를 보완하기 위해 데이터 읽기 요청이 발생한 경우 해당 데이터를가지고 있는 여러 서버에 요청을 발행하여 결과값을 비교해 보고 time stamp가

    가장 최신인 데이터를 반환하는 등의 로직을 제공하고 있습니다. 이때 time stamp가 오래된 응답을 보낸 서버는 최신의 데이터로 갱신하도록 합니다.


  - 데이터의 신뢰도를 높이기 위해 동일한 데이터를 가지고 잇는 여러 서버에서 데이터를 가져와서 비교하다 보면 성능에영향을 미칠 수 있습니다.

    따라서 Cassandra에서는 읽기 및 쓰기에대한 각각의 Consistency Level을 지정하여 성능과 신뢰도 수준을 조정하도록 하고 있습니다.

    Consistency Level이 All인 경우에는 읽기 및 쓰기 요청이 발생할 경우 복제된 데이터를가진 모든 서버에서 응답을 보내와야 완료됩니다.

    이경우 데이터베이스의 유연성 및 성능은 떨어지지만 데이터 신뢰도는 높아지게 됩니다.

    Consistency Level이 One일경우에는 읽기 및 쓰기 요청이 발생하였을 때 해당 데이터를 가지고 있는 하나의 서버를 대상으로 해당 연산을

    처리하고 완료하게됩니다. 데이터 신뢰성은 떨어지게되지만 분산에 대한 유연도와 응답 성능은 높아집니다.

    마지막으로QUORUM으로 설정해 두면 읽기 및 쓰기 요청이 들어온 데이터를 복제하여 가지고 있는 일정 대술의 서버에서 응답을 보낼 경우 완료하게 됩니다.

    참고로 Facebook에서 권장하는 Consistency Level은 One이나 replication factor(복제 서버수)를 3으로 둔 QUORUM입니다.

    

    ※ consistency level

    > Level           Write                                    Read

    > ANY | 요청한 내용이 적어도 한 node에 저장됨 |             - 

    > ONE | 요청한 내용이 적어도 한 node의 commit log 및 table에 저장된 후 요청자에게 응답함 | 가장 가까운 고의 replica에서 응답을 받아서 반환한다. Read repair 설정이 되어 있으면 Cassandra는 백그라운드 스레드에서 신뢰도 체크를 실시.

    > QUORUM | 요청자에게 응답하기 전에 quorum of replicas에 저장됨 | quorum of replicas의 응답 중 가장 최근 time stamp의 응답을 반환 |

    > LOCAL_QUORUM |요청자에게 응답하기 전에 local데이터 센터 내의 quorum of replicas에 저장됨. 데이터 센터 사이의latency로 인한 지연을 줄이기위한 설정 | 단일 데이터 센터의quorum of replicas의 응답중 가장 최근 time stamp의 응답을 반환. 데이터센터 사이의 latency를 줄이기 위함 |

    > EACH_QUORUM | 각 데이터센터의 quorum of replicas에 저장한 후 요청자에게 완료를 알림.| 각 데이터 센터의 quorum of replicas의 응답중 가장 최근 time stamp의 응답을 반환|

    > ALL | 모든 replica가 저장해야 함. 그러지않으면 해당 연산은 실패 | 모든 replaica에서 준 응답중 가장 최근 time stamp 값을 반환.하나라도 응답이 오지 않으면 실패 | 


  - key-value형 스토어 데이터 분산에는 memcached 등과 마찬가지로 Consistent Hashing 방식을 이용하고 있습니다.


2.5 장점

  - 대량의 데이터를 다수의분산된 서버에서관리해야 할 경우 적합합니다. 특히 많은 사람들이 이용하며 대량으로 쓰기가 발생하는 서비스에 좋습니다.

    데이터는 일단 메모리에 쓰여지며 데이터가 일정 크기가 되면 디스크로옮겨지게 됩니다.


  - Consistent Hashing 방식을 이용하여 데이터를 분산한다. Consistent Hashing방식에 로드 밸런싱을 위한 알고리즘을 더하여 요청이 적은 서버를

    요청이 많은 서버 구간으로 옮기는 방식으로 로드 밸런싱을 구현하고 있습니다. 따라서 대량의 요청이 소수의 서버에 몰리는 것을 막아 장애를방지하고

    성능을 높일 수 있습니다. 또한 신규로 서버가 추가되는 경우 로드 밸런싱을 고려하여 요청이 많은 구간에 우선 추가되어 부하 관리가 효율적으로 

    이루어지게 됩니다.


  - 신규 서버를 분산 시스템에 추가할 경우 서비스 중단없이 손쉽게 추가할 수 있는 것도 큰장점 입니다. 서비스 요청이 많아져서 신규로 서버를 추가하는경우,

    중앙에서 관리하는 별도 서버가 없기 때문에 새로 추가되는 서버만 기동하면 서비스에 해당서버가 추가되게 됩니다. 즉, 기존에 서비스를 제공하던 서버를

    재기동해야 하는 등의 서비스 중단이 필요 없습니다.


  - 아마존 다이나모 방식을 구현하여 데이터 일관성 대신 연속적인 서비스제공에 중점을 둔 구조로 가용성이 굉장히 뛰어납니다. 데이터 복제 설정도 동일한

    서버 랙을 사용하지 않는 서버에 복제본을 둔다거나 다른 데이터 센터에 복제본을두는 등 다양하게 구현할 수 있습니다.중앙에서관리하는 별도 서버가 없고

    데이터 복제를 기본으로 하고 있기 때문에 단일 노드의 장애 발생시 서비스에미치는 영향이 거의없습니다. Consistency Level을 통해 업무 특성에 맞춰 가용성과

    신뢰도의 정도를 조정할 수 있습니다.


  - Apache Foundation에서개발하고 있으며 여러 사이트에서 활용하고 있어 커뮤니티가 활발하며 사용 사례가 많습니다.따라서우녕ㅇ시 참고할 만한 자료가 다른 

    NoSQL데이터베이스에 비해 풍부한 편입니다. 커뮤니티가활발하여 문제발생시 유사 사례를 찾거나 의견을 구하는 것도 비교적 쉬운 편입니다.


2.6 단점

  - 컬럼형 데이터베이스로 Row형 데이터베이스인 관계형 데이터베이스와는 다른생소한 개념이라 진입장벽이 높습니다. 따라서많은 사용자를 대상으로 대량 데이터를

    다루는 서비스가 아닐 경우 굳이 Cassandra를 고집할 필요는 없을 것입니다.

  

  - 복잡한 조건의 검색이 불가능 합니다. Row key와 컬럼 두가지에대한 인덱스만 가능하기 때문에 데이터는 대량이지만 검색 조건은 단순한 서비스에 적합니다.

  

  - Super Column family의하위 컬럼에 대한 인덱싱은 불가능합니다.

    key 값을 토한 범위 검색은 데이터 분산 방식을 OrderPresservingPartitioner로 설정하여 key값을 통해 데이터를 서버에분배했을 때문 가능하는 등의

    검색 관련 제약사항이 있습니다.


  - 데이터에 대한 갱신 및 입력시 Atomic한 처리가 어렵습니다. 데이터에 대한Lock을 사용하려면 Zookeeper와 같은 전체분산 서버를 관리하는 프로그램을 추가해서

    별도로 설정해야 합니다. 데이터에 대한 동시 갱신 요청이 발생할 가능성이 높거나 Atomic한 트랜잭션이 필요한 서비스에서는다른 데이터베이스를 고려하는 것이 

    좋을 겁니다.


  - 지금 버전 1이 정식으로 나오지 않은 안정적이지 않은 시스템이라느 것도 불안요소가 될수 있습니다.

    커뮤니티가 매우 활발하여 계속해서새로운 기능을 추가하고이슈를 해결하고 있지만 그만큼 새로운 내용에 항상 촉각을 세우고 있어야한다.


2.7 도입사례

  - Facebook을 비롯하여 여러 유명 해외 서비스에서 사용하고 있습니다.

    > Facebook

    > Twitter

    > Digg

  또한 대량 데이터를 다루는 많은 사이트에서 도입을 검토하고 있습니다.


  - 사용케이스 : 시작은 Facebook에 최적화 되어 개발되었기 때문에 다수의 쓰기가 발생하는 대형 웹서비스에 적합합니다.

    앞서 이야기했듯이 Atomic한 처리가필요한 서비스보다는 동일 row에 대한 동시 갱신 요청이 적은 경우나 높은 데이터 신뢰도가 필요하지 않은 서비스에

    적합할 것입니다. 대량 데이터의 입력 성능이 뛰어나기 때문에 실시간 입력 요청이 많은 서비스에 좋습니다. 또한 대량의 데이터의 실시간 분석에도 적합니다.

    Twitter에서는 실시간 분석에 활용하고 있습니다.

    > 사용자가 많으며 사용자에의한 데이터입력이 빈번하게 발생하는 대량의데이터를 다루는 시스템

    > 빈번하게 변경되는 데이터에대한 실시간 분석용 시스템

    > 대량의데이터를 다루며 신뢰성보다 가용성이 중요한 시스템


  - 다른 key-value형 NoSQL 데이터베이스와는 달리 Cassandra는 관계형 데이터베이스를 대체하는 대량 데이터용 스토어로 사용되는 경우가 많습니다. 

    대량의 데이터를 다수 서버에 분산하여 많은 사용자가접속하여 쓰는 구성은 관계형 데이터베이스를 통해서는 효율적으로 지원하기 어렵습니다.

    대량 데이터 분산 처리용으로 나온 NoSQL데이터베이스에서는 HBase와 함께 Cassandra가 가장 앞서나가고 있습니다.


2.8 구체적인 이용 예

2.8.1 사용자 검색 정보 스토리지

  - 많은사용자가 이용하는 대규모 검색 사이트의 경우를 생각해 보겠습니다. 사용자가 많고 실시간으로 기록되눈 데이터(검색시도)가 많으며 데이터는 대부분

    텍스트 데이터로 이루어집니다. 검색 사이트에서 검색 정보를 기록하여 활용한다면 어떤 데이터베이스를 이용하는 것이 좋을까요?


  - 관계형 데이터베이스에서의 운용

    물론 관계형 데이터베이스로 관리하는 방법도 생각할 수 있습니다. 하지만 1000만명의 사용자가 하루 12시간, 시간당 20만건만 검색한다고해도

    1000000x20x12, 즉 24억 행의 데이터가 매일 추가됩니다. 매일 24억 행씩 증가하는 데이터라면 입력하려는 프로세스 간 경합으로 성능이 많이 떨어지게 될것입니다.

    뿐만 아니라 관계형 데이터베이스 응답 시간과 데이터 규모를 고려한다면 고가의 장비를 도입해야 할 것입니다.


    고가의 장비를 도입해서 관계형 데이터베이스로 해당 데이터를 관리한다고해도테이블 구조가 간단할 뿐더러 높은 실시간 데이터 일관성이 필요하거나 join등의 복잡한

    연산이 필요한 서비스가 아니기 때문에 낭비라는 생각이 자꾸 듭니다.

  

  - Cassandra를 사용한 운용

    이런 경우에는 Cassandra가 좋은 대안이 될 것입니다. 실시간으로 정확하게 제공하는 서비스가 아니기 때문에 높은 신뢰도를 제공하는 데이터베이스일 필요가 없습니다.

    검색 정보 데이터를 활용할 때도 데이터 구조가 간단하기 때문에 JOIN이나 복잡한 연산보다 통계성 분석이 주를 이룹니다. 대량의중요도가 높지 않은 데이터를 모두 저장해

    서 의미있는 비지니스 데이터로 활용하기 위해서는 저비용으로 대량의 데이터를 관리하며 고가용성과 유연성을 제공하는 Cassandra가 좋을 것입니다.



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

3. HBase (컬럼형 스토어) / 자바기반

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

3.1 HBase란

  - HBase란 2006년 차드 월터스와 짐 캘러만에 의해 시작되어 현재는 Apache 프로젝트로 개발이 진행되고 있는 오픈소스 소프트웨어입니다.

    NoSQL 데이터베이스에서는 컬럼형 데이터베이스라고 분류됩니다.

    공식 사이트 : http://hbase.apache.org


3.2 왜 HBase를 사용하는가?

  - 대용량 데이터를 안정적으로다루는 데 효과적

    > HBase는 Cassandra와 마찬가지로 Bigtable의 영향을받은, 대량 데이터를 효율적으로 다루기 위한 목적으로 개발된  NoSQL 데이터베이스

      입니다. 대용량 데이터를 다루는 NoSQL 데이터베이스중 Cassandra와 함께 가장 많이 사용되고 있습니다만, Cassandra와는 구별되는 뚜렷한

      특징을 가지고 있습니다. Cassandra는 성능을 우선시 할 경우 데이터 일관성이 보장되지 않을 수 있다고 말씀 드렸습니다. 대량 데이터를

      우수한 성능으로 데이터 일관성을 보장하면서 다뤄야 할 때는 어떻게 해야 할까요? 이부분에서 장점으로 가지고 있는 것이 HBase입니다.

      

      HBase는 중앙에 전체 분산 시스템을 통제하는 마스터를 두고 복제된 전체 데이터의 일관성을 관리 하기때문에 분산된 복제 데이터 사이의

      일관성을 보장하며 제약이 있지만 트랜잭셔성 처리도 지원이 가능합니다.


  - 대량 데이터분석 처리지원에 적합

    > 대량 데이터 분석 및 처리를 위해 사용되는 Hadoop의 산하 프로젝트로 시작된 데이터베이스로 HDFS 및 MapReduce등과 함께 사용하기에

      최적화 되어 있습니다. MapReduce를 지원하는 다른 데이터베이스도 있지만 별도로 개발되었기 때문에 HBase처럼 HDFS를 사용하며 

      MapReduce의 기능을 적합하게 사용하는 예는 없습니다.


      대량 데이터를 분삭하여 의미 있는 값을 만드는 데 있어 널리 사용되고 있는 MapReduce와 함께 효율적으로 이용할 수 있다는 것이 큰 

      장점 입니다.


3.3 특징과 사용 케이스

3.3.1 특징

  - 컬럼형 NoSQL 데이터베이스로기본 단위는 컬럼입니다. 여러 컬럼이 Row Key에 할당되고 이러한 Row key가 모여 테이블을 이룹니다.

    테이블 내의 Row key는 정렬되어 저장되며 해당 데이터베이스 내에서단일한 값을 가져 index와 비슷한 역할을 수행하게 됩니다.


    컬럼이 모여 Column family를 이룹니다. Column family 내의 모든 컬럼은 동일한 스토리지 파일에저장되고 데이터 압축 등 성능 개선을 위한 튜닝은

    Column family단위로 이루어 집니다. Column family내의 컬럼수에 대한제한은 없으며, 컬럼 값의 데이터 타입이나 길이에대한 제약도 없습니다. 앞서

    이야기한 것처럼 컬럼 단위로 디스크에 저장하기 때문에 행중심 데이터베이스에 비해 동일한 데이터라도 사용하는 디스크가 적습니다.


    데이터가업데이트되면 우선 commit log에 해당 내용을 저장하고 다음으로 HBase에서 사용하고 있는 메모리 상의데이터베이스(memstore)에 데이터를

    저장합니다. 이 때 commit log는 여러 무리적인 서버에 복제되기 때문에 변경된 데이터가 사라질 확률이 낮습니다. memstroe의 데이터가 미리 지정한

    크기를 넘어서면 디스크에 저장되며 저장 된 데이터에 대한 commit log는 삭제됩니다.


    분산 구성시 Master-Region 구조를 이룹니다. Region은 분산을 이루고있는기본 단위로, 연속한 row데이터를 가지고 있습니다. 구성파일에 정의해둔

    maximum size 값을 초과하면 자동으로 해당 region에서관리하고 있는 데이터의 절반을 key값을 기준으로 새 region에 분배합니다.

    참고로 현재 하나의 물리적인 서버에서 관리하는 region은 10~1000개, region 당 데이터는 1~2GB를 권고 하고 있습니다.


    HBase에서 Region의 정보를 관리하는 Master(HMaster)를 별도로 두고 있습니다. 데이터에 대한 읽기나 쓰기 요청이 발생하면 Master에서 어느 region에서

    해당 Rwo key를 관리하는지에 대한 기초 정보를 제공해 줍니다. Maste는 Region에 할당된 Row key값을 재분배 해줍니다. 장애를 예방하기 위해 Master는

    여러 대로 구성할 수 있습니다.


3.3.2 장점

  - HBase의 가장 큰 장점은 대량의데이터를 분산된 환경에서관리함녀서도 데이터일관성을 보장해 준다는 점입니다. 대량 데이터를 다루면서 일관성이 필요한

    환경에서 일관성이 완벽하게 보장되지 않는 데이터베이스를 사용한다면 프로그램 코드를 통해 데이터의 일관성을 보장해야 하므로 코딩의 복잡도가 크게

    올라가게 될것이다. HBase에서는 데이터의 일관성 보장에 초점을 맞추고 있으므로 이러한 경우에는 HBase를 사용함으로써 수고를 많이 줄일 수 있을것이다.


  - 데이터를 효율적으로 압축 할 수 있습니다. 행 기반에 비해 컬럼 기반으로 데이터를 저장하는 것이 데이터 압축을 더 효율적으로 할 수 있습니다. 일반적으로

    사용되는 행 기반으로 데이터를 입력하는 경우, 행에서 가지고 있는여러 컬럼 값은 서로 다른 데이터 타입의 차이가 큰 값일 가능성이 높습니다. 하지만

    가지고 있는 여러 컬럼 값은 서로다른 데이터 타입의 차이가 튼 값일 가능성이 높습니다. 하지만 컬럼 기반의 경우컬럼을 기준으로 데이터가 함께 저장되기

    때문에 근접 데이터 사이의 값의 차이가 크지 않아행 기반에 비해 데이터 압축률이 높습니다. 따라서 대량 데이터를 보다 경제적으로 관리할 수 있고, 대량

    조회가 발생할 경우 압축된 데이터를 가져오기 때문에 bandwidth 측면에서도 득을 볼 수 있습니다.


  - 이전 버전의 데이터 값도 관리가가능하다는 것도 장점 입니다.각기 다른 버전의 값을 통해 변경 빈도 등의데이트럴 분석 할 수 있습니다. 어느 버전까지 데이터를

    유지 할 것인지는 설정 파일을 통해 지정할 수 있브니다. 지난 버전 데이터를 통한 통계나 변경내용에 대한 분석도 가능합니다.


  - 한 행에 대한 Atomic한 처리가 가능합니다. 즉, 단일 행에 대해서는 트랜잭션성 처리가 가능하다는 장점을 가지고 있습니다. 대량 데이터를 다루면서 트랜잭션성

    처리가 필요할 경우 매우 요긴한 기능입니다. 또한 웹 콘솔을 통해 관리 및 모니터링 할 수 있는 기능을 제공하고 있습니다.


3.3.3 단점

  - 다수의 프로그램으로 이루어진 데이터베이스로다른 NoSQL 데이터베이스에 비해 이해하기가 복잡합니다. 효율적으로 관리하기 위해서는 HDFS, Zookeeper등 HBase뿐만

    아니라 다른 시스템에 대해서도 알아두어야 합니다. 단일 구조에 비해 설치 및 운영 시 시스템들의 연계로 인한 문제가 발생할 가능성이 높습니다. 뿐만 아니라 아직

    생소한 컬럼형 구조를 사용하고 있어 조기 진입에 벽이 높습니다.


  - 특정 범위의 key 값에 저장 요청이 집중되는 경우에도 문제가 발생할 수 있습니다.

    Region별로 저장되는 데이터는 Row key값에 따라 정해집니다. 즉, 일정 범위의 Row key가 Region에 함께 저장되는 구조로, 연속된 Row key를 가진 요청이 들어올 경우

    모든요청이 한두 Region에 집중되어응답 속도가 느려지는 등의 문제가 생길 수 있습니다.


  - HDFS를 파일시스템으로사용하기 때문에 HDFS의 파일 정보를 관리하는 Namenode에서 장애가 발생하거나, Namenode가 구동되어 있는 서버가 다운될 경우 HBase에도 문제가

    생기게 됩니다. 아직 Namenode는 이중화솔류션을 완벽하게 제공하지 않기때문에 전체 HDFS에서 Namenode는 하나뿐입니다. 따라서 Namenode가 중단되면 전체 서비스 중단이

    발생하게 됩니다.


  - Cassandra와 마찬가지로 현재 0.9.4로 아직 버전 1이 나오지 않은 안정적이지 않은 시스템입니다.

    신규 버전이 기존 버전에서 많이 변경되어 불편이 생길수도 있습니다.


3.3.4 도입사례

  - 최근 Facebook에서 데이터 일관성 보장을 이유를 들어 MySQL을대신하는 주 데이터베이스로 도입하기도 하였습니다.

    > Facebook

    > eBay

    > WorldLingo

  이외에도 Adobe 등에서 분석등의 용도로 HBase를 사용 하고 있습니다.


3.3.5 사용 케이스

  - 대량 데이터를 다루면서 데이터 일관성이 요구되는 서비스에서사용하는 것을 권장하고 있습니다. 또한 hadoop을 사용하여 대량 데이터를 분석하는 서비스의 대용량

    데이터베이스로 사용하는 경우도 많습니다.

    > 대량 데이터를 관리하는 사이트 중에서도 쓰기보다는 읽기 요청이 많은 사이트에 적합

    > 대량 데이터를 관리하면서 데이터 일관성 및 트랜잭션성 처리가 필요한 사이트

    > Hadoop을 사용하여 대량 데이터를 분석해야 하는 경우

  

  - HBase에서는 적어도 5대 이상의 서버에서 수백만행 이상의 데이터를 다루는데 사용 할 것을 권고 하고 있습니다.

    대량 데이터 중에서도 동시에 다수의 쓰기가 발생하는 성격의 업무보다는 DW성 데이터 처리에 적합하다고 합니다.


4.1 구체적인 이용 예

4.1.1 대형 SNS서비스의 주 스토리지

  - 대규모 SNS 서비스의 주 스토리지로 사용하는 것도 좋을것입니다. 이미 Facebook에서 주 스토리지로 도입하여 사용하고 있습니다.


  - 대량의 쓰기/읽기 요청

    > Twitter나 Faceboo, 카카오톡에서 제공하는 주 서비스를 생각해 보면 수천만 사용자가 실시간으로 데이터를 입력하고 검색하는 요청이

      계속해서 들어오게 됩니다. 하지만 데이터의 구조는 매우 간단하며 사용자와 키워드 검색이 주를 이룹니다. 새로 업데이트된 데이터에 대한

      읽기 요청이 계속해서 발생하기 때문에 데이터 일관성은 보장되어야 하며 쓰기 성능뿐아니라 검색 성능도 매우 중요합니다.


  - 관계형 데이터베이스를 사용한 운용

    > 수백,수천만의데이터 쓰기가 계속해서 요청되는 상황에서는 계속해서 Lock이 발생하여 데이터 읽기와 쓰기 모두 적합한 성능을 보이기 어려울

      뿐더러 관계형 데이터베이스를 이용해서 데이터의 급속한 증가를 관리하는 데는한계가 있습니다. 또한 이러한 대량 데이터를 조회하여 대량의 

      결과가 나와야 하는 경우, 분산에 한계가 있는 관계형 데이터베이스에서는 소수의 서버의 적은 자원으로 대량 요청을 처리해야 하므로 속도와

      성능이 좋지 못하고, 다른 요청을 처리하기도 어려울 것으로 보입니다.


  - HBase를 사용한 운용

    > 다수의 저가 서버(PC)를 분산해서 사용할 수 있는 HBase를 통해 관계형 데이터베이스에서 나타나는 이러한 이슈를 대부분 해결할 수 있습니다.

      테이블의 데이터 입력에 대한 Lock이 발생하지 않으며 데이터가 급속히 증가하더라도 단일 데이터 입력의 비용이 저렴할 뿐 아니라 많은 수의

      서버로 분산되어 부담을 줄일 수 있습니다. 데이터의 일관성이 실시간으로 필요하며 대량 데이터를 다룬다면 HBase를 도입해서 사용하는 것이

      좋을 것입니다.



본문 : http://gywn.net/2012/04/mysql-covering-index/


MySQL에서 커버링 인덱스로 쿼리 성능을 높여보자!!

안녕하세요.  오늘 짧지만 재미있는 내용을 하나 공유할까 합니다.

커버링 인덱스(Covering Index)라는 내용인데, 대용량 데이터 처리 시 적절하게 커버링 인덱스를 활용하여 쿼리를 작성하면 성능을 상당 부분 높일 수 있습니다.

커버링 인덱스란?

커버링 인덱스란 원하는 데이터를 인덱스에서만 추출할 수 있는 인덱스를 의미합니다. B-Tree 스캔만으로 원하는 데이터를 가져올 수 있으며, 칼럼을 읽기 위해 굳이 데이터 블록을 보지 않아도 됩니다.

인덱스는 행 전체 크기보다 훨씬 작으며, 인덱스 값에 따라 정렬이 되기 때문에 Sequential Read 접근할 수 있기 때문에, 커버링 인덱스를 사용하면 결과적으로 쿼리 성능을 비약적으로 올릴 수 있습니다.

백문이 불여일견! 아래 테스트를 보시죠.

테이블 생성

먼저 다음과 같이 테이블을 생성합니다.

create table usertest (
 userno int(11) not null auto_increment,
 userid varchar(20) not null default '',
 nickname varchar(20) not null default '',
 .. 중략 ..
 chgdate varchar(15) not null default '',
 primary key (userno),
 key chgdate (chgdate)
) engine=innodb;

약 1,000만 건 데이터를 무작위로 넣고 몇가지 테스트를 해봅니다.

커버링 인덱스(SELECT)

select chgdate , userno
from usertest
limit 100000, 100
************* 1. row *************
           id: 1
  select_type: SIMPLE
        table: usertest
         type: index
possible_keys: NULL
          key: CHGDATE
      key_len: 47
          ref: NULL
         rows: 9228802
        Extra: Using index
1 row in set (0.00 sec)

쿼리 실행 계획의 Extra 필드에 “Using Index” 결과를 볼 수 있는데, 이는 인덱스만으로 원하는 데이터 추출을 하였음을 알 수 있습니다.

이처럼 데이터 추출을 인덱스에서만 수행하는 것을 커버링 인덱스라고 합니다. 아시겠죠? ^^

그렇다면 일반 쿼리와 성능 테스트를 해볼까요?

커버링 인덱스(WHERE)

1) 일반 쿼리

select *
from usertest
where chgdate like '2010%'
limit 100000, 100

쿼리 수행 속도는 30.37초이며, 쿼리 실행 계획은 다음과 같습니다.

************* 1. row *************
           id: 1
  select_type: SIMPLE
        table: usertest
         type: range
possible_keys: CHGDATE
          key: CHGDATE
      key_len: 47
          ref: NULL
         rows: 4352950
        Extra: Using where

Extra 항목에서 “Using where” 내용은, Range 검색 이후 데이터는 직접 데이터 필드에 접근하여 추출한 것으로 보면 됩니다.

2) 커버링 인덱스 쿼리

select a.*
from (
      select userno
      from usertest
      where chgdate like '2012%'
      limit 100000, 100
) b join usertest a on b.userno = a.userno

쿼리 수행 시간은 0.16초이며 실행 계획은 다음과 같습니다.

************* 1. row *************
           id: 1
  select_type: PRIMARY
        table:
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 100
        Extra:
************* 2. row *************
           id: 1
  select_type: PRIMARY
        table: a
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: b.userno
         rows: 1
        Extra:
************* 3. row *************
           id: 2
  select_type: DERIVED
        table: usertest
         type: range
possible_keys: CHGDATE
          key: CHGDATE
      key_len: 47
          ref: NULL
         rows: 4352950
        Extra: Using where; Using index

Extra 에서 “Using Index”를 확인할 수 있습니다.

그렇다면 30초 넘게 수행되는 쿼리가 0.16초로 단축됐습니다. 왜 이렇게 큰 차이가 발생했을까요?

첫 번째 쿼리는 Where에서 부분 처리된 결과 셋을 Limit 구문에서 일정 범위를 추출하고, 추출된 값을 데이터 블록에 접근하여 원하는 필드를 가져오기 때문에 수행 속도가 느립니다.

두 번째 쿼리에서도 동일하게 Where에서 부분 처리된 결과 셋이 Limit 구문에서 일정 범위 추출되나, 정작 필요한 값은 테이블의 Primary Key인 userno 값입니다. InnoDB에서 모든 인덱스 Value에는 Primary Key를 값으로 가지기 때문에, 결과적으로 인덱스 접근만으로 원하는 데이터를 가져올 수 있게 됩니다. 최종적으로 조회할 데이터 추출을 위해서 데이터 블록에 접근하는 건 수는 서브 쿼리 안에 있는 결과 갯수, 즉 100건이기 때문에 첫 번째 쿼리 대비 월등하게 좋은 성능이 나온 것입니다.

커버링 인덱스(ORDER BY)

커버링 인덱스를 잘 사용하면 Full Scan 또한 방지할 수 있습니다. 대부분 RDBMS에는 테이블에 대한 통계 정보가 있고, 통계 정보를 활용해서 쿼리 실행을 최적화 합니다.

다음 재미있는 테스트 결과를 보여드리겠습니다. 전체 테이블에서 chgdate 역순으로 400000번째 데이터부터 10 건만 가져오는 쿼리입니다.

1) 일반 쿼리

select *
from usertest
order by chgdate
limit 400000, 100
************* 1. row *************
           id: 1
  select_type: SIMPLE
        table: usertest
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 9228802
        Extra: Using filesort
1 row in set (0.00 sec)

분명 인덱스가 있음에도, Full Scan 및 File Sorting이 발생합니다. 인덱스를 태웠을 때 인덱스 블록을 읽어들이면서 발생하는 비용보다 단순 Full Scan이 더 빠르다고 통계 정보로부터 판단했기 때문이죠. 인덱스도 데이터라는 것은 항상 기억하고 있어야 합니다^^

결과 시간은 책정 불가입니다. (안끝나요~!)

2) 커버링 인덱스 쿼리

위 결과와 다르게 커버링 인덱스는 조금 더 재미있는 결과를 보여줍니다.

select a.*
from (
      select userno
      from usertest
      order by chgdate
      limit 400000, 100
) b join usertest a on b.userno = a.userno
************* 1. row *************
           id: 1
  select_type: PRIMARY
        table:
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 100
        Extra:
************* 2. row *************
           id: 1
  select_type: PRIMARY
        table: a
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: b.userno
         rows: 1
        Extra:
************* 3. row *************
           id: 2
  select_type: DERIVED
        table: usertest
         type: index
possible_keys: NULL
          key: CHGDATE
      key_len: 47
          ref: NULL
         rows: 400100
        Extra: Using index

File Sorting이 발생하지 않고 커버링 인덱스가 사용되었으며, 실행 시간 또한 0.24초로 빠르게 나왔습니다.^^

Conclusion

커버링 인덱스는 InnoDB와 같이 인덱스와 데이터 모두 메모리에 올라와 있는 경우에 유용하게 쓰일 수 있습니다. 물론 커버링 인덱스가 좋기는 하지만, 커버링 인덱스를 사용하기 위해 사용하지 않는 인덱스를 주구장창 만드는 것은 최대한 피해야 하겠죠^^

잊지마세요. 인덱스도 데이터라는 사실을..


'DataBase > MySQL' 카테고리의 다른 글

MySQL 정규식으로 치환 함수  (0) 2017.02.02
UNIXTIME 관련 함수  (0) 2017.02.02
[펌] 커버링인덱스  (0) 2016.04.24
[링크] MySQL에서 사용하는 Lock 이해  (0) 2015.09.22
MySQL Split - 문자열 자름 처리.  (0) 2015.09.21
참조키 강제 해제  (0) 2015.06.03

INSERT INTO OPENQUERY([LINKED SERVER], '  SELECT [COLUMNS] FROM [TABLE]')
VALUES ~ SELECT [ '이건 입맛대로~' ]

* INSERT, UPDATE, DELETE, SELECT 모두 OPENQUERY(연결된 서버, 'SQL문자열') 로
동일합니다.

출처 : http://sqlsql.tistory.com/391



64bit sql server 에 excel 2013을 링크드 서버나 직접쿼리를 할 때 

일단 드라이버를 깔아야 한다. http://www.microsoft.com/en-us/download/details.aspx?id=13255


그런 후, 드라이버의 inprocess 설정을 한다. 

USE [master]

GO

EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0' , N'AllowInProcess' , 1

GO

EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0' , N'DynamicParameters' , 1

GO


계정설정 

혹시 NT Service\MSSQL$SQL2012 이런식으로 되어 있으면 -> 로컬시스템으로 바꾼다. ㅠ.,ㅠ

아니면 해당 폴더에 위 계정이 액세스 가능하게 하면 될 듯 하다. appdata\local\temp 역시 권한이 필요한듯 

이런거 다 귀찮으면 로컬 시스템으로 변경~


NT Service\MSSQL$SQL2012 였을때 에러 메시지 

연결된 서버 "(null)"의 OLE DB 공급자 "Microsoft.ACE.OLEDB.12.0"이(가) 메시지 "지정되지 않은 오류입니다."을(를) 반환했습니다.

메시지 7303, 수준 16, 상태 1, 줄 31

연결된 서버 "(null)"에 대한 OLE DB 공급자 "Microsoft.ACE.OLEDB.12.0"의 데이터 원본 개체를 초기화할 수 없습니다.


링크드 서버 연결 명령어 

/****** Object:  LinkedServer [bb]    Script Date: 2015-04-23 오전 11:08:34 ******/

EXEC master.dbo.sp_addlinkedserver @server = N'bb', @srvproduct=N'ACE', @provider=N'Microsoft.ACE.OLEDB.12.0', @datasrc=N'c:\sqltag\Book1.xlsx', @provstr=N'Excel 12.0; HDR=Yes'

 /* For security reasons the linked server remote logins password is changed with ######## */

EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'bb',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL

GO


인프로세스 쿼리 방법 

SELECT * FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0', 'Data Source=c:\sqltag\Book1.xlsx;Extended Properties=Excel 12.0')...[Sheet1$]


SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0; HDR=YES; IMEX=1; Database=F:\cmdb\fault티켓\Book1.xlsx', 'SELECT * FROM [Sheet1$]')


SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0; 

HDR=YES; IMEX=1; Database=\\127.0.0.1\f$\cmdb\fault티켓\FQ261_2011.xlsx', 'SELECT * FROM [sheet1$]')


SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0; 
HDR=NO; IMEX=1; Database=c:\sqltag\Book1.xlsx', 'SELECT * FROM [Sheet1$]')

SELECT * FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0', 'Data Source=\\127.0.0.1\c$\sqltag\Book1.xlsx;Extended Properties=EXCEL 12.0')...[Sheet1$] ;


-- 읽어보기 귀찮다.

-- 스타트 계정 로컬시스템으로 변경 후
exec sp_configure 'Ad Hoc Distributed Queries', 1
reconfigure with override

USE [master]
GO
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0' , N'AllowInProcess' , 1
GO
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0' , N'DynamicParameters' , 1
GO

SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0; HDR=YES; IMEX=1; Database=C:\event\faultPrco_2010q1.xls', 'SELECT * FROM [data$]')

메시지 7347, 수준 16

LINKED SERVER (연결된 서버) 를 통하여 쿼리시 (OPENROWSET, OPENQUERY)


오라클이나 MySQL 에서  "예상 데이터 길이와 일치하지 않는 데이터를 반환했습니다." 라는

메세지는 지금까지의 경험(짧은^^;;) 으로는 숫자형의 데이터를 문자형으로 전환하면

되었던 것 같다.

참 깔끔하게 포스팅 되어 있습니다. 블로그도 깔끔하구요~

http://blog.saltfactory.net/database/introduce-mysql-lock.html

'DataBase > MySQL' 카테고리의 다른 글

UNIXTIME 관련 함수  (0) 2017.02.02
[펌] 커버링인덱스  (0) 2016.04.24
[링크] MySQL에서 사용하는 Lock 이해  (0) 2015.09.22
MySQL Split - 문자열 자름 처리.  (0) 2015.09.21
참조키 강제 해제  (0) 2015.06.03
참조키 선언시 에러  (0) 2014.11.26

MySQL 에도 split 이 있다.

SUBSTRING_INDEX


1. 대상 예제 쿼리 및 결과


SELECT *
FROM (
	SELECT
		1                        AS seq,
		'Welcome To JKUN.NET|^^' AS message
	UNION ALL
	SELECT
		2                        AS seq,
		'Welcome To JKUN.NET|^^' AS message
	UNION ALL
	SELECT
		3 AS seq,
		'Welcome To JKUN.NET|^^' AS message
) AS EX;



2. SUBSTRING_INDEX 적용 쿼리 및 결과


SELECT 
	seq,
	message,
	SUBSTRING_INDEX(message, '|', 1) as first,
	SUBSTRING_INDEX(message, '|', -1) as second
FROM (
	SELECT
		*
	FROM (
		     SELECT
			     1                        AS seq,
			     'Welcome To JKUN.NET|^^' AS message
		     UNION ALL
		     SELECT
			     2                        AS seq,
			     'Welcome To JKUN.NET|^^' AS message
		     UNION ALL
		     SELECT
			     3                        AS seq,
			     'Welcome To JKUN.NET|^^' AS message
	     ) AS EX

) AS EX_SPLIT;



대단한건 아니지만 까먹으니 포스팅을 할 수밖에;;

'DataBase > MySQL' 카테고리의 다른 글

[펌] 커버링인덱스  (0) 2016.04.24
[링크] MySQL에서 사용하는 Lock 이해  (0) 2015.09.22
MySQL Split - 문자열 자름 처리.  (0) 2015.09.21
참조키 강제 해제  (0) 2015.06.03
참조키 선언시 에러  (0) 2014.11.26
우분투에서 mysql 삭제 후 재설치  (0) 2014.11.26

후;; 데이터베이스 스키마 일괄생성 스크립트를 모르고 mysql 데이터베이스에 돌렸다;;

아;;;;; 했는데

지우는게 있드만;;

#관계 체크 해제
SET foreign_key_checks = 0;

#관계 체크 설정
SET foreign_key_checks = 1;


ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)


참조키를 생성하는데 위와 같은 에러가 발생한다.

확인한 바 발생한 이유는 


테이블 생성시 참조하는 원본 테이블에는 INT UNSIGNED 가 되있는데

참조하는 테이블에서는 그냥 INT 가 되있었다. 해서 다시 수정하니 정상적으로 작동을 했는데,

구글링을 하다보니 깔끔하게 포스팅 해주신 분이 있어 링크 올립니다.^^


http://opentutorials.org/module/894/6653


어?? 오픈튜토리얼이네? ㅎㅎㅎ

'DataBase > MySQL' 카테고리의 다른 글

MySQL Split - 문자열 자름 처리.  (0) 2015.09.21
참조키 강제 해제  (0) 2015.06.03
참조키 선언시 에러  (0) 2014.11.26
우분투에서 mysql 삭제 후 재설치  (0) 2014.11.26
MySQL Stored Procedure (저장프로시저)  (2) 2014.03.28
임시테이블 - Temproray Table  (0) 2014.03.26
apt-get purge mysql-server
apt-get purge mysql-common
rm -rf /var/log/mysql
rm -rf /var/log/mysql.*
rm -rf /var/lib/mysql
rm -rf /etc/mysql
# and then:
apt-get install mysql-server --fix-missing --fix-broken

출처 : http://ykcho.tistory.com/20

'DataBase > MySQL' 카테고리의 다른 글

참조키 강제 해제  (0) 2015.06.03
참조키 선언시 에러  (0) 2014.11.26
우분투에서 mysql 삭제 후 재설치  (0) 2014.11.26
MySQL Stored Procedure (저장프로시저)  (2) 2014.03.28
임시테이블 - Temproray Table  (0) 2014.03.26
MySQL 에러처리  (0) 2014.03.26

MySQL 저장프로시저

내가 익숙치 않거나 못해서 그런걸수도 있지만 정말로 쓰다보니.. 많이 부족함과 불편함이 이만 저만이 아니다.

그리고 너무 많은 구글링 필요하다;;

MySQL 저장프로시저를 만들고 사용하다 보면 MS-SQL Server 와 오라클의 저장프로시저가 너무나 그리워

진다. 역시.. 돈들여서 안좋은건 없다고.. 다시한번 또..새삼스럽게..ㅎㅎ

일단 샘플로 간단하게 MySQL 저장프로시저 올린다.



DELIMITER $$

DROP PROCEDURE IF EXISTS SP_EMP_DPT_UPDATE $$
CREATE PROCEDURE SP_EMP_DPT_UPDATE(
	IN_UNION_QUERY_TEXT VARCHAR(1500),
	IN_EMP_NO INT,
	OUT OUT_RETURN_VALUE TINYINT
)
BEGIN
	DECLARE INSERT_QUERY_STRING VARCHAR(1500);
	DECLARE CATCH_ERROR TINYINT;	
	DECLARE EXIT HANDLER FOR SQLEXCEPTION SET CATCH_ERROR = -1;

	SET AUTOCOMMIT = 0;
	SET SQL_SAFE_UPDATES = 0;

	START TRANSACTION;

	DROP TEMPORARY TABLE IF EXISTS TEMP_MEMBER_EMP_DPT;
	CREATE TEMPORARY TABLE TEMP_MEMBER_EMP_DPT (
		EMP_DPT_NO INT,
		EMP_NO INT,
		DPT_NAME VARCHAR(100),
		DPT_AUTH TINYINT
	) engine = memory;

	SET @INSERT_QUERY_STRING = CONCAT("INSERT INTO TEMP_MEMBER_EMP_DPT (EMP_DPT_NO, EMP_NO, DPT_NAME, DPT_AUTH) ", IN_UNION_QUERY_TEXT);

	PREPARE STMT FROM @INSERT_QUERY_STRING;	
	EXECUTE STMT;
	DEALLOCATE PREPARE STMT;	

	UPDATE MEMBER_EMP_DPT AS A INNER JOIN TEMP_MEMBER_EMP_DPT AS B
		ON A.EMP_DPT_NO = B.EMP_DPT_NO
	SET A.DPT_NAME = B.DPT_NAME
	WHERE A.EMP_NO = IN_EMP_NO;

	INSERT INTO MEMBER_EMP_DPT (EMP_NO, DPT_NAME, DPT_AUTH)
	SELECT EMP_NO, DPT_NAME, DPT_AUTH
		FROM TEMP_MEMBER_EMP_DPT
	WHERE EMP_DPT_NO NOT IN (SELECT DISTINCT EMP_DPT_NO
							 FROM MEMBER_EMP_DPT
							 WHERE EMP_NO = IN_EMP_NO)
		AND EMP_NO = IN_EMP_NO;

	IF CATCH_ERROR < 0 THEN
		ROLLBACK;
		SET OUT_RETURN_VALUE = 0;
	ELSE
		COMMIT;
		SET OUT_RETURN_VALUE = 1;
	END IF;


	DROP TEMPORARY TABLE IF EXISTS TEMP_MEMBER_EMP_DPT;
	
	SELECT OUT_RETURN_VALUE;
END$$

#DELIMITER ;

'DataBase > MySQL' 카테고리의 다른 글

참조키 선언시 에러  (0) 2014.11.26
우분투에서 mysql 삭제 후 재설치  (0) 2014.11.26
MySQL Stored Procedure (저장프로시저)  (2) 2014.03.28
임시테이블 - Temproray Table  (0) 2014.03.26
MySQL 에러처리  (0) 2014.03.26
저장 프로시저 관련 포스팅  (0) 2014.03.26
  1. 자바맨 2014.06.18 00:52 신고

    감사합니다. 여태껏 mysql sp 땜시 개고생중이었어요.
    잘 배우고 갑니다.^^

참고링크

MySQL에서 Temporary Table을 활용한 데이터 질의..그 효과는?

java + temporary table. 임시테이블 사용하기. MYSQL


CREATE TEMPORARY TABLE IF NOT EXISTS TEMP_TABLE (

       ID BIGINT(20) NOT NULL 

)

+ Recent posts