문서 메뉴
문서 홈
/ /
Atlas Device SDK
/ / /

Device Sync를 사용한 데이터 모델링 - Kotlin SDK

이 페이지의 내용

  • Device Sync 데이터 모델 정의
  • 클라이언트 앱에서 스키마 생성
  • 기존 Atlas 데이터로 스키마 생성
  • Realm Mobile Sync 요구 사항
  • Realm 객체 매핑
  • Realm 관계 매핑
  • 일대일 관계 매핑
  • To-Many 관계
  • 역관계
  • 임베디드 객체
  • 스키마 유형 매핑 목록
  • Kotlin 유형
  • BSON 유형
  • Realm 유형

이 페이지에서는 Realm Mobile Sync Realm 데이터 모델과 Realm Mobile Sync에서 사용하는 Atlas App Services 스키마의 데이터를 클라이언트의 Kotlin SDK에서 사용하는 Realm 스키마에 매핑하는 방법에 대해 설명합니다.

이 페이지에서는 다음 작업 을 수행하지 않습니다.

Device Sync에 대한 자세한 설명은 Atlas App Services 문서에서 Get Started with Atlas Device Sync (Atlas Device Sync 시작하기)를 참조하세요.

이 페이지의 스키마 유형 매핑 목록 섹션에 있는 표는 지원되는 데이터 유형과 Realm과 App Services 간의 매핑 방법에 대한 빠른 참조를 제공합니다. 보다 포괄적인 리소스는 App Services 문서의 데이터 모델 매핑 을 참조하세요.

Realm 데이터 모델은 다음 스키마로 정의되며, 이를 통해 Realm Mobile Sync는 클라이언트와 Atlas 간에 데이터를 매핑할 수 있습니다.

  • Realm schema: 코틀린 SDK (Kotlin SDK)를 사용하여 데이터를 코틀린 클래스로 정의하는 앱의 클라이언트 사이드 객체 모델입니다.

  • App Services schema: BSON에서 데이터를 정의하는 Atlas App Services의 서버 측 스키마입니다. 자세한 내용은 App Services 문서의 스키마 를 참조하세요.

Realm Mobile Sync는 이러한 스키마를 사용하여 데이터를 동기화할 때 Kotlin과 BSON 형식 간에 객체를 검증하고 변환합니다. 클라이언트에서 데이터를 동기화하면 Realm Mobile Sync가 자동으로 Realm Kotlin 데이터 유형을 BSON으로 변환합니다. 그런 다음 클라이언트 기기가 Realm Mobile Sync를 통해 Atlas의 데이터를 동기화하면 SDK는 BSON 데이터를 Kotlin 객체로 다시 변환합니다.

Realm Mobile Sync를 사용하려면 Realm 스키마와 App Services 스키마를 정의해야 하며 두 스키마가 서로 일관되어야 합니다.

기본 설정과 사용 사례에 따라 클라이언트 앱 또는 Atlas에서 먼저 스키마를 정의할 수 있습니다. 그런 다음 일치하는 객체 모델로 해당 스키마를 생성할 수 있습니다.

새 클라이언트 애플리케이션을 개발하는 경우 클라이언트 앱의 데이터 모델을 반복할 수 있습니다. 클라이언트 앱 코드에서 직접 객체 모델을 정의한 후 Atlas App Services에서 개발 모드를 사용하도록 설정하여 일치하는 Atlas App Services 스키마를 자동으로 생성할 수 있습니다.

개발 모드 는 클라이언트에서 데이터를 동기화할 때 Device Sync가 클라이언트 사이드 데이터 모델을 기반으로 스키마를 추론하고 업데이트할 수 있도록 하는 구성 설정입니다. 자세한 내용은 App Services 문서에서 개발 모드 를 참조하세요.

Atlas에 이미 존재하는 데이터로 작동하는 클라이언트 애플리케이션을 개발하는 경우, 해당 데이터에서 스키마를 생성한 다음 Kotlin 클라이언트 앱에서 사용할 SDK 객체 모델을 생성할 수 있습니다. 자세한 내용은 App Services 문서에서 클라이언트 애플리케이션과 Atlas의 데이터 동기화 를 참조하세요.

객체를 성공적으로 동기화하기 위해서는 몇 가지 요구 사항이 있습니다. 앞서 설명한 대로 동기화하려는 객체를 포함하는 일치하는 Realm 및 App Services 스키마가 있어야 합니다.

또한 Realm Mobile Sync에는 다음이 필요합니다.

  • 객체 모델에는 _id 라는 프라이머리 키 필드가 있어야 합니다 . String, Int 또는 ObjectId 유형일 수 있습니다. Realm Mobile Sync는 이를 사용하여 Atlas collection의 객체를 식별합니다.

    객체에 정의된 _id 필드가 없으면 Realm에서 다음 스키마 유효성 검사 오류가 발생합니다: There must be a primary key property named '_id' on a synchronized Realm.

  • 각 클래스에는 쿼리 가능 필드가 하나 이상 있어야 합니다.

    개발 모드가 활성화된 경우 클라이언트 구독 쿼리에 포함하는 필드는 Atlas에서 쿼리 가능 필드로 자동으로 추가됩니다. Kotlin SDK로 구독을 구성하는 방법에 대한 자세한 내용은 구독 개요를 참조하세요.

Realm 객체는 해당 유형의 객체의 속성과 관계를 결정하는 Realm 스키마에 정의된 코틀린(Kotlin) 클래스의 고유한 이름을 가진 인스턴스입니다.

Atlas App Services는 다음과 같은 방식으로 Realm 객체를 Atlas에 매핑합니다.

  • Realm 객체 이름은 연결된 Realm Mobile Sync 데이터 소스의 Atlas 컬렉션에 매핑됩니다. 다음 사항에 유의하세요.

    • 개발 모드가 활성화되면 Atlas App Services는 동기화하는 각각의 새 Realm 객체 유형에 대한 collection과 스키마를 자동으로 생성합니다.

    • 포함된 객체는 Atlas의 자체 컬렉션에 저장 되지 않습니다 . 이는 상위 객체 유형 외부에 존재할 수 없기 때문입니다. 자세한 내용은 이 페이지의 포함된 객체 섹션을 참조하세요.

  • Realm 객체 스키마는 해당 collection 내의 App Services 스키마에 매핑됩니다.

다음 예제에는 Realm 스키마에 기본 속성이 정의된 FrogPond 객체가 있습니다.

Frog and Pond Realm 객체
// Maps to `Frog` collection
class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
}
// Maps to `Pond` collection
class Pond : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
}

Atlas에서는 이러한 Realm 객체 유형이 해당 Atlas App Services 스키마(각 객체가 해당 collection에 매핑됨)에 어떻게 매핑되는지 확인할 수 있습니다. 또한 이 Realm 데이터 모델을 준수하는 예제 개구리와 못 객체도 볼 수 있습니다.

App Services의 Frog 컬렉션
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"name": {
"bsonType": "string"
}
}
}
App Services의 Pond collection
{
"title": "Pond",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"name": {
"bsonType": "string"
}
}
}
Atlas의 Frog 객체 예시
{
"_id": ObjectId("5af712eff26b29dc5c51c60f"),
"name": "Kermit",
"age": 42
}
Atlas의 Pond 객체 예시
{
"_id": ObjectId("5af714eff24b294c5251cf04"),
"name": "Kermit's Pond"
}

Realm 객체 모델에는 객체 간의 관계 가 포함될 수 있습니다. 관계에는 다음과 같은 두 가지 주요 유형이 있습니다.

  • 대일 관계: 객체가 특정 방식으로 하나 이상의 다른 Realm 객체와 관련되지 않습니다.

  • 대다 관계: 객체는 특정 방식으로 여러 Realm 객체와 관련됩니다.

관계는 다른 Realm 객체의 기본 키를 참고하는 속성에 의해 매핑됩니다.

Atlas App Services 스키마의 관계 모델링에 대한 자세한 내용은 Atlas App Services 문서의 관계 를 참조하세요.

일대일 관계는 한 속성을 다른 Realm 객체의 단일 인스턴스에 매핑합니다. 대일 관계는 선택 사항 이어야 합니다. Kotlin SDK에서 일대일 관계를 정의하는 방법에 대한 자세한 내용은 대일 관계 속성 정의를 참조하세요.

위 예의 객체를 사용하여 Frog 에 하나의 즐겨찾기 폰드가 있을 수 있는 경우를 생각해 보세요. Pond 객체에 대한 선택적 링크인 favoritePond 속성을 Frog 모델에 추가할 수 있습니다.

Frog(연못과 일대일 관계)
class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
// To-one relationship (MUST be optional)
var favoritePond: Pond? = null
}

App Services 스키마에서 새 속성이 favoritePond 필드로 변환되는 것을 볼 수 있습니다.

  • 필드가 선택적 속성이므로 required 배열에 없습니다.

  • 해당 유형은 objectId Pond 별도의 Pond collection에 있는 특정 객체에 연결되는 입니다. 이는 Pond 모델의 기본 키를 objectId 로 정의했기 때문입니다.

Pond 스키마가 변경되지 않습니다. 이는 대일 관계이므로 단방향 관계입니다. Pond 은(는) Frog 와(과) 관계가 없습니다.

App Services 스키마
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"favoritePond": {
"bsonType": "objectId"
},
"name": {
"bsonType": "string"
}
}
}

대다 관계 관계는 한 속성을 다른 Realm 객체의 0개 이상의 인스턴스에 매핑합니다. Kotlin SDK에서 대다 관계를 정의하는 방법에 대한 자세한 내용은 대다 관계 속성 정의를 참조하세요.

Frog 에 즐겨찾기가 하나가 아닌 여러 개 있을 수 있는 또 다른 경우를 생각해 보세요. Pond 객체의 목록인 favoritePonds 속성을 Frog 모델에 추가합니다. 즐겨찾는 못이 없는 경우 이는 빈 목록입니다. 프로그가 즐겨찾는 못을 갖게 되면 새로운 Pond 객체를 만들어 프로그의 favoritePonds 목록에 추가할 수 있습니다.

Pond와 To-Many 관계를 가진 Frog
class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
// To-many relationship (can have many ponds)
var favoritePonds: RealmList<Pond> = realmListOf()
}

App Services 스키마에서 새 속성은 객체와 관련된 favoritePonds Pond 객체를 모두 포함하는 필드로 변환됩니다.Frog

  • 필드가 선택적 속성이므로 required 배열에 없습니다.

  • 이 필드의 유형은 objectId 유형의 배열입니다. 이는 Pond 모델의 프라이머리 키를 objectId 로 정의했기 때문입니다.

다시 말하지만, PondFrog 와 다시 관계가 없기 때문에 Pond 스키마는 변경되지 않습니다.

App Services 스키마
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"favoritePonds": {
"bsonType": "array",
"items": {
"bsonType": "objectId"
}
},
"name": {
"bsonType": "string"
}
}
}

역 관계는 역링크라고 하는 정의된 대일 또는 대다 관계로 해당 객체를 참조하는 다른 모든 객체에 객체를 다시 연결합니다. Kotlin SDK에서 역관계를 정의하는 방법에 대한 자세한 내용은 역관계 정의를 참조하세요 .

App Services 스키마는 역관계를 지원 하지 않습니다 . 이는 역관계가 역링크가 수정될 때 자동으로 업데이트되는 Realm의 암시적 관계를 나타내기 때문입니다. 즉, 역관계 값을 직접 설정할 수 없으며 해당 관계는 Atlas에 존재하지 않습니다. 대신 Realm은 Realm 객체 모델을 기반으로 클라이언트 애플리케이션에서 이러한 관계를 파생하고 업데이트합니다.

Pond 객체가 Frog 객체와 역관계에 있는 경우를 생각해 보세요.

Frog와 역관계가 있는 Pond
class Pond : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
// Backlink to the `Frog` that has this `Pond` as its favorite
val frog: RealmResults<Frog> by backlinks(Frog::favoritePonds)
}
class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
// To-many relationship (can have many ponds)
var favoritePonds: RealmList<Pond> = realmListOf()
}

App Services 스키마에서 FrogfavoritePonds 속성을 통해 Pond 와 대다 관계를 가지고 있습니다. 그러나 Pond 모델의 Frog 에 대한 역관계를 나타내는 frog 속성이 존재 하지 않습니다 . 이는 Atlas에서 역관계를 명시적으로 정의할 수 없기 때문입니다. 그러나 Realm은 관계에서 객체를 추가하거나 제거할 때마다 자동으로 업데이트합니다.

App Services 스키마
// `Pond` schema in App Services DOES NOT contain the
// `frog` inverse relationship property
{
"title": "Pond",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"name": {
"bsonType": "string"
}
}
}
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"favoritePonds": {
"bsonType": "array",
"items": {
"bsonType": "objectId"
}
},
"name": {
"bsonType": "string"
}
}
}

내장된 객체는 단일한 특정 상위 객체 내에 중첩된 데이터를 나타냅니다. 관계를 정의하는 것과 같은 방식으로 상위 Realm 객체 유형에서 내장된 객체를 참고할 수 있습니다. Kotlin SDK에서 포함된 객체를 정의하는 방법에 대한 자세한 내용은 포함된 객체 정의를 참조하세요 .

그러나 일반 Realm 객체와 달리 내장된 객체는 Atlas의 자체 collection에 저장 되지 않습니다 . 대신 상위 객체 문서의 일부로 저장되며 상위 객체 외부에서 액세스할 수 없습니다.

다음 예제에는 포함된 단일 Pond 객체를 참고하는 favoritePond 속성이 있는 Frog 객체와 여러 포함된 Pond 객체 목록을 참고하는 forestPonds 관계 속성이 있는 Forest 객체가 있습니다. :

내장된 연못 관계가 있는 개구리와 숲
class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
// Embed a single object (MUST be optional)
var favoritePond: EmbeddedPond? = null
}
class Forest : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
// Embed multiple objects (can have many ponds)
var forestPonds: RealmList<EmbeddedPond> = realmListOf()
}
class EmbeddedPond : EmbeddedRealmObject {
var name: String? = null
}

Atlas App Services 스키마에서 내장된 객체가 각 상위 유형의 문서에 매핑되는 것을 볼 수 있습니다.

App Services 스키마
{
"title": "Frog",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"age": {
"bsonType": "long"
},
"favoritePond": {
"title": "EmbeddedPond",
"type": "object",
"required": [],
"properties": {
"name": {
"bsonType": "string"
}
}
},
"name": {
"bsonType": "string"
}
}
}
{
"title": "Forest",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"forestPonds": {
"bsonType": "array",
"items": {
"title": "EmbeddedPond",
"type": "object",
"required": [],
"properties": {
"name": {
"bsonType": "string"
}
}
}
},
"name": {
"bsonType": "string"
}
}
}

다음 표는 Realm 객체 유형이 해당 Atlas App Services 스키마 BSON 유형에 매핑되는 방법을 보여줍니다. 지원되는 Atlas App Services 스키마 유형과 해당 매핑, 사용 가능한 속성의 전체 목록은 Atlas App Services 문서의 데이터 모델 매핑 을 참조하세요.

다음 표에는 지원되는 Kotlin 데이터 유형과 선언된 속성이 Realm 스키마와 App Services 스키마 간에 매핑되는 방식의 예가 나와 있습니다.

Kotlin SDK에서 지원하는 Kotlin 데이터 유형과 Realm 데이터 모델에서 이를 정의하는 방법에 대한 자세한 내용은 Kotlin 데이터 유형을 참조하세요 .

Kotlin 데이터 유형
Realm 객체
App Services 스키마
String
var stringReq: String = ""
"stringReq": {
"bsonType": "string"
}
Byte
var byteReq: Byte = 0
"byteReq": {
"bsonType": "long"
}
Short
var shortReq: Short = 0
"shortReq": {
"bsonType": "long"
}
Int
var intReq: Int = 0
"intReq": {
"bsonType": "long"
}
Long
var longReq: Long = 0L
"longReq": {
"bsonType": "long"
}
Float
var floatReq: Float = 0.0f
"floatReq": {
"bsonType": "float"
}
Double
var doubleReq: Double = 0.0
"doubleReq": {
"bsonType": "double"
}
Boolean
var boolReq: Boolean = false
"boolReq": {
"bsonType": "bool"
}
Char
var charReq: Char = 'a'
"charReq": {
"bsonType": "long"
}

다음 표에는 지원되는 MongoDB BSON 데이터 유형과 선언된 속성이 Realm 스키마와 App Services 스키마 간에 매핑되는 방식에 대한 예가 나와 있습니다.

Kotlin SDK에서 지원하는 MongoDB BSON 데이터 유형과 이를 Realm 데이터 모델에서 정의하는 방법에 대한 자세한 내용은 Kotlin( Kotlin) 데이터 유형을 참조하세요.

MongoDB BSON 유형
Realm 객체
App Services 스키마
var objectIdReq: ObjectId = ObjectId()
"objectIdReq": {
"bsonType": "objectId"
}
Decimal128
var decimal128Req: Decimal128 = Decimal128("123.456")
"decimal128Req": {
"bsonType": "decimal"
}

다음 표에는 지원되는 Realm별 데이터 유형과 선언된 속성이 Realm 스키마와 Atlas App Services 스키마 간에 매핑되는 방식에 대한 예가 나와 있습니다.

Kotlin SDK에서 지원하는 Realm별 데이터 유형과 이를 데이터 모델에서 정의하는 방법에 대한 자세한 내용은 Kotlin 데이터 유형을 참조하세요.

영역별 유형
Realm 객체
App Services 스키마
var uuidReq: RealmUUID = RealmUUID.random()
"uuidReq": {
"bsonType": "uuid"
}
var realmInstantReq: RealmInstant = RealmInstant.now()
"realmInstantReq": {
"bsonType": "date"
}
var realmAnyOpt: RealmAny? = RealmAny.create("foo")
"realmAnyOpt": {
"bsonType": "mixed"
}
var mutableRealmIntReq: MutableRealmInt = MutableRealmInt.create(0)
"mutableRealmIntReq": {
"bsonType": "long"
}
var listReq: RealmList<CustomObjectType> = realmListOf()
"listReq": {
"bsonType": "array",
"items": {
"bsonType": "uuid"
}
}
var setReq: RealmSet<String> = realmSetOf()
"setReq": {
"bsonType": "array",
"uniqueItems": true,
"items": {
"bsonType": "string"
}
}
var dictionaryReq: RealmDictionary<String> = realmDictionaryOf()
"dictionaryReq": {
"bsonType": "object",
"additionalProperties": {
"bsonType": "string"
}
}
var realmObjectPropertyOpt: CustomObjectType? = null
"realmObjectPropertyOpt": {
"bsonType": "<PRIMARY_KEY_TYPE>"
}
var embeddedProperty: EmbeddedObjectType? = null
"embeddedProperty": {
"title": "EmbeddedObjectType",
"type": "object",
"required": [],
"properties": {
"name": {
"bsonType": "string"
}
}
}

돌아가기

객체 모델 변경

다음

Realm 구성 및 열기