我們知道,火力地堡沒有一個計數查詢,有一個計數器的方法有兩種,得到所有數據在客戶端或存儲在數據庫中的計數值。我使用第二種方法,因爲第一種方法只有在數據很少時纔有效。火力地堡計數器,增量更新的情況下
這種方法的問題是,我可以有很多併發的作家,我用我的方法解決了這個問題,如果數據未被存儲,它會嘗試用增加或減少的計數器來重新保存數據。
確定當我只想更改一個計數器時,此方法運行良好,但在不同的情況下,我想用一個事務更改許多不同的計數器,並且在此模式下存在一種風險,即經過不同的嘗試後數據無法保存,因爲我們可以在許多不同的節點中擁有許多併發寫入器。與原子更新數據結構的一個例子是如下:
如果我保存這個
"comment": {
"counter": {},
"Data": {
"$Comment":{}
}
}
comment/counter = val + 1
comment/Data/comment1 = data
它的工作原理,如果我不更新,因爲其他作家正在更新計數器就在我可以用一個新的重試計數器的值,通常第一次後,我得出結論:成功的操作,但舉例來說,如果我想刪除一個用戶,他的一切行動,我想存儲這種類型的數據
"comment":{
"counter":{},
"Data": {
"$Comment":{}
}
},
"$user": {
"follower":{
"counter":{},
"data":{
"$Follower": {}
}
}
}
comment/counter = val - 1
comment/Data/comment2 = null
user1/follower/counter = val - 1
user1/follower/data/user30 = null
user2/follower/counter = val - 1
user2/follower/data/user30 = null
user3/follower/counter = val - 1
user3/follower/data/user30 = null
是可見的,在大批量更新的情況下,我必須更新很多計數器t可以有很多併發編寫器,在這種情況下,很容易在不同的重試之後無法更新所有計數器。
另一種情況是這樣的
"photo":{
"$photo":{
"comment":{
"counter":{},
"Data": {
"$Comment":{}
}
}
}
photo/10/comment/counter = val - 1
photo/10/comment/Data/comment1 = null
photo/10/comment/counter = val - 1
photo/10/comment/Data/comment2 = null
photo/10/comment/counter = val - 1
photo/10/comment/Data/comment3 = null
在這種情況下,這是不可能的,因爲我嘗試刪除具有相同的計數器不同意見,可以是僅值+ 1或價值相等更新計數器 - 1 。如果我想刪除所有的用戶數據,他可能會在同一張照片上寫下一些評論,但是我不能刪除一個交易中的所有評論,因爲只有單筆交易才能更新計數器。
我看到很多這樣的併發症,只是因爲不存在存在於任何類型的數據庫(SQL或NoSQL的)的計數查詢。我不懂爲什麼。這涉及到很多問題,否則無解浪費時間
下面是我的javascript函數來更新計數器。它如果不能在該記得自己是一個遞歸函數,因爲其他的更新併發作家
this.singleUpdate = function (paths, increment, countPath, retryCounter, callback) {
firebase.database().ref(countPath).once('value', function (counter) {
var value = counter.val() ? counter.val().value : 0;
var countValue = increment ? value + 1 : value - 1;
paths[countPath] = { value: null };
if (!increment && countValue == 0) { paths[countPath] = null; }
else {
paths[countPath].value = countValue;
}
firebase.database().ref().update(paths, function (error) {
if (error) {
retryCounter++;
if (retryCounter < 3) { singleUpdate(paths, increment, countPath, retryCounter, callback); }
else { callback(false, error); }
} else {
return callback(true, countValue);
}
});
});
}
這是一個問題?如果是這樣,您是否可以提供演示此問題的代碼示例以及Firebase結構的片段(如文本請勿插入圖片),以便我們瞭解您的數據? – Jay
我發佈我的函數來更新計數器,但問題不在於客戶端代碼,而是在Firebase數據結構中,如果我想更新一些不同的計數器,可能我因爲更多計數器意味着更多可能的併發編寫者而導致我的事務失敗。但在firebase不存在一個計數查詢這是唯一的方法可能我認爲 – DThink