2017-07-20 73 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)的低概率.. 。)

玩得開心