Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django neo4j的短增量uinque id_Django_Python 3.x_Neo4j_Cypher - Fatal编程技术网

Django neo4j的短增量uinque id

Django neo4j的短增量uinque id,django,python-3.x,neo4j,cypher,Django,Python 3.x,Neo4j,Cypher,我使用django和neo4j作为数据库。我需要在RESTAPI中使用基于节点ID的短url。在neo4j中,数据库中使用了一个id,可在应用程序中使用,并且有一种使用uuid的方法对于我的短URL来说太长了。因此,我添加了uid生成器: def uid_generator(): last_id = db.cypher_query("MATCH (n) RETURN count(*) AS lastId")[0][0][0] if last_id is None:

我使用django和neo4j作为数据库。我需要在RESTAPI中使用基于节点ID的短url。在neo4j中,数据库中使用了一个id,可在应用程序中使用,并且有一种使用uuid的方法对于我的短URL来说太长了。因此,我添加了uid生成器:

def uid_generator():
    last_id = db.cypher_query("MATCH (n) RETURN count(*) AS lastId")[0][0][0]
    if last_id is None:
        last_id = 0
    last_id = str(last_id)
    hash = sha256()
    hash.update(str(time.time()).encode())
    return hash.hexdigest()[0:(max(2, len(last_id)))] + str(uuid.uuid4()).replace('-', '')[0:(max(2, len(last_id)))]

我有两个问题,首先我在堆栈溢出中读到了,但仍然不确定
MATCH(n)RETURN count(*)AS lastId
是否是
O(1)
没有引用它!这个答案有参考资料吗?第二,在id唯一性和速度方面有更好的方法吗?

为什么不创建自己的标识符?您可以获得上一个标识符的最大值(我们将其称为RN表示记录编号)

匹配(n)返回最大值(n.RN)作为lastID


max是cypher中的几个数值函数之一

您的方法不好,因为它基于数据库中的节点数

如果创建一个节点(称为a),然后删除一个随机节点,然后创建一个新节点(称为B),会发生什么

A和B将具有相同的ID,我认为这就是为什么您在代码中添加了基于时间的散列(但我几乎不理解这行:)

另一方面,Neo4j的ID确保您在整个数据库中都有一个唯一的ID,但在时间上没有。默认情况下,Neo4j回收未使用的ID(删除节点时释放ID)

您可以通过更改配置来更改此行为(请参阅文档):
dbms.ids.reuse.types.override=RELATIONSHIP


使用这种配置后,即使删除节点,硬盘上数据库的大小也只能增加。

首先,应在id属性上设置唯一约束,以确保并行create语句不会产生冲突。这需要使用一个标签,但如果您计划对这些数据进行任何严肃的处理,则需要这个故障保护。但是通过这种方式,您可以为不同的标签设置滚动ID。(所有索引标签都将有一个计数表。唯一约束也会创建索引)

第二,您应该像这样在同一个密码中进行生成和创建

MATCH (n:Node) WITH count(*) AS lastId
CREATE (:Node{id:lastId})
这将最大限度地缩短生成和提交之间的时间,减少冲突的机会。(请记住,对来自唯一冲突的失败尝试重试)

我不确定你在用哈希做什么,只是你做错了。要么生成一个新的基于时间的UUID(它不需要任何参数)并按原样使用,要么使用有罪的id。(通过更改UUID,可以使保证唯一性的逻辑失效,从而显著增加冲突机会)


还可以将当前索引计数存储在节点中,如图所示。它不能保证线程安全,但只要您有唯一的约束,并在违反约束时重试,就不应该成为问题。这将更能容忍删除节点。

您可以通过分析查询来检查自己:
profile MATCH(n)RETURN count(*)
您应该看到
NodeCountFromCountStore
,这意味着这是从计数存储中进行的O(1)查找,而不是在图本身中对其进行计数。如果您计划删除图中的节点,“这将对这种方法造成阻碍。@InverseFalcon感谢您的回答,现在什么是短唯一id的最佳方法?快速澄清。如果创建节点1、2、3、4、5和删除3,则生成的下一个节点将接收id 3。(正如您的措辞所建议的,同时拥有两个id为5的节点)节点id保证是唯一的,并且在节点的生命周期内不会更改。(当您必须删除一个节点时,使用此ID可能会导致不一致)在最后一行中,我使用历元时间sha256哈希和uuid.uuid4的组合来改进uid的唯一性。我使用节点数来确定创建的uid的长度,因为我需要我的uid是增量的。这个解决方案不好,因为它很复杂。它的执行时间直接取决于数据库中的节点数。问题是如何获得自己的标识符!!在最后一行中,我使用了历元时间sha256哈希和uuid.uuid4的组合来改进uid的唯一性。我使用节点数来确定创建的uid的长度,因为我需要我的uid是增量的。@SaeedBabashahi UUID不是魔术。它们是逻辑算法,设计用于最小化冲突,即使在不同系统上生成。通过改变它,你只能使它变得不那么独特(除非你只是串联)。您需要使用UUID或递增ID。不过我会给您一个折衷方案。使用
YYYYMMDDhhmmss-
作为索引。或者换句话说,对订单部分使用从最大到最小的格式化日期,并在末尾附加UUID以确保唯一性。可以设置一个参数,说明您真正想要的是“创建日期”字段。As索引不关心创建的订单项。所以真正的问题是,为什么您需要一个唯一且不断增加的主id?您试图解决的实际问题是什么?正如我在问题中所说的,我需要短增量id来处理rest api中节点的短url。@SaeedBabashahi,这将是“扩展id”。“增量”表示“导致离散增量”,即每个ID必须大于前一个ID。无论哪种方式,这就是为什么仍然使用自动增量ID。Neo4j不自动支持此功能,但您可以获得。只要您有唯一的约束和重试。您甚至可以将数字转换为十六进制表示形式来压缩它。