35

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

因此,用户 A 更改(当他离线时)一些数据(换句话说,他会更新数据库条目)或将新记录添加到数据库中。当用户 A 连接到 Internet 时,所有更改和新记录都会传递给其他协作用户。因此,用户 B 将获得更改/更新,并可以将它们插入/更新到用户 B 的本地设备数据库中。

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

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

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

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

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

另一种可能性是使用整数自增主键并使用第二列 uuid。因此,要在用户本地设备上工作,我会将此主键(整数)用于 JOINS 等,而我会使用 uuid 列与其他用户同步。

你们如何看待这种方法,或者您认为它是否需要做很多工作,因为您不会期望直接使用 UUID 作为主键会出现重大的性能问题?

还有其他建议吗?

4

2 回答 2

31

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

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

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

可能,但如果它变成设备大小的数据库的重大问题,我会有些惊讶。

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

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

另一种可能性是使用整数自增主键并使用第二列 uuid。因此,要在用户本地设备上工作,我会将此主键(整数)用于 JOINS 等,而我会使用 uuid 列与其他用户同步。

正确的。您将拥有一个 UUID->local 整数 ID 映射表,在网络协议中使用 UUID,并主要使用本地整数 ID 保留本地数据库。这是否会显着提高性能(特别是考虑到数据库模式复杂性的增加),我不能说。

你们如何看待这种方法,或者您认为它是否需要做很多工作,因为您不会期望直接使用 UUID 作为主键会出现重大的性能问题?

恕我直言,要么运行一些性能测试,以便获得一些具体的可比数据,要么只在您的数据库 I/O 看起来缓慢时才担心它。

于 2013-01-06T17:50:56.657 回答
5

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

根据结果​​,二进制和字符串 UUID 在 SQLite 中都可以在索引时高效地创建和查询。一个单独的权衡是人类可读的字符串是否比二进制文件大小的较小数据大小更受欢迎。

于 2014-05-08T01:21:25.207 回答