Clean Code that Works.

이번에도 읽어 볼만한 글을 간단하게 번역해봤습니다.

http://javarevisited.blogspot.in/2014/05/how-string-in-switch-works-in-java-7.html


Java 7의 특징중에 하나로 Switch 구문에서 문자열을 사용할 수 있는데요.

이 원리에 대해서 설명한 내용입니다. :)


3줄 요약하면

1. Switch 에서 문자열을 사용했을 경우에 컴파일된 코드를 보면 hash code 와 equals() 를 사용해서 구분을 한것을 알 수 있다.

2. equals()를 사용해서 값을 확인을 한번 더 하기 때문에 숫자형이나 열거형을 사용했을경우 보다 연산이 +1 되고, 대소문자 문제 및 카멜표기법에 따른 문제 등이 발생한다.

3. 그러므로 문자열 보다는 숫자형이나 열거형을 사용하는 것이 좋고 열거형이 가독성과 코드 품질에 더 좋기 때문에 열거형을 사용하는 것이 좋다.


가볍게 읽어보세요 


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


Java의 switch 구문에서 문자열을 사용할 수 있게 됨으로써 숫자형이나 열거형을 쓰는 것 보다 더 사용하기가 쉬어서 많은 프로그래머들이 이를 사용한다. 이 기능은 자동 리소스 관리 및 다중 오류 catch blocks 를 포함해서 JDK 7의 기능중에 가장 유명한 기능중 하나다. 


Java 프로그램에서 문자열을 사용함으로써 주는 한가지 편의점은 간단하게 사용할 수 있다는 것이다. 하지만 새로운 내용에 대한것을 실제 제품 코드에 적용하기전에 나는  이 내용에 대해 조금 더 알아보는것을 선호 한다. 내가 이 기능에 대해서 처음 알았을 때 equals() 와 hashcode()를 사용하면 switch에서 문자열 사용하기를 구현할 수 있을 거라는 생각이 들었다. 그래서 Java 7 에서 문자열이 어떻게 Switch 에서 사용할 수 있게 됬는지 관심을 가지게 됬다. 한가지 더 이슈는 Java 면접을 진행할 때 질문을 하기 위해서 였고, 이런 질문을 가지고 있는 면접이 좀 더 흥미롭게 진행 될 수 있다.(간단하지만 흥미로운 질문이긴 하네요)


테스트는 간단하다. 그냥 코드를 Switch 블럭에서 문자열로 작성하면 되고 이 코드들을 디컴파일 해서 컴파일러가 이 코드들을 어떻게 변환했는지 보면 된다. 


파일되기 전 코드

아래 코드는 main 메서드에 switch 블럭을 가지고 있고 문자열을 포함한 간단한 테스트 코드다. String 변수가 프로그램이 동작할시 제공된다. 아래 테스트 코드는 3가지 모드(Activce, Passive, Safe)를 가지고 있다. 


고정값을 사용할 경우에는 열거형을 사용하는게 더 좋지만 문자열을 사용하기로 결정했다면 소문자 및 카멜 표기법으로 변수를 표시했을때 문제가 발생할 수 있으므로 대문자로 작성 하도록 한다. 


/**

* Java Program to demonstrate how string in switch functionality is implemented in * Java SE 7 release. 

*/ 

public class StringInSwitchCase 

public static void main(String[] args) { 

String mode = args[0]; 

switch (mode) { 

case "ACTIVE": 

System.out.println("Application is running on Active mode"); 

break

case "PASSIVE": 

System.out.println("Application is running on Passive mode"); 

break

case "SAFE": 

System.out.println("Application is running on Safe mode"); 

}

}


JDK 1.7을 설치해서 컴파일하고 코드를 실행해본다. JDK 7 어느 버전에서든 동작 한다.


디컴파일 된 코드

아래 코드는 jdk 1.7.0_40 버전에서 컴파일된 소스를 디컴파일 한 것이다. 만약 당신이 자바를 처음 접하고 자바 클래스파일을 디컴파일에 리버스 엔지니어링을 어떻게 하는지 알고 싶다면 이 게시글을 참조하라. 


새로운 버전이 계속 나오면서 문섭들이 점점 더 편리해지고 쉬어 지기 때문(설탕 문법, syntactic sugar)에 이를 확실하게 알려면 모든 레벨의 자바 프로그래머들에게 클래스를 디컴파일하는 방법을 아는것은 매우 중요하다. 


/** * Reverse Engineered code to show how String in Switch works in Java. */ 

import java.io.PrintStream


public class StringInSwitchCase

public StringInSwitchCase() { } 

public static void main(string args[]) { 

String mode = args[0]; 

String s; 

switch ((s = mode).hashCode()) { 

default: break

case -74056953: 

if (s.equals("PASSIVE")) { 

System.out.println("Application is running on Passive mode"); 

}

break

case 2537357: 

if (s.equals("SAFE")) { 

System.out.println("Application is running on Safe mode"); 

} 

break

case 1925346054: 

if (s.equals("ACTIVE")) { 

System.out.println("Application is running on Active mode"); 

break

}

}


이 코드에서 문자열이 hashCode()와 equals() 메서드를 사용하는걸 볼 수 있다. 

JAVA 7 이전에 swich 구문에서는 byte, short, car 및 int 만 사용가능했던걸 되세겨보자. 


코드를 자세히 들여다 보면 swich는 해쉬 코드 와 eqauls()메서드를 통한 비교를 하고 있다. 이 검사는 꼭 필요한데 두개의 유니크한 오브젝트도 같은 hashcode 값을 가질 수 있다. 성능으로 따지면 열거형을 사용하는 것이나 숫자형을 사용하는 것 만큼 빠르지 않지만 모든 부분에서 아주 좋지 않은것은 아니다. 

자바 컴파일러는 문자열을 비교할때 매우 빠르게 할 수 있는 equals()를 사용한다.("abc" == "abc"). hashcode()메서드를 사용하는 경우에는 코드가 이미 생성되어 있기 때문에 1번더 추가적인 시간이 소모된다. 문자열은 그들의 hash code를 캐시한다. 그래서 이 코드가 hash code를 호출하는 비용은 크지 않을 것이다. 

그럼에도 불구하고 나는 여전히 Switch 에서 문자열을 사용하거나 고정된 숫자값을 사용하는것은 좋은 방법이 아니라고 본다. 자바는 이러한 이유때문에 열거형이라는 타입을 제공하고 모든 자바 프로그래머는 되도록 열거형을 사용하는 것이 좋다.


이게 Java 7의 Switch 구문에 문자열이 어떻게 동작하는지에 대한 것이다. 

예상했던 대로 전환을 하기 위해 hashCode()를 사용하고 검증을 하기 위해서 equals()를 사용한다. 이것은 문법적으로는 심플 하지만 오히려 기본 성능보단 느리다. 


결국 선택은 사용자의 몫이다. 나는 개인적으로 Switch 구문에서 문자열을 사용하는것(다루기 힘든 코드, 대소문자 문제, 값 검증을 위한 컴파일 시간 문제)에 대해 좋아하는 사람은 아니다.


사실 숫자 정수와 열거형 타입은 성능이 중요한 코드에서 내가 좋아 하는 방법이다. 가독성과 코드 품질이 더 중요하다.

실제로는 99.99%로 열거형을 쓰는게 문자열이나 숫자형을 사용하는 것보다 좋다. 

이전에 인덱스를 가지고 값을 찾을 때

findByPropertyValue()를 썼는데 이게 deprecated 됬다.


SDN 3 부터는 Scheme base 인덱스를 사용하는데.... 
findBySchemaPropertyValue() 이걸 사용하면 된다.


("파라미터로는 해당 모델(스키마)의 변수명", "찾을 값") 두개를 주면 되고 해당 변수에 @Indexed 가 붙어 있어야 된다.
@Indexed(unique=true)로 지정하게 되면 유니크 인덱스가 된다.

eBay and Wallmart Adopt Neo4j : The Graph is Transforming Retail

오늘(3월 18일) 이베이와 월마트같은 소매 유통 업체에서 Neo4j를 활용한 미션 크리티컬한 비즈니스 애플리케이션을 개발하여 큰 성공을 거두었다고 Neo4의 개발사인 Neo Technology에서 발표 했다. 이베이는 전 세계에 위치한 고객들에게 자사의 인기있는 서비스인 당일 배송 서비스를 개선하기 위해 Neo4j를 사용한다. 월마트는 온라인 쇼핑객 구매 행동을 분석하여 최적화된 연관 상품들을 제공하기 위해 Neo4j를 사용한다.

이베이는 대략 75% 소비가 고객의 집에서 15마일이내에서 발생한다는 것을 알고 지역 상권을 재정의 하는 대담한 목표를 가지고 있었다.  전자 상거래는 빠르고 편리하지만 배송은 불편했다. 당일 배송 시스템의 출현으로 지역 상업의 모든 행위가 마비될 것으로 보인다. 온라인 쇼핑과 오프라인 매장의 소비자 경험간의 융합은 소매 업체와 고객사이의 원할한 관계를 만들어 상거래 혁명을 일으키고 있다. 유연하고 빠르고 사용하기 쉽도록 하기 위해 Neo4j는 소매상과 온라인 고객사이의 가장 큰 방해물을 제거할 수 있도록 했다. 

이베이의 폭발적인 성장과 새로운 기능들로 인해 가능한 가장 빠르고 확실한 배송을 위해 이베이의 서비스 플랫폼을 새롭게 구성할 필요가 있었다. 이전 시스템인 MySQL은 너무 느리고 계속 유지하기엔 복잡하고 배송을 위한 최적의 경로를 찾는 쿼리의 수행시간이 너무 길었다. 이베이의 개발팀은 그래프데이터베이스가 성능과 확장에 대한 문제점을 해결하기 위해 기존의SOA 및 서비스 구조에 추가될 수 있다는 것을 알았다.  이 팀은 그래프데이터베이스 시장의 최적의 해결책인 Neo4j를 사용했다.

우린 말그대로 이전 MySQL보다 천배이상 빠르고 10~100번정도 적은 코드로 수행되는 Neo4j를 사용했다. 오늘날 Neo4j는 이전의 이베이에서는 불가능했던 기능들을 지원한다.

- Volker Pacher, Seniro Developer at eBay.


월마트 같은 대형 유통업체도 Neo4j를 사용한다. 과거에 소비자들은 마케팅 형태로 제조업체에서 제공하는 정보에 크게 의존했었다. 요즘은 소비자들이 생성한 제품에 관한 리뷰와 구매에 대해서 소셜 미디어에 상담하는 등 다른 정보를 가지고 있다. 소비자간의 정보의 풍요로움과  전문가의 의견에 따른 전에 없던 가용성은 소비자들을 좀 더 다양한 제품에 대한 경험을 가질수 있게 하고 그들이 사용하거나 소유하려고 고유하는 경향에 대하여 결정할 수 있게 해준다. 이렇게 서로 연결된 모든 데이터들을 이해하기 위하여 월마트는 Neo4j 그래프 데이터베이스를 사용한다.

"Neo4j는  우리가 이해하려고 했던 온라인 고객들의 성향과 고객 및 상품간의 관계에 대하여 실시간 상품 추천을 위한 완벽한 기능을 제공한다. 그래프 데이터베이스 시장의 선두주자이고 확장성과 가용성에 대한 고급 기능들을 제공하는 Neo4j는 우리들의 요구사항을 충족시키는 완벽한 제품이다."

- Marcos Wada, Software Developer at Walmart

그래프는 어디든지..그것은 바로 Neo4j

그래프는 산업 전반에 걸친 다루기 힘든 기술적인 문제에 대한 해결 방안으로 공공연하게 인정받고 있다. DB-Engines에 따르면 Neo4j는 가장 인기있는 그래프데이터베이스다.
firm에 따르면 "데이터베이스 관리 시스템중에 작년에 비해 자신의 인기가 가장 증가했는가 볼때 250% 증가한 그래프 데이터베이스는 명백한 승자라고 볼 수 있다."

이베이의 케이스 스터디는 http://www.neotechnology.com/ebay 을 참조.


이번에 만들어본 인터넷 차계부.

기존에 쓰던 차계부 어플이 너무 불편해서.. 그냥 모바일도 지원되는 버전으로 만들었다.

http://mycarcare.kr

PC, 태블릿 버전은 동일한 UI로 지원하고, 모바일 버전은 모바일 UI로 제공한다.

그래프 데이터베이스와 Neo4j

그래프 데이터 베이스와 Neo4j에 대해서는 아래의 그림 한장으로 설명 될 수 있습니다.
차분히 읽어 보면 개념 자체는 어렵지 않습니다. ㅎㅎ

아래 동영상은 Neo4j의 공동 설립자인 Emil Eifrem이 설명하는 그래프 데이터베이스입니다.


그럼 본론으로 들어가서..
아래 내용들은 Neo4j.org 에 있는 글들을 번역한 것입니다.
되게 어렵게 설명해서 발번역이 됬네요. ㅋ
직접들어가서 한번 보는것도 추천 드립니다.


그래프 데이터베이스란 무엇인가?

그래프 데이터베이스는 데이터를 그래프에 저장하고 데이터의 구조가 가장 일반적이고, 우아하고 높은 접근 방식으로 모든 데이터를 표현할 수 있다.

그래프에 대해 설명하는 몇가지 그래프들을 보도록 하자. 다이어그램 주위의 화살표를 따라 읽으면 문장을 형성해서 그래프를 읽을 수 있다.

그래프는 Nodes 와 Relationships 을 가지고 있다.

A Graph-[:RECORDS_DATA_IN]->Nodes-[:WHICH_HAVE]->Properties.
가장 심플한 그래프는 한개의 노드로 표현할 수 있다. 프로퍼티라는 값으로 정의 될 수 있다.
약간 평범하지 않은 이야기이긴 하지만 노드는 한개의 속성을 가지고 시작해서 몇 백만개까지 증가할 수 있다. 
이렇게 하는 것 보다는 명시적인 관계로 조직된 다수의 노드로 나누는게 좋다.

위 그래프를 화살표를 따라 읽으면 

A Graph는 Nodes 와 Relationships으로 기록 되고, 각각 Node들은 Relationship으로 조직될 수 있다. 
또 Nodes와 Relationships 은 각각 별도로 속성을 가질 수도 있다.


순회를 통해 그래프에 조회 하기

A Traversal - navigates -> a Graph; it - identifies -> Paths - which order -> Nodes.

순회는 그래프에 어떻게 질문을 하는가 라고 말할 수 있다.
알고리즘에 따라 시작 노드 부터 관계가 있는 노드까지 탐색하고, 아래와 같은 질문에 대한 답을 찾을 수 있다. 
"내 친구가 좋아 하는 음악중에 내가 가지고 있지  않은것은 무엇인가?"
"만약 이 파워 서플라이가 다운되면 웹 서비스에 끼치는 영향은 무엇인가?"



노드와 관계에 대한 인덱스.

An Index - maps from -> Properties - to either -> Nodes or Relationships. It - is a special -> Traversal

가끔 특정 노드나 관계에 저장된 속성들에 대해 찾아야할 때가 있다. 
"Account 중에서 사용자 이름이 '그래프 마스터'인 것에 대해 찾아라" 같은 순회 방식은 가장 일반적인 방식으로 인덱스 룩업에 최적화 되어 있다. 

Neo4J란 무엇인?

Neo4j는그래프 데이터베이스로 신뢰할 수 있고 끈끈하게 연결된 데이터들에 대해 빠르게 관리 및 조회할 수 있다.
Neo4j 는 오픈소스 그래프데이터베이스로 Neo Technology에서 제공한다.
Neo4j 속성들과 함께 다양한 관계들과 연결된 노드들을 직접 저장한다.

주요 특징

  • 직관적 : 데이터를 표현하기 위해 그래프 모델을 사용

  • 믿을수 있는 : FULL ACID 트랜잭션을 제공

  • 빠르고 안전한 : 커스텀 디스크와 네이티브 스토리지 엔진 

  • 대규모 확장 : 수십억개의 노드/관계/속성

  • 고 가용성 : 다양한 머신에 분산

  • 사람이 읽기 편한 그래프 

  • 쿼리 

  • 빠른 속도의 그래프 쿼리를 통산 빠른 검색 속도

  • 몇개의 작은 jar 파일들로 서버 세팅 가능

  • 간편 함 : REST interface를 통한 API 제공 및 OOP한 Java API 제공











팀내 공유 했던것 가볍게 정리.


발표 자료 : http://prezi.com/k56wvgphtmix/big/?utm_campaign=share&utm_medium=copy

프레지 자료라.. 읽을 내용이 없습니다. OTL

"생각은 언어로 표현되는 순간 죽어 버린다" 라는 말이 있는데요. 

팀 세미나를 말로 진행했었는데 글로 쓰려니 영 표현이 안되네요 ^^; 


왜 이책을 읽게 되었나?

제가 처음 빅데이터 관련해서.. 읽었던 책이 지금은 3판까지 나온 한빛미디어 출간 Hadoop 완벽 가이드 입니다. 이 책이 처음 출간 되었을 때는 빅데이터에 대한 내용들이 국내에 서서히 알려지기 시작했고 점점 관심있는 사람들이 늘어나기 시작했었습니다. 아무튼 이 책을 한 반절 정도 읽다가 말았다가 작년에 다른 하둡책을 사서 vmware에 우분투를 설치해서 책에 있는 내용을 실습해 봤습니다. 워드카운팅이라던지 기타 등등...


그런데 한달 정도 지나니깐 다 잊어 버렸습니다. -_-;

배웠는데 써먹을 곳이 없으니까 잊어 버린거죠. 그래서 좀 생각을 해 보니.. 내가 너무 빅 데이터의 기술(하둡)에만 집착하고 있는 것이 아닌가.. 과연 빅데이터가 무엇이고 기술적인 관점이 아닌 비즈니스 적인 관점에서 보면 어떻게 될까, 써먹을 곳을 찾아 볼 수 있을까 하고 생각하다가 이 책을 읽게 되었습니다.


제가 생각하는 이 책에서 가장 큰 핵심은 "빅 데이터의 시작은 모델과 시나리오를 만드는 것" 입니다. 

개발자의 마인드에서 빅데이터에 대한 공부를 할때 기술서적을 먼저 보면서 시작 하는 것도 좋지만 빅데이터가 과연 무엇이고 어떻게 써야 하는지 이것을 잘 생각해서 단순히 워드 카운팅이 아닌 진짜 쓸만한 모델과 시나리오를 만들어 보고 이것을 가지고 시작하면 좋을 것 같습니다.


WHY?

그럼 왜 빅데이터가 이렇게 관심을 끌게 되었는지 생각해보면 전체적인 시대의 흐름과 기술의 발전이 빅데이터 시대를 가속화 했다고 볼 수 있습니다.



가트너에 따르면 2020년에 스마트폰과 태블릿, PC 를 제외한 약 260억개의 디바이스가 인터넷에 연결되고 이것들을 포함하면 약 500억에서 750억개의 디바이스가 인터넷에 연결된다고 합니다. 이러한 디바이스들은 다양한 데이터들을 생산하게 되고 이렇게 생산된 데이터들이 빅 데이터가 됩니다.


그리고 이렇게 생성된 빅데이터들을 저장하고 처리하기 위한 시스템들의 가격도 많이 낮아져서 빅데이터가 관심을 끌 수 있는 한가지 원인이 됩니다. 

CPU, STORAGE, NETWORK, BANDWIDTH 이 하드웨어들의 가격은 시간이 지날수록 성능은 향상되고 가격은 낮아지기 때문에 합리적인 가격으로 매우 많은 양의 데이터들을 처리 할 수 있게 됩니다.


이렇게 다양한 디바이스이 만들어낸 데이터들과 이를 처리할 수 있는 하드웨어들의 성능향상과 비용감소에 따라 데이터에서 새로운 가치를 뽑아 낼 수 있기때문에 빅데이터가 인기를 끌게 됩니다. 


구글의 수석 과학자 이런 말을 했다고 하네요.

"우리는 남보다 더 나은 알고리즘을 가진것이 아니다. 단지 우리는 더 많은 데이터가 있을 뿐이다."

물론 더 나은 알고리즘도 가지고 있겠지만 -ㅁ-;; 데이터가 얼마나 중요한지 강조 하고 있습니다.


WHAT? 


그럼 빅데이터는 무엇인가?

IT 시장 전문 리서치 업체인 IDC에서는 아래와 같이 정의 하고 있습니다.


"빅데이터는 클라우드 컴퓨팅과 대형 메모리 모델의 변화를 포함한 하드웨어 기능의 변화와 플랫폼 변경에 따른 데이터 처리 능력과 비용을 극대화하기 위한 기술 범위의 발현이다"


단순히 볼륨이 큰 데이터를 의미 하는것이 아니라 데이터 처리 속도, 데이터 관리 인프라등 여러가지 사항을 만족 해야 빅데이터라고 볼 수 있습니다.


최근에 IDC는 빅데이터를 분석 관점인 BI(Business Intelligence)측면에서 대규모의 데이터로부터 매우 빠르게 데이터를 추출, 발굴, 분석하여 가치를 경제적으로 찾아낼 수 있는 새로운 기술과 차세대 아키텍처라고 정의 하였습니다. 


그럼 빅데이터의 특징을 정의 할 수 있는 4가지 V(보통 이 4가지를 충족하면 빅데이터로 볼 수 있습니다)에 대해서 알아 보도록 하겠습니다.



위 이미지에 설명이 잘 되어 있네요!

여기를 참조 하시면 됩니다. http://dashburst.com/infographic/big-data-volume-variety-velocity/


간략히 정리 해 보면 

VOLUME : Big data is big. 말그대로 BIG 해야 겠죠. 2020년에는 40제타 바이트정도가 될꺼라고 예상한다고 합니다.(1제타 바이트 = 뉴욕 맨하탄의 20% 규모의 서버)

VELOCITY : 보통 한사람당 2.5정도의 네트워크 커넥션을 가지고 있고 엄청난 양의 데이터를 생산해 냅니다. 이것들을 신속하게 분석 해야 겠죠.

VARIETY : 다양한 형태의 데이터들. 지금 당장만 하더라도 YouTube에 40억 시간의 비디오가 올라와있고 페이스북을 통해 한달에 공유되는 내용만 해도 300억 건에 다랍니다.

VERACITY : 데이터의 불확실성. 데이터가 늘어난 만큼 쓸모있는 데이터를 뽑아내는 것도 중요합니다. 북미에서 매년 3조 천억 달러정도가 데이터를 검증하는데 소모 된다고 합니다. 이 때문에 데이터 분석학자들이 많이 필요 하다고 합니다.


HOW?

그럼 빅데이가 무엇인지 대충 감을 잠았으니..어떻게 활용할 것인지 생각해 보도록 하죠.

빅데이터의 주요 니즈와 활용에 대해 아래와 같이 간략히 정리 할 수 있습니다.


1. 대량 데이터 분석과 거래량 처리는 매우 복잡하고 광범위한 데이터베이스의 로직 및 도식을 필요로 함

2. 다량의 정형/비정형 데이터 수집 및 분석 필요

3. 동시에 수 천명의 웹 어플리케이션 사용에 따른 대용량 데이터 관리 필요.

4. 조직관련 데이터는 방대한 네트워크 및 엔티티 유형을 포괄함. 


이러한 비즈니스 활용 시나리오로는 고객 행동분석을 통한 고객이탈 방지, 소셜 네트워크에는 감성 분석을 통해 상품, 서비스에 관한 긍정적인지 부정적인지 어떤 반응을 하는지에 관한 분석이 있습니다. 쇼핑몰에서는 비슷한 취향의 아이템을 추천하는 교차판매 엔진같은게 있을 수 있고, 인터넷의 클릭스트림을 분석하고 로그 데이터의 마이닝을 통해 악의적인 부정과 인터넷 범죄자들을 찾는데 도움이 될 수도 있습니다. 금융 업종 및 제조와 유통 업종에서도 네트워크상에서 발생한 로그와 다양한 센서 기반의 데이터를 통해서 다양한 문제를 파악하고 분석해서 해결하는데 도움이 될 수도 있습니다.

(책을 읽어 보시면 더 다양한 사례를 볼 수 있습니다.)


그럼 어떤 기술을 써야 할까요?

오픈 소스로 다음과 같이 정리할 수도 있습니다. 



허허허.. 이것들 언제 다 배우나요. ㅠㅠ

아래 링크에 위 이미지에 대한 설명이 있습니다. 

http://datakulfi.wordpress.com/2013/03/27/big-data-open-source-technology-landscape/


여기까지 빅데이터에 대해서 간략하게 정리해 보았습니다.

위 견해는 저의 관점에서 바라본 빅데이터구요. 더 많은 관심이 있으신분은 책을 보시는것을 추천 드립니다.


마무리로 간단히 말씀 드리면

개발자로서 빅데이터의 기술 부터 공부하기 보다는 빅데이터가 무엇이고 비즈니스적인 관점에 미리 생각해보고 공부를 하면 빅데이터에 대해서 좀 더 효과적으로 접근할 수 있고 생각의 범위가 넓어질 수 있습니다. 



"데이터가 있다면 데이터를 살펴보고, 우리가 가지고 있는 모든 정보를 마이닝 하자"

- 구글 수석 과학자 -



http://stackoverflow.com/questions/9829224/jquery-mobile-301-redirect-issues

http://java.dzone.com/articles/modelling-data-neo4j-0

이번에도 마음대로 번역!@

내용을 요약하면 노드을의 관계에 대해서 검증(확실하게 아는)된 것이면 노드에 속성을 부여(관계+1속성)을 사용하는 것 보다, 여러 타입의 관계를 사용 하는것이 read 속도에서 압도적으로 빠르다.

지금 하고있는 생활 코딩 소스를 보면 아래와 같은 관계로 표현하는것이 관계를 여러개 타입으로 사용하는 것이다.
관계에 대한 것을 아래처럼 type으로 정의할 수도 있고, 관계 클래스를 만들어서 정의(클래스에 속성값 사용 가능, 관계 + 속성) 할 수 있다.

@RelatedTo(type = "FRIENDS", direction = Direction.OUTGOING)
private Set<leaguesummoner> friends;
@RelatedTo(type = "LIKES", direction = Direction.OUTGOING)
private Set<leaguesummoner> likes;
@RelatedTo(type = "INTEREST", direction = Direction.OUTGOING)
private Set<leaguesummoner> interest;
@RelatedTo(type = "TROLL", direction = Direction.OUTGOING)
private Set<leaguesummoner> trolls;

아래부터 번역 시작.
Java로 작성된 샘플 코드는 Neo4J Java API를 사용한 것이고, Cypher(사이퍼)로 작성된 것은 Neo4j에서 제공하는 Cypher Query Language로 된 것이다.(SQL 처럼)

=======================================================================================

'초보자를 위한 Neo4j 모델링' 시리즈의 이전 포스트에서 양방향성 관계에 대해 살펴보았다. 이 포스트에서는 다른 타입의 여러 관계와 관계에 속성을 사용하는 방법에 대해 비교해 보도록 하겠다.

검증을 위한 속성(Properties as Qualifiers)

Neo4j에서 영화에 대한 평점을 매기는 모델링에 대해 이야기해보자. 사람들은 1~5까지 평점을 매길수 있고 이것을 모델링 하는 처음으로 생각한 방법은 'RATED' 라는 관계를 생성하고 1~5사이의 값을 가지고 있는 rating이라는 속성을 만드는 것이다.

Java 와 Cypher을 사용하여 이 모델에 대한 쿼리를 만드는것은 간단하다. 펄프 픽션에 대한 긍정적인 평가들을 구할려면 아래와 같이 rating이 3이상인 것을 구하면 된다.

1.for (Relationship r : pulpFiction.getRelationships(INCOMING, RATED)) {
2.if ((int) r.getProperty("rating") > 3) {
3.Node fan = r.getStartNode(); //do something with it
4.}
5.}

동일하게 사이퍼에서는 아래와 같이 하면 된다.

1.START   pulpFiction=node({id})
2.MATCH   (pulpFiction)<-[r:RATED]-(fan)
3.WHERE   r.rating > 3
4.RETURN  fan


다양한 관계들

우리는 가능한 관계들에 대해서 다 알고 있기 때문에 각각 평점에 대해 다른 관계를 설정하는 방법을 생각할 수도 있다.  
예를 들어 1~5까지의 평점에 따라  LOVED, LIKED, NEUTRAL, DISLIKED, HATED의 관계를 만들 수 있다. 
이 관계를 그래프로 표현하면 아래와 같다.

이전에 사용했던 쿼리들은 동일한 결과를 표시하기 위해 약간 수정을 해야 한다. 펄프 픽션의 팬이 누구인지 자바로 표현하면 아래와 같다.

1.for (Relationship r : pulpFiction.getRelationships(INCOMING, LIKED, LOVED)) {
2.Node fan = r.getStartNode(); //do something with it
3.}

그리고 사이퍼로 표현하면

1.for (Relationship r : pulpFiction.getRelationships(INCOMING, LIKED, LOVED)) {
2.Node fan = r.getStartNode(); //do something with it
3.}


비교 하기

위 두가지 방법에 대한 쿼리 문법은 크게 다르지 않다. 
예를 들어 보면 10가지 다른  관계가 있고 이중에서 7가지를 조회하는 쿼리를 만들 경우 첫번째 방식이 더 효과적이라고 주장할 것이다. 
이 방식은 우리가 찾길 원하는 관계 타입에 대해서 전부 입력해서 조회하지 않아도 된다.

하지만 우리는 성능에 관점을 두고 두가지 방법으로 탐색을 해보도록 하자. 
첫 번째 실험은 두 가지 방법사이의 쓰기 처리량의 차이가 있는지 알 수 있도록 되어있다.
노드 사이의 1000개의 관계를 생성 하고 이걸 생성하는데 걸리는 시간을 측정했다. 
결과는 아래와 같다.

둘 사이의 명확한 쓰기량 차이는 보이지 않지만 탐색을 위한 경우에는 다르게 나온다.

두 번째 실험은, 100개의 노드와 5000개의 무작위 관계를 가지 쿼리를 수행했다.(무슨 말인지 이해가 안되서 아래 원문을 참조 하세요)
In the second experiment, we executed all the queries shown earlier 100 times on a graph with 100 nodes and 5,000 randomly qualified, uniformly distributed relationships (which makes the degree of each node 100, on average).

실험은 아래 3개지 다른 세팅을 가지고 수행하였다.

1. 캐쉬 없이 데이터를 디스크에서 읽는다.
2. 데이터에 대한 로우레벨 캐시만 적용되어 있고, 하이레벨 캐쉬는 중지
3. 데이터에 대한 하이레벨 캐시 적용.

아래 두가지 그림은 각각 Cypher와 Java에서 수행했을때의 결과를 보여준다.

다양한 관계를 생성하는 방법이 항상 단일관계-1개 속성의 방법보다 더 뛰어난 성능을 보여주고 가끔 8배 이상의 성능을 보여준다. 
여기에는 Neo4j에서 디스크와 메모리에서의 데이터를 구성하는 방법의 기술적인 이유가 있다. 하지만 이 내용을 여기선 다루지 않고, 다음 글에서 이야기 할예정이다.

Single-hop 탐색 측정을 수행한것이 중요한데 이 결과가 8배 빠른데 관계의 깊이가 2레벨이 되면 64배 빠를수 있고 3레벨이 되면 512배 빠를 수 있다.

결론

가능하면 다양한 관계를 설정하는 방식이 단일관계-1개 속성의 방식보다 월등한 성능을 보여준다. 이 방식은 두번째 방식 보다 항상 최소한 2배 이상 빠르다.

만약 하이레벨 캐쉬를 사용하고 native Java API를 사용하면 다양한 관계를 설정하는 방법이 두번째 방식보다 8배 이상 빠르다.



http://java.dzone.com/articles/modelling-data-neo4j?mz=36885-nosql

위 아티클 맘대로 번역.


관계형 데이터베이스 세계에서 아름다운 그래프의 세계로 전환하기 위해서는 데이터에 대한 생각의 변화가 필요하다. 
그래프는 종종 테이블보다 더 직관적이긴 하지만 처음으로 그래프로 모델링을 할려고 할때 생기는 몇가지 문제 점이 있다. 
이 아티클에서 혼동되는 한가지 상황를 살펴 본다(양방향 관계)


단방향 관계

Neo4j 에서 관계는 반드시 타입을 가져야 하고 관계에 의미를 부여 해야 하고 방향성이 있어야 한다. 
방향은 자주 관계가 의미하는 것의 일부분이 된다. 즉 관계는 방향성이 없으면 모호하게 된다.
예를 들어 아래 그래프는 아이스하키에서 Czech Republic 팀이 Sweden 을 DEFEATED했다는것을 보여준다. 
방향성이 없으면 이 관계는 모호하게 되고, 누가 승리자가되는지 알수가 없게 된다.



아래 그래프 그림 처럼 관계가 존재 하는것은 반대관계가 있다는 것을 의미한다.
이는 흔한 경우로 다른 예를 들어보면 펄프픽션은 쿠엔틴 타란티노에 의해 DIRECTED_BY 됬고 쿠엔틴 타란티노는  펄프픽션의 IS_DIRECTOR_OF 관계도 된다.
관계들이 모두 짝을 이루고 있기 때문에 관계의 수가 매우 늘어날 수 있다.


Neo4j로 도메인을 모델링할때 발생하는 가장 흔한 실수중에 하나는 짝을 이루는 관계 두개를 만드는 것이다. 
한 관계는 다른 관계도 의미하기 때문에 이것은 공간과 탐색 시간 면에서 낭비적이다.
Neo4j는 양방향의 관계에 대해 탐색이 가능하다.
조금 더 중요것은 Neo4j가 데이터를 구성하는 방법에 때문에 탐색의 스피드는 관계의 방향에 의존 하지 않는다.


양방향 관계

다른 한편으로 어떤 관계들은 페이스북이나 실제 현실에서 친구들 처럼 자연적으로 양방향성을 가지고 있다.
우리가 모델을 어떻게 보느냐에 따라 달려있지만 방향성이 없다고도 말할 수 있다.

아래 그림을 보면 GraphAware와 Neo technology는 파트너 회사들이다. 이 상호 관계이기 때문에 우리는 양방형성과 방향성이 없는 관계로 각기 정의 할 수 있다. 


하지만 이중에 Neo4j에서 직접적 정의가 가능한게 없기 때문에 초보자들은 가끔 아이스 하키 모델 잘못된 동일한 문제를 겪고 불필요한 관계를 가진 모델을 생성한다.


Neo4j API는 만약 개발자가 원한다면 쿼리로 그래프를 사용할때 완벽하게 방향성을 무시하고 사용할 수 있도록 허락한다. 예를 들어 Neo4j는 자신만의 Cypher라는 자신만의 쿼리 언어를 가지고 있다. Neo Technology 와 파트너 회사를 조회하는 쿼리는 아래와 같다.

MATCH (neo)-[:PARTNER]-(partner)

이 결과는 아래 두 쿼리의 결과를 합한것과 동일하다.

MATCH (neo)-[:PARTNER]->(partner)
or
MATCH (neo)<-[:PARTNER]-(partner)


따라서 파트너 관계를 정의하는 정확한 방법(혹은 가장 효과적인)은 하나의 PARTNER 관계를 임의의 방향으로 설정 하는것이다.

결론


Neo4j에서의 관계는 동일한 속도로 양방향 탐색이 가능하다. 게다가 방향성은 완벽하게 무시하고 사용 가능하다. 
따라서 만약 하나가 다른것을 의미하는 경우 노드들 사이에 두개의 서로 다른 관계를 만들 필요가 없다.



http://blog.neo4j.org/2013/10/neo4j-200-m06-introducing-neo4js-browser.html

브라우저를 통해서 그래프를 탐색 할 수 있게 된다.


1.8 버전에는 neoclipse 를 통해서 했었는데... 1.9버전은 안되더니..
2.0버전 부터는 웹콘솔 자체에 포함해서 해주는듯... 기대 중이다!

근데 그전에.. 간단한 보안관련 로직도 좀 넣어 주면 안되겠니? ..;