首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在数据库中存储以Java表示的“大”数据的最佳实践是什么?

在数据库中存储以Java表示的“大”数据的最佳实践是什么?
EN

Stack Overflow用户
提问于 2015-06-25 23:28:53
回答 1查看 901关注 0票数 1

在数据库中存储以Java表示的“大”数据的最佳实践是什么?

我正在考虑三种变体:

  1. 使用@OneToMany将数据存储在单独的表中。
  2. 序列化数据并将其存储在父表中。
  3. 将数据存储为文件(命名约定)?和身份证一样?)。

更具体地说

大型数据实体:

代码语言:javascript
复制
class SingleSleeper{

    private Double startPositionOnLeft;
    private Double endPositionOnLeft;
    private Double startPositionOnRight;
    private Double endPositionOnRight;
....
}

class RutEntry{

    private Double width;
    private Double position;
...
}

在一个父实例中大约有50个SingleSleeper类实例和大约25000个RutEntry类实例。父实例大约每天生成40次。我使用的是EclipseLink JPA2.1,德比

加法

最重要的是,我对Java中最好的可读性感兴趣。但是,如果我将过多的数据存储到数据库中,那么数据库的速度恐怕会大大降低。大量请求将选择特定父实体的SingleSleeper或RutEntry类的所有实例。我对支持不同的数据库类型不感兴趣,但如果需要,我可以迁移到其他数据库。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-29 07:53:42

我想我不会做任何你的变体。

我会在子实体中添加一个ManyToOne (这在某种程度上与第一个变体相反):

代码语言:javascript
复制
public class SingleSleeper {
   @ManyToOne(optional = false, fetch = FetchType.LAZY)
   private ParentEntity parent;

   ...
}

public class RutEntry {
   @ManyToOne(optional = false, fetch = FetchType.LAZY)
   private ParentEntity parent;

}

这确保了您有一个映射,并且如果您不需要父对象,就永远不会加载父对象的所有25000个实体(懒散的提取确保您甚至不需要加载父实体)。

如果您真的想要的话,可以在父对象中创建一个带有OneToMany链接的mappedBy。例如,因为您总是需要父实体中的所有子对象:

代码语言:javascript
复制
class ParentEntity {
    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
    Collection<SingleSleeper> singleSleepers;

    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
    Collection<RutEntry> rutEntries;
}

但是我不知道EclipseLink在这里是如何工作的--对于Hibernate,至少需要一个附加的BatchSize注释来指示它应该同时加载尽可能多的子实体。它不能与父实例(例如,将这两个实例定义为FetchType.EAGER)一起获取,因为只允许急切地获取一个结果行(否则,相应的select语句的结果集中将有25000 *50个结果行)。

加载父实体的所有子实体的最佳方法是分别加载它们,或者使用JPQL (更容易阅读,更快编写),或者使用标准API (typesafe,但您需要元模型):

代码语言:javascript
复制
ParentEntity parent = entityManager.find(ParentEntity.class, id);

// JPQL:
List<SingleSleeper> singleSleepers = entityManager.createQuery(
   "SELECT s FROM SingleSleeper s WHERE s.parent = %parent"
   ).setParameter("parent", parent).getResultList();

// Or Criteria API:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<SingleSleeper> query = criteriaBuilder.createQuery(SingleSleeper.class);
Root<SingleSleeper> s = query.from(SingleSleeper.class);
query.select(s).where(criteriaBuilder.equal(s.get(SingleSleeper_.parent), parent));
List<SingleSleeper> singleSleepers = entityManager.createQuery(query).getResultList();

这种方法有三个优点:

  1. 仍然容易阅读-如果你把加载到自己的方法。
  2. 您可以灵活地决定何时加载25050名儿童。
  3. 您也可以加载子程序的一个子集(通过使用createQueryQuery.setMaxResults修改结果)。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31062477

复制
相关文章

相似问题

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