存储静态数据本地化

huangapple go评论71阅读模式
英文:

Storing static data locally

问题

我目前有200行键 -> 值的数据,每个键有两个值,尽管我只使用第一个值。

我想知道如何处理这种情况,是否可以使用JSON文件存储所有这些数据,然后将其转换为map<String,List<String>>,或者是否可以创建一个枚举类来存储所有这些数据?

我只是不太确定如何解决这个问题。

英文:

I currently have 200 rows of key -> value, values, where one key has two values. Even though I'm only using the first value.

I'm wondering about ways to handle this, whether using a json file to store all this data and converting it to a map<String, List<String>> or if I could create an enum class to store all this?

I'm just not sure how to solve this

答案1

得分: 0

假设需要持久化数据。

MapDB 在 Java 中非常适用于这样的需求。它可以用来存储任何可序列化的类型。

可以直接将 Map 存储在文件中并进行检索。
它内置支持事务。

import org.mapdb.DB;
import org.mapdb.DBMaker;

private DB mapDb;
private ConcurrentMap<String, LinkedHashSet> translationMap;

@PostConstruct
private void init() {
    log.info("Map db Start initiated...");

    mapDb = DBMaker
            .fileDB(new File(nosqlDbPath))
            .fileMmapEnable()
            .transactionEnable()
            .make();

    translationMap = (ConcurrentMap<String, LinkedHashSet>) mapDb.hashMap("map").createOrOpen();
    log.info("Map db Start completed.");
}

@PreDestroy
private void close() {
    log.info("Map db shutdown initiated...");
    mapDb.commit();
    mapDb.close();
    log.info("Map db shutdown complete.");
}

在启动时,translationMap 将保存所有数据。

不要忘记添加 MapDB 的 JAR 包。

英文:

Assuming the data needs to persist.

MapDB comes in handy for requirements like this in java. This can be used to store any serializable type.

Map can be directly stored in a file and retrieved.
It has embedded support for transactions.

import org.mapdb.DB;
import org.mapdb.DBMaker;

private DB mapDb;
    private ConcurrentMap&lt;String, LinkedHashSet&gt; translationMap;

    @PostConstruct
    private void init() {
        log.info(&quot;Map db Start initiated...&quot;);

        mapDb = DBMaker
                .fileDB(new File(nosqlDbPath))
                .fileMmapEnable()
                .transactionEnable()
                .make();

        translationMap = (ConcurrentMap&lt;String, LinkedHashSet&gt;) mapDb.hashMap(&quot;map&quot;).createOrOpen();
        log.info(&quot;Map db Start completed.&quot;);
    }


    @PreDestroy
    private void close() {
        log.info(&quot;Map db shutdown initiated...&quot;);
        mapDb.commit();
        mapDb.close();
        log.info(&quot;Map db shutdown complete.&quot;);

    }

translationMap would hold all the data on startup.

Don't forget to add the MapDB jars

答案2

得分: 0

由于条目只有200个,您有很多选择。

1. 只需将其存储在哈希映射中。

优点:

  • 简单直接,O(1) 查找。

缺点:

  • 如果有多个线程对其进行更改,可能会出问题。

  • 顺序不会被保留。

  • 没有提供 TTL(生存时间)。

2. 存储在 LinkedHashMap 中

与哈希映射相同,不同之处在于顺序将被保留。

3. 存储在 ConcurrentHashmap 中

与哈希映射相同,但是即使多个线程尝试对其进行更改,也可以使用此方法。

4. 存储在 CaffeineCache 中

您可以设置 TTL。

5. 存储在 EHCache 中

您可以设置 TTL。提供在 OffHeap 主内存中存储的功能。提供溢出到磁盘的功能。

上述所有方法都在利用主内存。这将为读取提供最高性能。不用说,这都是暂时的,一旦关闭机器,数据将消失。另一方面,在运行时,如果要对其进行更改并在重新启动后保留更改,可能需要考虑更持久的存储方式。

由于这是键值查找,您可以使用 static 块或带有 @PostConstruct 注解的方法或构造函数,在应用程序启动时填充它。或者,如果您在 Spring Boot 中,可以利用带有 @Configuration 注解的类以及与包含所有数据的属性/ YAML 文件一起使用 @Value 注解的 Map<String, Object> 成员变量,并将其注入进来。

关于两个值

如果您确定只会获得两个值,我会将其更改为具有类型的类,例如

class Values {
    Value left;
    Value right;
}

而不是 List,毕竟这是一种强类型语言的程序。

英文:

since its just 200 entries, you have a lot of options.

1. Just store it in a Hashmap.

Pros:

  • Simplest as it can get. O(1) look up

Cons:

  • If you have multiple threads mutating this, you are asking for trouble

  • Order will not be preserved

  • No provision to TTL

2. Store It in LinkedHashMap

Same as Hashmap except Order will be preserved

3. Store it in ConcurrentHashmap

Same as Hashmap except this one can be used even if multiple threads tries to mutate it

4. Store it in CaffeineCache

You can set TTL

5. Store it in EHCache

You can set TTL. Provision to store in OffHeap Primary Memory. Provision to overflow to Disk

All the aforementioned approaches are leveraging primary memory. It will give you the highest performance for Reads. This goes without saying, it's all ephemeral, as soon as you switch off the machine it will vanish. On the other hand, during runtime, if you want to mutate it and persist the mutations across restarts, you might need to look into more persistent storages.

Since it's a key-value look-up, you can use a static block or @PostConstruct annotated methods or Constructer to populate it when the app starts. Or if you are in spring-boot land, you could leverage @Configuration annotated class and @Value annotated Map<String,Object> member variable in conjunction with a property/yaml file where you have all the data and get it injected

Regarding 2 values

If you are sure, you will ever be getting only 2 values, I would change it as typed class, for example

class Values {
    Value left;
    Value right;
}

rather than a List<Value>, After all its a Strongly typed language program

huangapple
  • 本文由 发表于 2020年10月20日 22:05:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/64446876.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定