-
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가 많이는 존재하지 않음.
보았을 때 mysql쪽이 성능이 더 좋은 것으로 판단되었다. 하지만
- 공식 홈페이지와 성능 차이가 커서 올바르게 측정을 하였는지 정확하지 않음
- 팀원의 의사를 존중
- 확장성을 고려 하여 그래프 db를 사용하는 것으로 결정하였다.
- 스키마 제약이 없어도 기본 스키마는 만들자. 스키마의 크기를 고려해야 한다
- 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
- 동사와 명사로 구분해서 모델링
그럼 네이밍 규칙을 적용해서 문장을 모델링하는 것을 살펴봅시다 이런 방식으로 우리도 데이터 모델링을 함
(Node)-[relation]->(Node)
User authored Feed
Feed authored by User
Feed has comments
User authored Comment
Comment authored by User
Comment liked by User
User likes comments
User friend User
User tagged at Feed
Feed tagged User
- 오전 회의 때 공부한 내용 공유
- 왜 모두가 공유했는지. : 디비설계 및 설정은 모두가알아야 하는 내용이므로 서로 이해했는지 명확해 해야 했음.
- 공부한 내용을 발표하고 그 내용을 이해했는지 다시 말해봄.
- 테스트 데이터, 환경을 위키로 공유
- 기록으로 남겨야 하는부분은 위키로 공유
- 팀원모두 기술 공유에 대한 여러 아이디어를 냄
-
회고
-
학습
-
스프린트
-
기술공유
-
회의
-
마스터클래스_정리
-
데일리마무리회의
-
데일리스크럼