JSON 데이터베이스
Connect Base의 NoSQL JSON 데이터베이스 심화 가이드입니다.
개요
Connect Base JSON 데이터베이스는 스키마 없이 시작할 수 있는 유연한 NoSQL 데이터베이스입니다. JSON 형식으로 데이터를 저장하고 강력한 쿼리 기능을 제공합니다.
앱 내에서 테이블을 직접 생성하여 데이터를 관리합니다. 별도의 데이터베이스 그룹 없이 앱 단위로 테이블을 플랫하게 관리하는 구조입니다.
스키마 설계
스키마리스 접근
테이블 생성 시 스키마를 정의할 필요가 없습니다:
typescript
// tableId(tbl_xxx)는 콘솔 → 데이터베이스 → 테이블 만들기 후 발급
await cb.database.createData('tbl_users', {
data: {
name: '홍길동',
email: '[email protected]',
age: 30,
profile: {
bio: '개발자입니다',
avatar: 'https://...'
},
tags: ['developer', 'korea']
}
})중첩 객체
JSON의 장점을 활용하여 중첩 구조 사용:
typescript
await cb.database.createData('tbl_orders', {
data: {
orderId: 'ORD-001',
customer: {
name: '홍길동',
email: '[email protected]',
address: {
city: '서울',
street: '강남대로 123'
}
},
items: [
{ productId: 'P1', quantity: 2, price: 15000 },
{ productId: 'P2', quantity: 1, price: 25000 }
],
totalAmount: 55000
}
})쿼리 최적화
필요한 필드만 조회
typescript
// 전체 필드 조회 (비효율)
const all = await cb.database.getData('tbl_users')
// 필요한 필드만 조회 (효율적)
const partial = await cb.database.queryData('tbl_users', {
select: ['name', 'email']
})인덱싱
자주 조회하는 필드에는 인덱스를 설정하세요:
typescript
// 콘솔에서 인덱스 설정
// 테이블 > 설정 > 인덱스 추가
// 필드: email, 유형: 고유 인덱스페이지네이션
대량 데이터 조회 시 반드시 페이지네이션 사용:
typescript
// 첫 페이지
const page1 = await cb.database.queryData('tbl_users', {
limit: 20,
offset: 0,
orderBy: 'created_at',
orderDirection: 'desc'
})
// 다음 페이지
const page2 = await cb.database.queryData('tbl_users', {
limit: 20,
offset: 20,
orderBy: 'created_at',
orderDirection: 'desc'
})고급 쿼리
복합 조건
typescript
const results = await cb.database.queryData('tbl_products', {
where: {
category: 'electronics',
price: { $gte: 10000, $lte: 100000 },
stock: { $gt: 0 }
}
})OR 조건
typescript
const results = await cb.database.queryData('tbl_users', {
where: {
$or: [
{ role: 'admin' },
{ role: 'moderator' }
]
}
})배열 검색
typescript
// 태그 포함 여부
const developers = await cb.database.queryData('tbl_users', {
where: {
tags: { $contains: 'developer' }
}
})모범 사례
1. 데이터 정규화 vs 비정규화
비정규화 (권장 상황):
- 읽기가 쓰기보다 훨씬 많을 때
- 데이터 일관성이 덜 중요할 때
typescript
// 주문에 고객 정보 복사 (비정규화)
{
orderId: 'ORD-001',
customerName: '홍길동', // 복사됨
customerEmail: '[email protected]' // 복사됨
}정규화 (권장 상황):
- 데이터 일관성이 중요할 때
- 데이터 업데이트가 자주 일어날 때
typescript
// 주문에 고객 ID만 저장 (정규화)
{
orderId: 'ORD-001',
customerId: 'user_123' // 참조만
}2. 배열 크기 제한
배열이 무한정 커지지 않도록 주의:
typescript
// ❌ 나쁜 예: 배열이 무한정 커질 수 있음
{
userId: 'user_123',
loginHistory: [/* 수천 개... */]
}
// ✅ 좋은 예: 별도 테이블로 분리
// logins 테이블
{
userId: 'user_123',
timestamp: '2024-01-15T10:00:00Z'
}3. 일관된 필드 타입
같은 필드에는 항상 같은 타입 사용:
typescript
// ❌ 나쁜 예: 타입 혼용
{ age: 30 } // number
{ age: "30" } // string
// ✅ 좋은 예: 일관된 타입
{ age: 30 }
{ age: 25 }