web-dev-qa-db-ja.com

レルムの各エンティティの主キーを定義する必要がありますか?

レルムではPKの設定は必須ではなく、単に省略できることに気づきました。しかし、ドキュメントには次のように記載されています。

主キープロパティのインデックスは自動的に作成されます。

そして、私はいくつかの質問をクリアしたいと思います:

1)PKのデフォルト値は、自分で割り当てない場合、レルムによって定義されます。ハッシュか何か? (PKを設定せずに[MyRealmObject primaryKey]を呼び出すと、nilが返されます)

2)この暗黙のPKがデフォルトでインデックス付けされている場合は?インデックスが作成されていない場合、このエンティティの一般的なパフォーマンス(オブジェクトのフェッチなど)に影響を与えることを意味するので、心配する必要がありますか?

3)RLMObjectサブクラスごとに毎回PKを定義するのは良い習慣ですか、それともRealmには必要なく、Realm自体によって定義された内部実現に依存するだけですか?

19
David

(免責事項:私はレルムで働いています。)

うん! Realmで主キーを設定することは必須ではなく、必須でもありません。そのため、実装で必要かどうかを判断するのは、開発者とアプリの要件に完全に依存します。

あなたの質問に答えて:

1)デフォルト値はありません。独自のプロパティの1つを主キーとして指定します。 primaryKeyは、主キーとして機能するプロパティをレルムに示すために自分でオーバーライドする必要があるため、デフォルトでnilを返します。一部のユーザーは主キーとして整数を設定していますが、多くの場合、UUID文字列を使用するのが最も一般的です。

2)暗黙の主キーはありません。 [RLMObject primaryKey]メソッドを使用して、どのプロパティが主キーであるかを明示的に指定する必要があります。そうすると、インデックスが作成されます。 :)

3)私自身の(空き時​​間の)開発経験では、通常、主キーがあると、特定のオブジェクトの識別と処理がはるかに簡単になることがわかります。たとえば、スレッド間でオブジェクトを渡す場合は、主キー値を渡し、[RLMObject objectForPrimaryKey:]を使用してオブジェクトを再フェッチするだけです。明らかに、これはあなた自身の実装要件に依存します。本当に必要であることがわからない限り、主キーを追加するべきではありません。

例として、UUID文字列を主キーとして設定する場合にRLMObjectサブクラスに追加するものを次に示します。

@interface MyObject : RLMObject

@property NSString *uuid;

@end

@implementation MyObject

+ (NSString *)primaryKey
{
   return @"uuid";
}

+ (NSDictionary *)defaultPropertyValues
{
   @{@"uuid": [[NSUUID UUID] UUIDString]};
}

@end

お役に立てば幸いです。

補遺:以下のコメントのいくつかを詳しく説明するために、同じキーを持つオブジェクトがデータベースにすでに存在するかどうかに応じて機能を変更するRealm APIには、主キーが明示的に必要です。たとえば、+[RLMObject createOrUpdateInRealm:]は、その主キーを持つオブジェクトがまだ存在しない場合はデータベースに新しいRealmオブジェクトを追加し、そうでない場合は既存のオブジェクトを更新するだけです。

そのため、主キーが後続のロジックの重要なコンポーネントであるこれらのインスタンスでは、それらが必要です。ただし、これらのAPIは、レルムでデータを追加/更新できるさまざまな方法のサブセットであるため、APIを使用しないことを選択した場合でも、主キーは必要ありません。

16
TiM

馬はすでに殴打されて死んでいますが、主キーなしでレルムオブジェクトが作成または更新された場合に例外をスローするレルムコードを参照せずにはいられませんでした。

+ (instancetype)createOrUpdateInRealm:(RLMRealm *)realm withValue:(id)value {
    // verify primary key
    RLMObjectSchema *schema = [self sharedSchema];
    if (!schema.primaryKeyProperty) {
        NSString *reason = [NSString stringWithFormat:@"'%@' does not have a primary key and can not be updated", schema.className];
        @throw [NSException exceptionWithName:@"RLMExecption" reason:reason userInfo:nil];
    }
    return (RLMObject *)RLMCreateObjectInRealmWithValue(realm, [self className], value, true);
}
2
Stephen Paul