我目前正在我的一个项目中使用数据通信,一个问题困扰着我。
以下是我的问题的简化版本:
为了简化插入过程,我尝试多次编写相同的数据(即不检查数据库中是否已经存在记录)。但我担心表演的影响。
谢谢你的帮助
发布于 2016-12-26 21:41:49
从逻辑上讲,数据体数据库是一组排序的数据集,因此多次添加相同的数据集是幂等的。但是,当您使用动态断言数据时,您可能会创建一个新的数据集,用于表示与旧数据集相同的信息。这就是:db/unique
进来的地方。
为了确保实体不会多次存储,您需要将:db/unique
属性属性设置为:db.unique/identity
,以获得正确的属性。例如,如果您的模式包含3个属性:word/text
、:sentence/text
和:sentence/words
,那么:word/text
和:sentence/text
应该是:db.unique/identity
,这将产生以下模式安装事务:
[{:db/cardinality :db.cardinality/one,
:db/fulltext true,
:db/index true,
:db.install/_attribute :db.part/db,
:db/id #db/id[:db.part/db -1000777],
:db/ident :sentence/text,
:db/valueType :db.type/string,
:db/unique :db.unique/identity}
{:db/cardinality :db.cardinality/one,
:db/fulltext true,
:db/index true,
:db.install/_attribute :db.part/db,
:db/id #db/id[:db.part/db -1000778],
:db/ident :word/text,
:db/valueType :db.type/string,
:db/unique :db.unique/identity}
{:db/cardinality :db.cardinality/many,
:db/fulltext true,
:db/index true,
:db.install/_attribute :db.part/db,
:db/id #db/id[:db.part/db -1000779],
:db/ident :sentence/words,
:db/valueType :db.type/ref}]
然后插入的事务如下所示:
[{:sentence/text "Hello World!"
:sentence/words [{:word/text "hello"
:db/id (d/tempid :db.part/user)}
{:word/text "world"
:db/id (d/tempid :db.part/user)}]
:db/id (d/tempid :db.part/user)}]
关于业绩:
您可能根本不需要进行优化,但在我看来,导入过程中潜在的性能瓶颈是:
要改进2.
:当您插入的数据被排序时,索引的速度更快,所以应该是插入排序的单词和句子。您可以使用Unix工具对大型文件进行排序,即使它们不适合内存。因此,这个过程将是:
:sentence/text
):word/text
):sentence/words
)为了改进1.
:实际上,它可以减少对事务处理程序使用实体ids来处理已经存储的单词的压力,而不是使用整个单词文本(这需要索引查找以确保唯一性)。一种方法可以是通过利用并行性和/或仅针对频繁的单词来执行对等查询(例如,您可以从第一个1000个句子中插入单词,然后检索它们的实体in并将它们保存在一个散列图中)。
就我个人而言,在经验证明这些优化是必要的之前,我不会进行这些优化。
发布于 2016-12-23 18:35:13
你不需要担心像这样的预优化。零售电脑商店的硬盘售价约为0.05美元/GB,所以你在这里谈论的是价值50美分的存储空间。随着Datomic的内置存储压缩,这将是更小。索引&其他开销会稍微增加一些,但仍然太小,不值得担心。
与任何问题一样,最好是逐步构建解决方案。所以,也许用你的前1%的数据和时间做一个实验,这是最简单的算法。如果速度很快,就试试10%。现在您已经很好地估计了整个问题加载数据所需的时间。我打赌查询数据比加载更快。
如果您在前1%或10%之后遇到了一个障碍,那么您可以考虑重新设计。既然你已经构建了一些具体的东西,你就不得不更详细地思考这个问题&解决方案。这比挥舞着手的论点和白板设计要好得多。您现在对您的数据和可能的解决方案实现有了更多的了解。
如果发现最简单的解决方案不能在更大的范围内工作,那么第二个解决方案将更容易设计和实现,因为它具有第一个解决方案的经验。很少有最终的解决方案是从你的脑海中完全形成的。对于任何重大问题来说,对解决方案的反复改进都是非常重要的。
我最喜欢的一章是弗雷德·布鲁克斯( Fred )的开创性著作“神话中的男人月”()中的一章,题为“计划扔掉一个”。
发布于 2016-12-24 04:15:50
如果要添加具有唯一标识的单词/句子(:db.unique/ identity ),则Datomic将只在存储中保留它的一个副本(即单个实体)
同样,使用:db.unique/identity,那么您就不需要查询实体id来检查它的存在。
有关更多信息,请参阅这里
https://stackoverflow.com/questions/41305070
复制相似问题