Android:在SQLite中使用UUID作为主键

时间:2013-01-06 17:41:58

标签: android performance sqlite primary-key uuid

我的应用需要与其他应用用户同步(在自己的设备上)。我还想支持离线编辑,当用户连接到互联网时,这些编辑会与其他协作用户同步。

因此用户A改变(当他离线时)一些数据(用汉语来表示他将更新数据库条目)或向数据库添加新记录。当用户A连接到互联网时,所有更改和新记录都将传递给其他协作用户。因此,用户B将获得更改/更新,并可以将其插入/更新到用户B本地设备数据库中。

但我需要确保数据库条目的id在整个系统中是唯一的。因此我需要使用像UUID这样的东西。

我的问题:在android sqlite数据库表中使用UUID(String / Varchar)作为主键而不是自动递增的整数是不是一个坏主意?

我想通过使用字符串(UUID有36个字符)作为主键会出现性能问题。

我认为索引uuids而不是整数需要更长时间(比较字符串与比较整数)。我还猜测,当我使用UUID时,每次插入新的数据库记录/条目时,数据库都需要重新索引主键列,因为它们的主键索引不再处于排序顺序(这将是我何时使用整数自动递增主键,因为每个未来的记录都会在末尾添加,因为新的自动递增的主键始终是目前为止最大的数字,因此索引将自动按排序顺序排列)。我还需要做的是加入2到3张桌子。我还猜测,比较JOINS上的字符串而不是整数会减慢数据库查询的速度。

但是我无法看到实现这种协作同步系统的任何其他可能性,所以我必须使用UUID,对吗?

另一种可能性是使用整数自动增量主键并使用第二列uuid。因此,为了处理用户本地设备,我将使用此主键(整数)进行JOINS等,而我将使用uuid列与其他用户进行同步。

你们对这种方法有什么看法,或者你认为有多少工作,因为你不会期望UUID直接作为主键出现重大的性能问题?

还有其他建议吗?

2 个答案:

答案 0 :(得分:30)

  

在android sqlite数据库表中使用UUID(String / Varchar)作为主键而不是自动递增的整数是不是一个坏主意?

我能想到的唯一问题是,您将无法使用CursorAdapter及其子类来显示该表上的查询结果。 CursorAdapter需要_id中的唯一整数Cursor列,并且可能您不会拥有其中一列。您必须创建自己的适配器,可能会扩展BaseAdapter来处理它。

  

我想通过使用字符串(UUID有36个字符)作为主键会出现性能问题。

可能,但如果在设备大小的数据库中出现重大问题,我会感到有些惊讶。

  

但是我无法看到实现这种协作同步系统的任何其他可能性,所以我必须使用UUID,对吗?

您的网络协议需要某种UUID。据推测,您将需要数据库中的UUID。是否UUID需要是表的主键,我不能说,因为我不知道你的架构。

  

另一种可能性是使用整数自动增量主键并使用第二列uuid。因此,为了处理用户本地设备,我将使用此主键(整数)进行JOINS等,而我将使用uuid列与其他用户进行同步。

正确。您将拥有UUID->本地整数ID映射表,使用网络协议中的UUID,并使用本地整数ID保留本地数据库。这是否会带来显着的性能提升(特别是考虑到数据库架构复杂性的增加),我不能说。

  

你们对这种方法有什么看法,或者你认为有多少工作,因为你不会期望UUID直接作为主键出现重大的性能问题?

恕我直言,要么运行一些性能测试,以便获得一些具体的可比数据,要么只是担心如果你的数据库I / O看起来很迟钝。

答案 1 :(得分:5)

UUID作为二进制文本和文本的一组性能结果可以在一些相关的UUID / SQLite问题中找到:https://stackoverflow.com/a/11337522/3103448

根据结果,二进制和字符串UUID在索引时可以在SQLite中用于创建和查询。单独的权衡是人类可读字符串是否优先于二进制文件大小的较小数据大小。