Neo4j SDN4和正确使用内部ID
我读到将Neo4j内部ID用于外部目的不是一个好的实践 我想我在SDN4/Neo4j应用程序中犯了一个错误,因为我到处都在使用内部ID 我的应用程序中的每个SDN 4节点实体都具有以下属性:Neo4j SDN4和正确使用内部ID,neo4j,spring-data-neo4j-4,neo4j-ogm,Neo4j,Spring Data Neo4j 4,Neo4j Ogm,我读到将Neo4j内部ID用于外部目的不是一个好的实践 我想我在SDN4/Neo4j应用程序中犯了一个错误,因为我到处都在使用内部ID 我的应用程序中的每个SDN 4节点实体都具有以下属性: @GraphId private Long id; 我将此长值用作web应用程序URL的一部分。。比如说 /products/3245234 其中,3245234是该产品节点实体的内部Neo4j标识符 从Neo4j的角度来看,以这种方式使用内部ID安全吗?如果没有,请提供一个新代理密钥如何解决此问题的示
@GraphId
private Long id;
我将此长值用作web应用程序URL的一部分。。比如说
/products/3245234
其中,3245234是该产品节点实体的内部Neo4j标识符
从Neo4j的角度来看,以这种方式使用内部ID安全吗?如果没有,请提供一个新代理密钥如何解决此问题的示例。从应用程序视图来看,使用Neo4j内部id是安全的,因为使用它们不会破坏应用程序中的任何内容 这就是说,Neo4j内部id被回收,我的意思是,如果一个节点或关系的内部id为12345,并且在某个点上该节点或关系被删除,那么12345的id将有资格被未来的节点或关系重用。我认为,明智的做法是假设新的可用id将在将来某个时候重新使用。这有消极的副作用,即Neo4j内部id不被认为是“稳定的”,不应在应用程序之外使用
作为一个新代理密钥的示例,我将向您介绍GraphAware的neo4j uuid项目。此Neo4j插件可用于在所有节点和关系上自动创建唯一且稳定的UUID,这些节点和关系不会也不能更改或更新。从应用程序视图来看,使用Neo4j内部id是安全的,因为应用程序中的任何内容都不会因使用它们而中断 这就是说,Neo4j内部id被回收,我的意思是,如果一个节点或关系的内部id为12345,并且在某个点上该节点或关系被删除,那么12345的id将有资格被未来的节点或关系重用。我认为,明智的做法是假设新的可用id将在将来某个时候重新使用。这有消极的副作用,即Neo4j内部id不被认为是“稳定的”,不应在应用程序之外使用
作为一个新代理密钥的示例,我将向您介绍GraphAware的neo4j uuid项目。此Neo4j插件可用于在所有节点和关系上自动创建唯一且稳定的UUID,这些节点和关系不会也不能更改或更新。Eric所说的Neo4j内部ID如何回收是正确的 我们已经开始向SDN添加支持,以帮助开发人员解决这个问题。我们可以通过几个例子来做到这一点 示例1:当您有一个自然ID时 假设我们有一个用户域对象,它由一个名为email的字段唯一标识。我们可以这样设置模型:
@NodeEntity
public class User {
@GraphId
private Long id;
@Index(unique=true, primary=true)
private String email;
...
}
然后,我们可以将存储库设置为:
public interface UserRepository extends CrudRepository<User, String> {
}
看看如何传入类的主ID
示例2:当您需要合成ID时
假设我们上面定义的用户有tweet。因为推特没有自然的ID,所以我们给它一个。避免ID冲突的最佳方法是使用类型4 UUID。幸运的是,Java预先打包了UUID,SDN支持UUID的持久性
import org.neo4j.ogm.annotation.typeconversion.Convert;
import org.neo4j.ogm.typeconversion.UuidStringConverter;
import java.util.UUID;
@NodeEntity
public class Tweet {
@GraphId
private Long id;
@Convert(UuidStringConverter.class)
@Index(unique = true, primary = true)
private UUID uuid;
...
public Tweet(String message) {
this.uuid = UUID.randomUUID();
// other initialisation.
}
}
所以我们这里有一个UUID分配给任何创建的Tweet。然后可以通过转换器将其保存到数据库中。关于这一点,最方便的是没有额外的库可安装。在大多数情况下,它也得到了很好的保证!永远不会有内部Neo4j ID的问题。赞成或反对的是,通过应用程序代码,ID被制造成具有普遍唯一性
如果您希望数据库始终生成UUID,那么我还推荐GraphAware插件
同样,Tweet存储库可以利用这一点:
public interface TweetRepository extends CrudRepository<Tweet, UUID> {
}
最后一个音符;在编写@Indexedunique=true时,primary=true可能会在SDN 5.0中被简单地称为@Id。Eric所说的关于Neo4j内部Id如何可以回收的问题是正确的 我们已经开始向SDN添加支持,以帮助开发人员解决这个问题。我们可以通过几个例子来做到这一点 示例1:当您有一个自然ID时 假设我们有一个用户域对象,它由一个名为email的字段唯一标识。我们可以这样设置模型:
@NodeEntity
public class User {
@GraphId
private Long id;
@Index(unique=true, primary=true)
private String email;
...
}
然后,我们可以将存储库设置为:
public interface UserRepository extends CrudRepository<User, String> {
}
看看如何传入类的主ID
示例2:当您需要合成ID时
假设我们上面定义的用户有tweet。因为推特没有自然的ID,所以我们给它一个。避免ID冲突的最佳方法是使用类型4 UUID。幸运的是,Java预先打包了UUID,SDN支持UUID的持久性
import org.neo4j.ogm.annotation.typeconversion.Convert;
import org.neo4j.ogm.typeconversion.UuidStringConverter;
import java.util.UUID;
@NodeEntity
public class Tweet {
@GraphId
private Long id;
@Convert(UuidStringConverter.class)
@Index(unique = true, primary = true)
private UUID uuid;
...
public Tweet(String message) {
this.uuid = UUID.randomUUID();
// other initialisation.
}
}
所以我们这里有一个UUID分配给任何创建的Tweet。然后可以通过转换器将其保存到数据库中。这件事最方便的地方是
没有要安装的额外库。在大多数情况下,它也得到了很好的保证!永远不会有内部Neo4j ID的问题。赞成或反对的是,通过应用程序代码,ID被制造成具有普遍唯一性
如果您希望数据库始终生成UUID,那么我还推荐GraphAware插件
同样,Tweet存储库可以利用这一点:
public interface TweetRepository extends CrudRepository<Tweet, UUID> {
}
最后一个音符;在编写@Indexedunique=true时,primary=true可能会在SDN 5.0中被简单地称为@Id。非常感谢您的详细回答!关于密码查询和UUID的一个后续问题。以前,我将其用作密码查询的参数Ids@GraphId以及以下语句-例如,{productIds}中的where IDp。。现在,我必须传递一组UUID,而不是内部ID。如何在{productUUIDs}中的Cypher-IDp或{productUUIDs}中的simlpe p中正确使用这些UUID。另外,从性能的角度来看,GraphId和@Indexunique=true,primary=true private UUID UUID UUID之间有什么区别吗?您应该能够执行类似于{productuuid}中的p.UUID,其中productuuid是字符串表示形式。我不确定目前是否支持存储库方法的参数转换,但我们将在下一个版本中提供。关于性能,如果您启用了自动索引,或者您已经为该标签的uuid属性编制了索引,那么它应该会非常快,因为查找是通过索引完成的。非常感谢您提供详细的答案!关于密码查询和UUID的一个后续问题。以前,我将其用作密码查询的参数Ids@GraphId以及以下语句-例如,{productIds}中的where IDp。。现在,我必须传递一组UUID,而不是内部ID。如何在{productUUIDs}中的Cypher-IDp或{productUUIDs}中的simlpe p中正确使用这些UUID。另外,从性能的角度来看,GraphId和@Indexunique=true,primary=true private UUID UUID UUID之间有什么区别吗?您应该能够执行类似于{productuuid}中的p.UUID,其中productuuid是字符串表示形式。我不确定目前是否支持存储库方法的参数转换,但我们将在下一个版本中提供。关于性能,如果您启用了自动索引,或者您已经为该标签的uuid属性编制了索引,那么它应该非常快,因为查找是通过索引完成的。