그래프 데이터베이스 — Neo4j 와 Cypher · 그래프가 이기는 문제 · 퀴즈
퀴즈: 그래프가 이기는 문제
문항 8개. 정답과 해설은 풀어 본 뒤에 보여 드립니다.
'같은 기기를 쓰는 넷 이상' 만으로 사기 고리를 판정했더니 도서관 공용 단말의 이용자들이 잡혔다. 올바른 좁히기는?
- 기기 종류가 phone 인 것만 남겨 공용 pc 와 태블릿을 결과에서 뺀다
- 기기를 처음 쓴 시각이 같은 날인 사람끼리만 묶어 우연한 공유를 뺀다
- 같은 기기와 같은 주소를 **둘 다** 함께 쓰는 사람만 세도록 패턴에 LIVES_AT 을 더한다
- 네 명이 아니라 여섯 명 이상으로 문턱을 올려 작은 공유는 무시한다
`MATCH p = (a:Account)-[:TRANSFER*3..5]->(a)` 를 금액 조건 없이 돌리면 어떤 문제가 생기나?
- 정상적인 소액 송금으로 우연히 만들어진 순환이 잔뜩 섞여 나온다
- 순환은 관계 유일성 때문에 MATCH 로 찾을 수 없어 결과가 늘 비어 나온다
- 출발 노드와 끝 노드에 같은 변수를 쓰면 패턴이 성립하지 않아 문법 오류가 난다
- 가변 길이에 하한 3 이 적혀 있으면 상한과 무관하게 정확히 3단계만 찾는다
세 계좌짜리 순환 하나가 결과에 세 번 나왔다. 이유와 처리는?
- 송금이 세 번 중복 적재된 것이니 관계를 지워야 한다
- 세 번 나온 것이 각각 다른 순환이므로 셋 다 보고한다
- Neo4j 가 방향을 무시해 역방향 순환까지 찾은 것이니 화살표를 붙인다
- 출발 노드마다 한 번씩 나온 같은 순환이니, 가장 작은 id 에서 시작하는 것만 남긴다
차수(degree) 1위 계좌가 230곳으로 송금했다. 이것을 어떻게 읽어야 하나?
- 차수가 높으면 곧 사기이므로 바로 차단한다
- 차수는 어디를 볼지 정해 줄 뿐이다 — 보내기만 하는 급여 계좌일 수 있어 방향과 상대를 봐야 한다
- 230 은 관계 유일성 위반이므로 데이터 오류다
- 송금 수가 아니라 잔액이 큰 계좌가 허브이므로 다시 계산한다
협업 필터링 점수를 `count(other)` 가 아니라 `count(DISTINCT other)` 로 세는 이유는?
- DISTINCT 가 없으면 상품이 아니라 사람이 결과 행이 되기 때문
- 나와 여러 상품이 겹치는 한 사람이 그 수만큼 반복해 나와 점수를 부풀리기 때문
- count(other) 는 NULL 을 함께 세어 값이 커지기 때문
- DISTINCT 가 있어야 ORDER BY 를 쓸 수 있기 때문
추천 질의에서 `NOT (me)-[:BOUGHT]->(rec)` 를 빼면 무슨 일이 생기나?
- me 와 other 가 같은 사람으로 묶여 점수가 0 이 된다
- 결과가 비어 나온다 — 패턴이 맞는 상품이 없어진다
- 점수는 같고 정렬 순서만 바뀐다
- 내가 이미 산 상품이 가장 높은 점수로 추천된다
SQL 로 '3~5단계 만에 돌아오는 송금 순환' 을 찾으려면 무엇이 필요한가?
- 길이마다 자기 조인을 한 벌씩 쓰거나, 길이가 가변이면 재귀 CTE 로 경로를 쌓아야 한다
- GROUP BY from_account HAVING count(*) >= 3 한 줄이면 된다
- 인덱스를 걸면 조인 없이 순환을 바로 찾을 수 있다
- 윈도우 함수 LAG 로 이전 송금을 참조하면 된다
다음 중 그래프 데이터베이스가 **유리하지 않은** 질문은?
- 두 사람이 송금 몇 다리로 이어져 있는가
- 같은 기기와 주소를 함께 쓰는 사람의 무리는 어디인가
- 지난달 업종별 결제 총액은 얼마인가
- 이 계좌에서 나간 돈이 세 단계 안에 어디로 갔는가