我应该为 Realm 中的每个实体定义主键吗?

Should I define the primary key for each entity in Realm?

我注意到在 Realm 中设置 PK 不是必须的,可以省略。但在文档中指出:

Indexes are created automatically for primary key properties.

我想澄清一些问题:

1)PK的默认值是多少是Realm定义的,如果我不自己分配的话。它是散列还是什么? (如果我不设置PK就叫[MyRealmObject primaryKey]就returnsnil

2) 如果这个隐式 PK 默认被索引?我应该担心它吗,因为如果它没有被索引,是否意味着它会影响这个实体的一般性能(例如,获取对象)?

3) 每次为每个 RLMObject 子类定义 PK 是否是一个好习惯,或者它不是 Realm 所必需的并且可以简单地依赖于 Realm 本身定义的内部实现?

(免责声明:我为 Realm 工作。)

是的!在 Realm 中设置主键不是强制性的,也不是必需的,这就是为什么完全取决于开发人员和应用程序的要求来确定在他们的实现中是否有必要。

回答您的问题:

1) 没有默认值;您将自己的属性之一指定为主键。 primaryKey returns 默认情况下为零,因为您需要自己覆盖它以向 Realm 指示您要将哪个 属性 作为主键。一些用户将整数设置为主键,但通常情况下,使用 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 来说都是明确必需的,这些 API 会根据是否已经具有相同键的对象更改其功能存在于数据库中。例如,如果具有该主键的对象不存在,+[RLMObject createOrUpdateInRealm:] 将向数据库添加一个新的 Realm 对象,否则将简单地更新现有对象。

因此,在主键是后续逻辑的关键组件的这些情况下,它们是必需的。但是,由于这些 API 是可以在 Realm 中 add/update 数据的不同方式的子集,如果您选择不使用它们,您仍然不需要拥有主键。

马已经被打死了,但我还是忍不住参考了 Realm 代码,如果在没有主键的情况下创建或更新 Realm 对象,则会抛出异常。

+ (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);
}