首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否多次添加相同的数据不是最优的?

是否多次添加相同的数据不是最优的?
EN

Stack Overflow用户
提问于 2016-12-23 16:47:17
回答 3查看 247关注 0票数 3

我目前正在我的一个项目中使用数据通信,一个问题困扰着我。

以下是我的问题的简化版本:

  • 我需要分析一个小的英语句子列表,并将完整的句子和它的单词插入到数据体中。
  • 包含句子列表的文件相当大(> 10 GB)。
  • 相同的句子可以在文件中多次出现,它们的单词也可以多次出现在不同的句子中。
  • 在插入过程中,属性将设置为将每个句子与其相应的单词相关联。

为了简化插入过程,我尝试多次编写相同的数据(即不检查数据库中是否已经存在记录)。但我担心表演的影响。

  • 当相同的数据被多次添加时,数据通信中会发生什么情况?
  • 是否值得检查在事务之前是否已经添加了数据?
  • 是否有一种方法可以防止数据通信覆盖先前的数据(例如,如果已经存在记录,则跳过事务)?

谢谢你的帮助

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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,这将产生以下模式安装事务:

代码语言:javascript
运行
复制
[{: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}]

然后插入的事务如下所示:

代码语言:javascript
运行
复制
[{: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)}]

关于业绩:

您可能根本不需要进行优化,但在我看来,导入过程中潜在的性能瓶颈是:

  1. 在Transactor中构建事务所花费的时间(这包括索引查找唯一属性等)。
  2. 构建索引所花费的时间。

要改进2.:当您插入的数据被排序时,索引的速度更快,所以应该是插入排序的单词和句子。您可以使用Unix工具对大型文件进行排序,即使它们不适合内存。因此,这个过程将是:

  • 对句子排序,插入它们(:sentence/text)
  • 提取单词,排序,插入它们(:word/text)
  • 插入单词-句子关系(:sentence/words)

为了改进1.:实际上,它可以减少对事务处理程序使用实体ids来处理已经存储的单词的压力,而不是使用整个单词文本(这需要索引查找以确保唯一性)。一种方法可以是通过利用并行性和/或仅针对频繁的单词来执行对等查询(例如,您可以从第一个1000个句子中插入单词,然后检索它们的实体in并将它们保存在一个散列图中)。

就我个人而言,在经验证明这些优化是必要的之前,我不会进行这些优化。

票数 2
EN

Stack Overflow用户

发布于 2016-12-23 18:35:13

你不需要担心像这样的预优化。零售电脑商店的硬盘售价约为0.05美元/GB,所以你在这里谈论的是价值50美分的存储空间。随着Datomic的内置存储压缩,这将是更小。索引&其他开销会稍微增加一些,但仍然太小,不值得担心。

与任何问题一样,最好是逐步构建解决方案。所以,也许用你的前1%的数据和时间做一个实验,这是最简单的算法。如果速度很快,就试试10%。现在您已经很好地估计了整个问题加载数据所需的时间。我打赌查询数据比加载更快。

如果您在前1%或10%之后遇到了一个障碍,那么您可以考虑重新设计。既然你已经构建了一些具体的东西,你就不得不更详细地思考这个问题&解决方案。这比挥舞着手的论点和白板设计要好得多。您现在对您的数据和可能的解决方案实现有了更多的了解。

如果发现最简单的解决方案不能在更大的范围内工作,那么第二个解决方案将更容易设计和实现,因为它具有第一个解决方案的经验。很少有最终的解决方案是从你的脑海中完全形成的。对于任何重大问题来说,对解决方案的反复改进都是非常重要的。

我最喜欢的一章是弗雷德·布鲁克斯( Fred )的开创性著作“神话中的男人月”()中的一章,题为“计划扔掉一个”。

票数 1
EN

Stack Overflow用户

发布于 2016-12-24 04:15:50

  • 当相同的数据被多次添加时,数据通信中会发生什么情况?

如果要添加具有唯一标识的单词/句子(:db.unique/ identity ),则Datomic将只在存储中保留它的一个副本(即单个实体)

  • 是否值得检查在事务之前是否已经添加了数据?
  • 是否有一种方法可以防止数据组覆盖先前的数据(即,如果已经存在记录,则跳过事务)?*

同样,使用:db.unique/identity,那么您就不需要查询实体id来检查它的存在。

有关更多信息,请参阅这里

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41305070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档