2013-01-06 207 views
30

我的應用需要與其他應用用戶(在自己的設備上)同步。我還希望支持離線編輯,當用戶連接到互聯網時,這些編輯將與其他協作用戶同步。Android:使用UUID作爲SQLite的主鍵

因此,用戶A(當他離線時)改變了一些數據(以更好的語言,他將更新數據庫條目)或向數據庫添加新的記錄。當用戶A連接到互聯網時,所有更改和新記錄都會發送給其他協作用戶。因此,用戶B將獲得更改/更新,並且可以將它們插入/更新到用戶B本地設備數據庫中。

但我需要確保數據庫條目的id在整個系統中是唯一的。因此我需要使用像UUID這樣的東西。

我的問題:在android sqlite數據庫表中使用UUID(字符串/ Varchar)作爲主鍵而不是自動遞增的整數是不是一個好主意?

我想通過使用字符串(一個UUID有36個字符)作爲主鍵會出現性能問題。

我猜索引uuids而不是整數需要更長的時間(比較字符串與比較整數)。我也猜測,當我使用UUID時,每次插入一個新的數據庫記錄/條目時,數據庫都需要重新索引主鍵列,因爲它們的主鍵索引不再是排序順序了(這將是我何時使用整數自動增加主鍵,因爲每個將來的記錄都在最後添加,因爲新的自動遞增主鍵總是迄今爲止最大的數字,因此索引將自動按照排序順序)。我還需要做的是連接2 - 3表。我也猜測在JOINS而不是整數上比較字符串會減慢數據庫查詢的速度。

但是我不能看到任何其他可能性來實現這樣的協作同步系統,所以我必須使用UUID,對吧?

另一種可能性是使用整數自動增加主鍵和使用第二列uuid。因此,爲了處理用戶本地設備,我會將這個主鍵(整數)用於JOINS等,而我將使用uuid列與其他用戶進行同步。

你們認爲這種方法或您認爲很多工作是什麼,因爲您不會直接將UUID作爲主鍵使用,因此您不會期望出現重大性能問題?

其他建議?

回答

27

在android sqlite數據庫表中使用UUID(字符串/ Varchar)作爲主鍵而不是自動增加的整數是不是一個好主意?

我能想到的唯一可以確定的問題是,您將無法使用CursorAdapter及其子類來顯示該表上的查詢結果。 CursorAdapterCursor中需要一個唯一的整數_id列,並且大概你不會有其中的一個。您將不得不創建自己的適配器,它可能會擴展到處理它的BaseAdapter

我想通過使用字符串(一個UUID有36個字符)作爲主鍵會有性能問題。

可能,但如果它變成設備大小的數據庫的重大問題,我會有點驚訝。

但是我不能看到任何其他的可能性來實現這樣的協作同步系統,所以我必須使用UUID,對吧?

您需要某種UUID用於您的網絡協議。據推測,你將需要在你的數據庫中的UUID。無論該UUID是否需要成爲表格的主鍵,我都不能說,因爲我不知道您的模式。

另一種可能性是使用整數自動增加主鍵並使用第二列uuid。因此,爲了處理用戶本地設備,我會將這個主鍵(整數)用於JOINS等,而我將使用uuid列與其他用戶進行同步。

正確。您將擁有一個UUID->本地整數ID映射表,在您的網絡協議中使用UUID,並使本地數據庫大部分使用本地整數ID。不管這是否會顯着提高性能(特別是考慮到數據庫架構複雜性增加),我不能說。

你們認爲這種方法或你認爲很多工作是什麼,因爲你不會期望通過直接使用UUID作爲主鍵的重大性能問題?

恕我直言,要麼運行一些性能測試,所以你得到一些具體的可比數據,或者只是擔心它,如果你的數據庫I/O似乎呆滯。

+0

您可以將UUID存儲爲16字節的二進制文件 –

+0

@EirNym:這很好理解,儘管我沒有看到它與問題,答案或我的答案的明顯倒退有什麼關係。 – CommonsWare

+0

你說SQLite3中的ASCII表示只是一個UUID,並告訴它缺點。二進制表示沒有這樣的缺點:對於那些推薦在2013年最低的Android 2.3+的設備,它足夠快。今天我們有更快的設備,我們不僅可以使用SQLite3作爲數據庫引擎,而且它將保持通用。 –

2

一組性能結果的UUID二進制和文本可以在一定程度上相關的UUID/SQLite的問題中找到:https://stackoverflow.com/a/11337522/3103448

%的結果,二進制和字符串的UUID可以高效SQLite中用於創建和查詢時索引。單獨的權衡是人類可讀字符串是否優於二進制文件大小的較小數據大小。

相關問題