참고서적 : do it! 리액트프로그래밍정석
컴퓨팅에서 그래프 데이터베이스(graph database, GDB)는 시맨틱 쿼리를 위해 노드, 엣지, 프로퍼티와 함께 그래프 구조를 사용하여 데이터를 표현하고 저장하는 데이터베이스이다. 이 시스템의 주 개념은 그래프(엣지 또는 관계)이며 스토어에 직접 데이터 항목들의 관계를 정한다. 이러한 관계들은 스토어 안의 데이터가 함께 직접 연결될 수 있게 한다. 위키백과:그래프 데이터베이스
많은 양의 데이터를 처리할때 그래프DB 도입을 하게 된다. 서버에서 데이터를 받게 되면 배열형태로 받게 되는데, 이때 배열구조([{...},{...}...]
)를 객채({data:{ 1: {...}, 2:{...}}}
)로 변경하여 state에 저장, 고유값(id)을 key로 하여 데이터를 검색하게 된다. 배열을 순회하여 데이터를 찾는 것보다, 키 검색으로 객체 내부데이터를 검색하는 속도가 빠르기 때문에 검색 속도 최적화에도 적합하다.
// DB에서 받은 오리지널 데이터
// data :[{},{},{}...] 배열 속 객체 나열 형식
{ DBData : [
{
id : 1,
name : 'hwang',
age : 20
},
{
id : 2,
name : 'zuzu',
age : 30
},
]
}
// 해시맵구조 도입하여 객채 속 객채 형태 (json같이)
{
data : {
ids : [1,2],
entities : {
1 : { // DBData[0]['id']를 키값으로 설정한다.
id : 1,
name : 'hwang',
age : 20
},
2 : { // DBData[1]['id']를 키값으로 설정한다.
id : 1,
name : 'zuzu',
age : 30
}
}
}
}
// action-type
export const SET_HASHMAP = 'SET_HASHMAP'
// action-creater
export const setHashmap = (DBdata) => {
return {
type : SET_HASHMAP,
payload : DBdata
}
}
// reducer
const initState = {
ids : [],
entities : {}
}
const hashmapReducer = (state=initState, action) => {
const { type, payload } = action
// 스토어에 반환할 값을 변수에 담자
switch(type) {
case SET_HASHMAP: {
const ids = payload.map(entity => entity['id']); // [1,2]
// reduce((누적값, 현재값(선택인덱스값), 현재값의인덱스, 원본배열)=>{}, 반환그릇)
const entities =payload.reduce((finalEntities,entity)=>{
return {
...finalEntities,
[entity['id'] : entity ]
}, {}) // 최종결과는 객체{}에 담아 반환한다.
return {
ids,
entities
}}
}
}
스토어에 저장된 데이터를 확인하는 방법으로 아래 2가지 식이 있다.
스토어.getState()
메서드 사용두가지 방법중 getState()
를 통해 스토어 전체 객체에 접근해 보자!
const store = createStore(reducer, initState, enhancer)
const collection = store.getState()
const { ids, entities } = collection // 구조분해할당
// 원본 DBData와 같은 형태로 만들기
const DBData = ids.map(id => entities[id]) // 1: {id:1,name:'hwang',age:20}
// 결과 :
// [{
// id : 1,
// name : 'hwang',
// age : 20
// },{
// id : 2,
// name : 'zuzu',
// age : 30
// },
// ]
기존 배열형태에서 객체형태로 변경한 그래프DB는 key를 조회하여 바로 접근가능하기 때문에 수정이 간편해졌다. 배열방식의 경우 인덱스를 순회하며 해당값을 찾아야 하는 번거러움이 있다.
// action-type 추가
export const SET_HASHMAP_NAME = 'SET_HASHMAP_NAME'
// action-creater 추가
export const setName = (id, name) => {
return {
type: SET_HASHMAP_NAME,
payload : {
id,
name
}
}
}
// reducer 추가
// 키값으로 순회가 간편하나, 작성이 복잡...
const hashmapReducer = (state=initState, action) => {
const {type, payload} = action
switch(type){
case SET_HASHMAP: {
// ... 내용동일
}
case SET_HASHMAP_NAME:{
const {id, name} = payload
return {
...state,
entites : {
...state.entites,
[id] : {
// [id] 는 key의 위치로,
// key값은 중복을 허용하지 않기 때문에,
// value가 최신 입력값으로 업데이트 된다.
...state.entities[id],
name
}}
}}
default :
return state;
}
}