2017-07-20 37 views
0

我目前正在使用PostgreSQL数据库,Spring和Hibernate。我有一个表的属性correlation_id是唯一的。每次在我首先添加一个新元素之前,我必须检查任何具有新的correlation_id的项目是否已经存在于数据库中。在数据库和内存中搜索数据时的性能

对于这种情况,我已经实现了递归函数,它将生成一个新的correlation_id并检查它是否存在或不在db中。这意味着这个函数每次都会调用db,所以有时候可能只是一次调用,但有时我可能会是五次,十次甚至更多。这个例子在示例一中显示。

例1:

private String generateId() { 

    String myId = StaticFunction.generateMyId(); 
    MyMessages doesExist = MyServiceDaoImpl.checkDoesItExistInDB(myId); 
    if(doesExist != null) { 
     generateId(); 
    } 

    return myId; 
} 

在第二个例子,我想我可以只创建一个调用数据库和检索所有项目,并把它们放到收集。然后我可以通过流来搜索特定的物品,同时使用递归功能。 例2:

private String generateId(List<MyMessages> messages) { 
    String myId = StaticFunction.generateMyId();   

    MyMessages myMessage = messages.stream().filter(m -> 
     m.getCorrelationId.equals(myId)).findFirst().orElse(null); 
    if (MyMessages != null) { 
     generateId(messages); 
    } 

    return myId; 
} 

我的问题是什么是让这件事情吧,最好的办法?你有其他解决方案吗?以上例子的优点和缺点是什么?

+0

你为什么不使用数据库生成的ID –

+1

和第三选择是刚插入任何和失败的重复键 –

+0

@ScaryWombat我不使用,因为某些原因产生的ID correlation_id有时可以为null,并且我还需要一些项目以包含null作为correlation_id –

回答

1

如果您不能使用db生成的id,如评论中所建议的那样,您可以使用UUID生成器来创建PK。碰撞概率非常低,不值得在db中检查。

对于Java中生成的UUID看看http://docs.oracle.com/javase/7/docs/api/java/util/UUID.html

+0

我知道,但仍有可能两个项目包含相同的correlation_id。反正用UUID我可能会减少对db的调用。 –

+1

你被陨石击中的可能性要比UUID碰撞更有可能 – Andres

+0

哈哈是的,你说得对,但是想象你正在制作应付钱等的应用程序,这是不可接受的 –

0

有什么不妥情况1,当列索引,数据库可以做到查找非常effeciently。但是 - 你需要做数据库访问。

第二种情况看起来要快得多(在内存中迭代将比任何数据库访问快得多),但它有缺点:必须将所有消息(或至少它们的相关标识符)保存在内存中,并且当有A大量的数据,你scr ..你将有不良的时间来修复它

以及您的应用程序的多个实例可以访问数据库的可伸缩性。

因此,我建议让数据库生成密钥(您可以使用例如SERIAL数据类型),并在保存对象时返回生成的密钥。如果您需要自定义ID(以您的应用程序生成的),你可以使用UUID那里的价值冲突

除了可以使用UPSERT语法(INSERT .... ON CONFLICT(CORRELATION_ID)的低概率.. 。)

玩得开心