-
Notifications
You must be signed in to change notification settings - Fork 2
2주차 기술공유 graphdb
- declarative graph query language(선언적 그래프 질의 언어)
- node , relationship, label, properties
-
node : 그래프 DB에서 1개의 개체
-
label : node의 그룹조건 노드의 역할을 명시하고, 노드를 그룹화 하기 위한 타입
- 하나의 노드는 여러 라벨링이 가능
-
propreties : node,relation이 가질 수 있는 값들 ex) user node의 name, phone, id..
-
relationship : node의 관계 entity 연결, 구조를 설정, properties
노드는 graphDB에서 하나의 개체이고 노드의 관계를 표시하는 게 relationship입니다. 노드와 relation은 label과 property를 가질 수 있다. 라벨은 명시되는 타입입니다. 회사 타입, employee 타입등을 명시해서 쿼리 셀렉트를 쉽게할 수 있습니다. 프로퍼티는 node,relation이 가질 수 있는 값들
()
(variable)
(:Label)
(variable:Label)
(:Label1:Label2)
(variable:Label1:Label2)
여러개의 라벨을 한 노드에 사용가능하다.
(신기하게도)neo4j는 하나의 노드에 여러 라벨을 부여 할 수 있습니다.
DB는 Curd!! 기초 crud 를 알아봅시다
CREATE (john:Person {name: 'John'})
CREATE (joe:Person {name: 'Joe'})
CREATE (steve:Person {name: 'Steve'})
CREATE (sara:Person {name: 'Sara'})
CREATE (maria:Person {name: 'Maria'})
// 관계설정해서 만들기(뒤에 나옴)
CREATE (john)-[:FRIEND]->(joe)-[:FRIEND]->(steve)
CREATE (john)-[:FRIEND]->(sara)-[:FRIEND]->(maria)
먼저 노드를 만들어야겠져?
// name A인 Person label 노드와 name B인 노드를 연결한다
MATCH (a:Person),(b:Person)
WHERE a.name = 'John' AND b.name = 'Joe'
CREATE (a)-[r:Friend { description : a.name + '<->' + b.name }]->(b)
RETURN type(r), r.description
그다음은 관계를 만들어야겠져? joe 와 john은 친구다
MATCH (user)-[:friend]->(follower)
WHERE user.name IN ['Joe', 'John', 'Sara', 'Maria', 'Steve'] AND follower.name =~ 'S.*'
RETURN user.name, follower.name
(tip) =~ 정규표현식으로 검색
- 모든 노드 반환
MATCH (variable)
RETURN variable
- Label에 해당하는 노드 반환
MATCH (variable:Label)
RETURN variable
만든 노드들을 조회해봅시다
MATCH (n:Person {name:"kkyu"}) SET n.age=35
만든 노드의 프로퍼티를 수정해봅시다. SET을 이용하면 됨
MATCH (n:Person {name:"kkyu"}) REMOVE n.age=35
// 관계 삭지
MATCH (a:Persion{name:'yeon'})-[r]-(b) DELETE r
- 관계가 설정된 노드는 관계부터 삭제해야 한다. ref
만든 노드를 삭제해봅시다. 하지만 관계가 있다면 관계부터 삭제해야 합니다
MATCH
(person:Person)-[:KNOWS]-(friend:Person)-[:KNOWS]-(foaf:Person)
WHERE
person.name = "Joe"
AND NOT (person)-[:KNOWS]-(foaf)
RETURN
foaf
우리의 상황은 항상 쉽지 않죠. 조금 더 복잡한 쿼리를 알아보겠습니다. 목적 : 친구의 친구들 중 나와 친구가 아닌 친구들을 찾아봅시다 예상되야되는 결과 : bob은 뜨면안되고 sally, anna 만 결과로 확인되어야 합니다. person의 이름이 Joe이고 person과 KNOW의 관계가 2depth가 아닌 1depth인 경우를 나타내는 cypher입니다.
MATCH
(person:Person)-[:KNOWS]-(friend)-[:KNOWS]-(foaf:Person)
WHERE
user.name = "Joe" AND foaf.name = "Sally"
RETURN
friend.name
MATCH
path = shortestPath(
(p1:Person)-[:KNOWS*..6]-(p2:Person)
)
WHERE
p1.name = "Joe" AND p2.name = "Billy"
RETURN
path
- graph db가 관계를 나타내는데 적합한 구조를 가진다는 사실을 알게됨.
- https://tech.kakao.com/2016/01/29/opensource-1-s2graph/ 오..?
- https://neo4j.com/news/how-much-faster-is-a-graph-database-really/ 오2..?
친구의 친구 찾기가 엄청 편하네!를 알게 되었어요 그럼 우리가 도입할 수 있을지를 생각해봅시다
- 일반적인 RDB에서 너비 우선 탐색을 구현하려면 대규모의
JOIN
과GROUP BY
가 불가피함 -> 따라서 수많은 관계를 나타내기 위해서는 그에 특화된 그래프 DB를 이용하는 것이 성능이 빠르다.
이하의 공식 문서 결과를 보면 graphDB가 얼마나 관계에 최적화되어있는지 볼 수 있다.
이 공식 문서에 대해 정확한 확인을 해보기 위해서 직접 테스트를 작성해서 이하에서 테스트해보았다.
-
유저 1,000,000명
-
depth : 1,2 depth
-
Graph db: 한 유저에 대한 friends 관계인 User들 143명 가져오는 쿼리
- MATCH (a:Person {name : 'User33'}) -[:FRIENDS] -> (m:Person) RETURN m;
-
Mysql db: 한 유저에 대해 tb_friend_relation 테이블 inner join을 통해 143명 가져옴
-
select * from tb_user as user left join tb_friend_relation friend on user.id = friend.user_id left join tb_user as user1 on friend.user_id2 = user1.id where user.id = 'id1200';
-
Case | graphDB | Mysql |
---|---|---|
Depth1 | 8ms | 0.1ms |
Depth2 | 26ms | 10.1ms |
- neo4j에 대한 orm이 존재하지 않음. ( 개발 속도가 더딜 수 있음. )
- mysql에 비해 neo4j에 대한 reference가 많이는 존재하지 않음.
- 하지만 데이터, 관계가 많아질 시 graphDB에 대한 성능이 좋기 때문에 선택함.
- 스키마 제약이 없어도 기본 스키마는 만들자. 스키마의 크기를 고려해야 한다
- Neo4j limits the number of relationship types to 65K to keep the database fast
- file은 blob으로 저장하지 말기
- Indexing : legacy indexing -> schema indexing
- never use explain profile
-
MERGE 는 유일성을 보장하지 않는다. use the
UNIQUE
constrain
- LABEL은 대문자로 시작하는 명사로 정의 User
- RelationShips : 목적어를 가질 수 있는 동사로 정의, 대문자 권장 SENT
- property : 명사형 {name:""}
그럼 우리 디비에서 어떻게 모델링을 해야할까요? 각 요소들의 네이밍 규칙을 먼저 알아봅시다
=>
* John is friends with Sally
* Sally is friends with John
* John has read Graph Databases
* Sally has read Graph Databases
- 동사와 명사로 구분해서 모델링
그럼 네이밍 규칙을 적용해서 문장을 모델링하는 것을 살펴봅시다
User has feeds.
Feed has comments.
- 오전 회의 때 공부한 내용 공유
- 왜 모두가 공유했는지. : 디비설계 및 설정은 모두가알아야 하는 내용이므로 서로 이해했는지 명확해 해야 했음.
- 공부한 내용을 발표하고 그 내용을 이해했는지 다시 말해봄.
- 테스트 데이터, 환경을 위키로 공유
- 기록으로 남겨야 하는부분은 위키로 공유
-
회고
-
학습
-
스프린트
-
기술공유
-
회의
-
마스터클래스_정리
-
데일리마무리회의
-
데일리스크럼