在Java中使用枚举作为小型数据库的替代方案

在Java中使用枚举作为小型数据库的替代方案,java,database,enums,Java,Database,Enums,我有一个java应用程序,它使用一个类“Country”。业务逻辑将世界上的每个国家与以下内容关联: iso代码 国家电话号码 适合该国家/地区的TZ数据库时区ID列表 通常,这是一个完美的数据库数据。但是,考虑到该数据相当稳定(当然,它会不时发生变化,但通常不用于对这些记录执行创建/更新/删除操作),我考虑将信息放入如下枚举中: public enum Country { US(1,new String[]{"America\New York","America\California"

我有一个java应用程序,它使用一个类“Country”。业务逻辑将世界上的每个国家与以下内容关联:

  • iso代码
  • 国家电话号码
  • 适合该国家/地区的TZ数据库时区ID列表
  • 通常,这是一个完美的数据库数据。但是,考虑到该数据相当稳定(当然,它会不时发生变化,但通常不用于对这些记录执行创建/更新/删除操作),我考虑将信息放入如下枚举中:

    public enum Country
    {
    
       US(1,new String[]{"America\New York","America\California",...}),
    
       ...
    
       NL(31, new String[]{"Europe\Amsterdam"});
    
        ...
    
        public Country(int telephoneCode, String[] timezoneIds)
        {
           ...
        }
    }
    
    这种方法的可能优势:

  • 数据可以直接从java源代码中访问,因此进行数据库查询不会有延迟
  • 不需要在某个地方设置和维护数据库文件(这对我来说是件大事,因为我还不熟悉JDBC)
  • 缺点可能是:

  • 数据被“隐藏”在源代码中,如果政治发生变化,数据不会自动更新
  • 如果枚举发生更改,则必须重新分发代码。(见附件。)
  • 与获取特定信息的数据库查询相比,“大”枚举(超过200个可能值)的性能如何?
  • 我想问一个粗体的问题(缺点3),但欢迎对更大范围的问题发表意见


    我知道java中的Locale类可以用来获取java系统中已知的所有可能国家的列表。不幸的是,电话和时区信息不可用。我的目的是将这些数据合并到一个枚举中。这种做法被认为是一种合理的替代方案还是黑客反模式

    我只能同意目前为止的评论。一个国家的名单可能会改变,但它总是小到足以将整个名单留在记忆中。如果只查询一次然后缓存,那么性能上的任何差异实际上并不重要

    这可能取决于谁在使用该软件(个人使用或大型公司),但我想说,这里最大的担忧是2,而不是3。在代码中与在数据库中,应该根据以后可能需要更改值的人来决定。你真的需要一个开发人员来更改一个值,重新编译所有内容并推出新版本或补丁软件吗?只需更新文本文件或数据库就会容易得多

    如果它是一个个人项目,那么这个参数可能对你来说并不重要,但即使是这样,文本文件(例如CSV格式)也可能比代码更容易维护。我仍然建议使用一个简单的数据库——只是为了学习体验。您不需要设置像MySQL这样的大型数据库系统。您可以使用小型可嵌入数据库,如或


    仅供参考国家代码和名称的更改频率:


    ISO 3611-1(定义了现有国家的语言和国家代码)。这大约是每年2.4次。

    创建一个Enum没有问题:一般来说,国家变化很少

    我的建议是:

  • 使用枚举
  • 在初始化期间在数据库上存储数据并加载项(静态缓存)
  • 使用命中和未命中缓存(,…)
  • 使用

  • 如果您有一个枚举,但从未在源代码中使用常量,那么这就是代码的味道。这看起来像应该驻留在数据库中的数据。在没有实际测试的情况下担心性能还为时尚早,但如果所有其他方面都失败了,您始终可以缓存整个数据集。与执行数据库查询相比,在200个成员的枚举中查找值的性能就像到下一个房间比到月球一样。访问内存要比通过网络往返访问数据库快得多。除了JB的评论外,即使这些信息在数据库中,也最好在内存中缓存一次,然后从缓存中多次访问。即使不考虑性能,我认为可以保证一份国家名单在很长一段时间内保持不变(除非我们有另一个小国获得独立并由国际标准化组织指定新的国际标准化组织代码),该国的时区也是如此。我不会为此创建数据库表。