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

时间:2022-09-15 23:59:18

I have noticed that setting PK is not obligatory in Realm and simply can be omitted. But in documentation is stated that:

我注意到在领域中设置PK不是必须的,可以简单地忽略它。但在文件中指出:

Indexes are created automatically for primary key properties.

索引是为主键属性自动创建的。

And I'd like to clear up some questions:

我想澄清一些问题:

1) What is the default value for PK is defined by Realm, if I don't assign it by myself. Is it hash or whatever ? (If I don't set PK and call [MyRealmObject primaryKey] it returns nil)

1) PK的默认值是由Realm定义的,如果我不自己赋值的话。是哈希还是别的什么?(如果我不设置PK并调用[MyRealmObject primaryKey]它返回nil)

2) If this implicit PK is indexed by default ? Should I worry about it, because if it is not indexed, does it mean that it affects the general performance of this Entity (for example,fetching objects) ?

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

3) Is it a good practice to define PK every time for each RLMObject subclass or it isn't necessary for Realm and simply may rely on it's internal realization defined by Realm itself?

为每个RLMObject子类定义PK是一种好的做法吗?或者它对领域来说不是必需的,仅仅依赖于它的内部实现是由领域本身定义的?

2 个解决方案

#1


14  

(Disclaimer: I work for Realm.)

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

Yep! Setting a primary key in Realm isn't obligatory, nor necessary, which is why it's completely up to the developer and the requirements of the app to determine whether it's necessary or not in their implementation.

是的!在领域中设置主键不是必须的,也不是必须的,这就是为什么完全由开发人员和应用程序的需求来决定在实现中是否需要主键。

In response to your questions:

回答你的问题:

1) There are no default values; you specify one of your own properties as a primary key. primaryKey returns nil by default since you need to override that yourself in order to indicate to Realm which property you want to act as a primary key. Some users have set integers as primary keys, but more often than not, using a UUID string is the most common.

1)没有默认值;您将自己的一个属性指定为主键。primaryKey默认返回nil,因为您需要自己重写它,以便向领域表明您希望将哪个属性作为主键。有些用户将整数设置为主键,但通常使用UUID字符串是最常见的。

2) There's no implicit primary key. You must use the [RLMObject primaryKey] method to explicitly state which property is the primary key, and THEN it will be indexed. :)

2)没有隐式主键。您必须使用[RLMObject primaryKey]方法显式地声明哪个属性是主键,然后它将被索引。:)

3) In my own (spare-time) development experience, I usually find having a primary key makes it a lot easier to identify and handle specific objects. For example, if you're passing an object across threads, you can simply pass the primary key value and use [RLMObject objectForPrimaryKey:] to refetch the object. Obviously this depends on your own implementation requirements. You probably shouldn't add a primary key unless you find out you really need one.

3)在我自己的(业余时间)开发经验中,我通常发现拥有一个主键可以更容易地识别和处理特定的对象。例如,如果您正在跨线程传递一个对象,您可以简单地传递主键值并使用[RLMObject objectForPrimaryKey:]来重新获取该对象。显然,这取决于您自己的实现需求。您可能不应该添加主键,除非您发现您确实需要一个主键。

As an example, here's what you would add to your RLMObject subclass if you wanted to set a UUID string as a primary key:

举个例子,如果你想设置一个UUID字符串作为主键,你可以在你的RLMObject子类中添加以下内容:

@interface MyObject : RLMObject

@property NSString *uuid;

@end

@implementation MyObject

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

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

@end

I hope that helped!

我希望帮助!

Addendum: To elaborate upon some of the comments made below, primary keys are explicitly necessary for any Realm APIs that change their functionality depending on if an object with the same key already exists in the database. For example +[RLMObject createOrUpdateInRealm:] will add a new Realm object to the database if an object with that primary key doesn't already exist, and will simply update the existing object otherwise.

附录:要详细说明下面所做的一些注释,对于任何改变其功能的领域api来说,主键都是显式必需的,这取决于数据库中是否存在具有相同键的对象。例如,如果带有主键的对象不存在,那么将向数据库添加一个新的域对象,并且只会更新现有的对象。

As such, in these instances where a primary key is a critical component of the subsequent logic, they are required. However, since these APIs are a subset of the different ways in which it is possible to add/update data in Realm, if you choose to not use them, you still not required to have a primary key.

因此,在主键是后续逻辑的关键组件的这些实例中,它们是必需的。然而,由于这些api是在领域中添加/更新数据的不同方式的子集,如果您选择不使用它们,仍然不需要拥有主键。

#2


2  

The horse has been beaten to death already, but I couldn't help but reference the Realm code which throws an exception if a Realm Object is created or updated without having a primary key.

这匹马已经被打死了,但是我不得不引用域代码,如果一个域对象在没有主键的情况下被创建或更新,就会抛出异常。

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

#1


14  

(Disclaimer: I work for Realm.)

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

Yep! Setting a primary key in Realm isn't obligatory, nor necessary, which is why it's completely up to the developer and the requirements of the app to determine whether it's necessary or not in their implementation.

是的!在领域中设置主键不是必须的,也不是必须的,这就是为什么完全由开发人员和应用程序的需求来决定在实现中是否需要主键。

In response to your questions:

回答你的问题:

1) There are no default values; you specify one of your own properties as a primary key. primaryKey returns nil by default since you need to override that yourself in order to indicate to Realm which property you want to act as a primary key. Some users have set integers as primary keys, but more often than not, using a UUID string is the most common.

1)没有默认值;您将自己的一个属性指定为主键。primaryKey默认返回nil,因为您需要自己重写它,以便向领域表明您希望将哪个属性作为主键。有些用户将整数设置为主键,但通常使用UUID字符串是最常见的。

2) There's no implicit primary key. You must use the [RLMObject primaryKey] method to explicitly state which property is the primary key, and THEN it will be indexed. :)

2)没有隐式主键。您必须使用[RLMObject primaryKey]方法显式地声明哪个属性是主键,然后它将被索引。:)

3) In my own (spare-time) development experience, I usually find having a primary key makes it a lot easier to identify and handle specific objects. For example, if you're passing an object across threads, you can simply pass the primary key value and use [RLMObject objectForPrimaryKey:] to refetch the object. Obviously this depends on your own implementation requirements. You probably shouldn't add a primary key unless you find out you really need one.

3)在我自己的(业余时间)开发经验中,我通常发现拥有一个主键可以更容易地识别和处理特定的对象。例如,如果您正在跨线程传递一个对象,您可以简单地传递主键值并使用[RLMObject objectForPrimaryKey:]来重新获取该对象。显然,这取决于您自己的实现需求。您可能不应该添加主键,除非您发现您确实需要一个主键。

As an example, here's what you would add to your RLMObject subclass if you wanted to set a UUID string as a primary key:

举个例子,如果你想设置一个UUID字符串作为主键,你可以在你的RLMObject子类中添加以下内容:

@interface MyObject : RLMObject

@property NSString *uuid;

@end

@implementation MyObject

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

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

@end

I hope that helped!

我希望帮助!

Addendum: To elaborate upon some of the comments made below, primary keys are explicitly necessary for any Realm APIs that change their functionality depending on if an object with the same key already exists in the database. For example +[RLMObject createOrUpdateInRealm:] will add a new Realm object to the database if an object with that primary key doesn't already exist, and will simply update the existing object otherwise.

附录:要详细说明下面所做的一些注释,对于任何改变其功能的领域api来说,主键都是显式必需的,这取决于数据库中是否存在具有相同键的对象。例如,如果带有主键的对象不存在,那么将向数据库添加一个新的域对象,并且只会更新现有的对象。

As such, in these instances where a primary key is a critical component of the subsequent logic, they are required. However, since these APIs are a subset of the different ways in which it is possible to add/update data in Realm, if you choose to not use them, you still not required to have a primary key.

因此,在主键是后续逻辑的关键组件的这些实例中,它们是必需的。然而,由于这些api是在领域中添加/更新数据的不同方式的子集,如果您选择不使用它们,仍然不需要拥有主键。

#2


2  

The horse has been beaten to death already, but I couldn't help but reference the Realm code which throws an exception if a Realm Object is created or updated without having a primary key.

这匹马已经被打死了,但是我不得不引用域代码,如果一个域对象在没有主键的情况下被创建或更新,就会抛出异常。

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