Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/215.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/97.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用SQLite和Azure SQL数据库作为中心存储的在线/离线多客户端移动应用程序的最佳主键策略是什么?_Android_Ios_Sqlite_Database Design_Azure - Fatal编程技术网

Android 使用SQLite和Azure SQL数据库作为中心存储的在线/离线多客户端移动应用程序的最佳主键策略是什么?

Android 使用SQLite和Azure SQL数据库作为中心存储的在线/离线多客户端移动应用程序的最佳主键策略是什么?,android,ios,sqlite,database-design,azure,Android,Ios,Sqlite,Database Design,Azure,在以下情况下,关系数据库模型最适合使用什么主键策略 数以万计的用户 每个用户有多个客户端(电话、平板电脑、台式机) 每个表有数百万行(不断增长) Azure SQL将是通过Web API公开的中央数据存储。客户端将包括一个web应用程序和许多本机应用程序,包括iOS、Android、Mac、Windows 8等。web应用程序将需要一个“始终打开”的连接,并且不会有本地数据存储,而是通过api检索和更新-通过RESTful api思考CRUD 所有其他客户端(电话、平板电脑、桌面)都将有一个

在以下情况下,关系数据库模型最适合使用什么主键策略

  • 数以万计的用户
  • 每个用户有多个客户端(电话、平板电脑、台式机)
  • 每个表有数百万行(不断增长)
Azure SQL将是通过Web API公开的中央数据存储。客户端将包括一个web应用程序和许多本机应用程序,包括iOS、Android、Mac、Windows 8等。web应用程序将需要一个“始终打开”的连接,并且不会有本地数据存储,而是通过api检索和更新-通过RESTful api思考CRUD

所有其他客户端(电话、平板电脑、桌面)都将有一个本地数据库(SQLite)。首次使用这种类型的客户端时,用户必须进行身份验证和同步。经过身份验证和同步后,这些客户端可以在脱机模式下运行(在本地SQLite数据库中创建、删除和更新记录)。这些更改最终将与Azure后端同步

数据库的分布式特性给我们留下了一个主要的关键问题,以及提出这个问题的原因

以下是我们迄今为止所考虑的:

GUID

每个客户端都创建自己的密钥。在同步时,出现重复密钥的可能性很小,但我们需要将功能写入每个客户端,以使用新密钥更新所有关系。guid很大,当每个表考虑多个外键时,随着时间的推移,存储可能会成为一个问题。最大的问题可能是guid的随机性,这意味着由于碎片化,guid不能(或不应该)用作聚集索引。这意味着我们需要为每个表创建一个聚集索引(可能是任意的)

身份

每个客户端都创建自己的主键。同步时,这些密钥将替换为服务器生成的密钥。这增加了同步过程的复杂性,并迫使每个客户端“修复”其密钥,包括相关表上的所有外键

综合

在第一次同步时为每个客户端分配一个客户端id。此客户端id与本地自动递增id一起用作每个表的复合主键。此复合键将是唯一的,因此同步时不会发生冲突,但这确实意味着大多数表将需要复合主键。这里关注的是性能和查询复杂性

HiLo(合并复合)

与复合方法一样,在第一次同步时为每个客户机分配一个客户机id(int32)。客户机id与唯一的本地id(int32)合并到一个列中,以形成应用程序范围内的唯一id(int64)。这应该不会导致同步期间发生冲突。由于每个客户机生成的ID都是顺序的,因此这些键与GUID之间的顺序更高,但是会有数千个唯一的客户机ID,因此我们的聚集索引是否仍然存在碎片化的风险


我们是不是忽略了什么?还有其他值得研究的方法吗?讨论每种方法的优缺点都会很有帮助。

要记住的关键(双关语)是为存储在持久存储上的每个对象都有一个唯一的键。如何处理该对象的存储完全取决于您以及如何访问该密钥的方法。您列出的每种策略都有自己的原因来解释为什么要这样做,但最终它们会在数据库中存储某个对象的键,以便在数据库中保留相同的对象引用的同时更改其所有属性

我仔细考虑了这个问题,最终决定GUID通常是最好的解决方案。以下是一些关于原因的信息:

身份 Identity选项听起来似乎消除了所有的负面影响,但在实现了实现该系统的单页Web应用程序之后,我可以告诉您,它为代码增加了大量的复杂性。一个临时id可以很快地在客户端数据中传播,在寻找每一个可能的用法时,很难创建一个没有漏洞的系统。它通常会产生特定于应用程序和数据的硬编码信息来跟踪客户机上的外键(随着数据库的更改和您忘记更新这些信息,这既繁琐又容易出错)。它还为每次同步增加了大量开销,因为每次同步都可能需要运行多个表来检查临时ID。也许有更好的方法来实现这个系统,但我还没有看到一个好的方法,它不会在数据中增加大量的复杂性和可能的错误状态

混合成的 复合方法在生成会话ID和从中创建ID的过程中也给代码增加了很多复杂性,它们与GUI相比没有任何优势,只能保证它是唯一的-但问题是,GUID在理论上是唯一的,尽管我担心可能会重复,我意识到这是一个无限小的机会,实际上有一个非常简单的方法来处理这种可能性,它不是唯一的

伪装 关于使用GUID,我最担心的是

  • 它们的大小很大,并且不是传统的整数,这将使传输大量数据的速度变慢,并降低数据库性能
  • 如果你真的遇到冲突,它会毁掉你的应用程序,所以你必须编写复杂的代码来处理你可能永远不会使用的情况
  • 然后我意识到,在离线风格的web应用程序中,通常不会同时传输大量数据,因为这些数据都存储在客户端

    你也不知道w