database - 分布式主键-UUID,简单的自动增量还是自定义的顺序值?

标签 database distributed database-agnostic

我知道以前曾问过这种类型的问题,但是我找不到一个可以比较我所想到的选择的问题。因此,我将在此处发布它们,如果有重复,请发布链接。

这篇文章发表了很长的篇幅,如果您有时间请仔细阅读,因为问题已经结束了

编辑2:我接受了一个答案,因为我认为这将是目前最好的解决方案。但是我想我想提出另外两个问题,回答有关串联数字的查询。可以在这里找到它们:Combine two integers to create a unique numberConcatenate integers in C#。如果我要尝试编码数字(如下所示,例如51122222),我认为这将很有用。尽管也许仅使用C#中的String.Format之类的东西对于我的小型应用程序就足够快了。

我目前正在尝试找到一种方法来设置使用相同数据库架构的分布式应用程序,并且可以与所有其他同步的主数据库进行同步。

我目前正在计划的程序将从一个非常简单的程序开始,以跟踪信息。第一个版本可能包含两个表:Items和ItemHistory。这是可能的字段的示例:

项目
ItemID(PK)?
名称字符串
内容字符串

项目历史
ItemHistoryID(PK)?
ItemID(FK)?
EventName字符串
CreatedOn DateTime

我已经列出了字段名称和类型,这个问题是关于将什么用于PK类型,因此它们丢失了。

第一个版本将是一个标准的桌面应用程序,我目前正在计划将W#前端和SQLite用于数据库使用C#。最终,我也想创建一个同样可以在我的Android手机上运行的版本。这是分布式部分进入的地方。我并不总是有信号,因此需要该应用程序离线运行并允许再次在线时进行同步。

到目前为止,这是我对如何处理ID的想法:

  • 使用UUID作为ID,因此不存在合并冲突
  • 使用一个自动增量字段,并以某种增量设置每个版本的应用程序的起始编号,例如第一个应用程式为1,第二个应用程式为10000,第三个应用程式为20000,依此类推
  • 使用带有偏移值的自动增量字段来避免冲突,而数字之间不会有大的间隔(为此,mysql具有auto_increment_increment和auto_increment_offset)
  • 生成我自己的ID,该ID对每个数据库的ID进行编码,以便它们可以具有自己的自动增量值,而不会引起冲突。我发现其他人也有相同的想法:What data type is recommended for ID columns?

  • 尽管选项1可以工作,并且我过去曾经使用过它,但我想看看其他选择是否可以避免UUID问题。我希望有一个在调试时更易于阅读且可排序的解决方案。

    选项2可以使用,但确实会限制记录数量。我知道在我的小型应用程序中,它几乎永远不会超过那么多,但是我想尝试看看是否有不需要这种限制的解决方案。选项3通过使用交替数字来避免限制,但是我认为您需要知道要使用多少个数据库,否则您可能会填写所有数字。在DB1上使用1的开头和1的增量,在DB2上使用2的开头和2的增量将交替使用每个数字。您可以使用50作为增量,但是您还有另一个限制,但是现在限制了可以使用它的应用程序的数量。我再次知道它的限制在我的情况下不会受到影响,但在突然变得非常流行的应用程序中可能会成为一个问题。

    选项4似乎可以为我解决问题,但是我不确定它是否可以在实践中起作用。我的一个想法是允许在每个应用程序上设置一个前缀,然后可以将其与自动递增值一起使用。例如PC1,PC2用于记录PC上的记录,也许PHONE1,PHONE2等用于记录来自Android的记录。这会起作用,但是在字符串中使用数字会导致排序问题,其中1,11,100并排显示,即使用较少的前导零,然后再次将其返回到有限数量的记录。

    我想知道是否有可能使用一个数字作为数据库ID和自动递增。例如PC = 1和PHONE = 2,那么PC就有11、12、13等,在PHONE上,第11个记录可能为111,第304个记录为2304。但是我不知道这将如何完成或是否可以轻松完成,并且不会产生过多的开销来生成值。

    在工作中,他们使用了类似的编号系统,他们使用的是类似51122222的名称。5将引用应用程序的实例,然后是2位数字的年份,最后是一个自动递增的编号。我还没有一个明确的答案,如果我们一年超过99999条记录,将会发生什么。我认为他们可能已经意识到这种情况不会发生,并且很高兴他们已经计算出了风险。

    因此,最后一个问题是,是否有一种方法可以为分布式应用程序创建主键系统,该系统允许排序并且不执行限制(数据类型本身的大小(例如,最大整数)除外)?

    编辑:这是我计划编写的应用程序的更多信息。我想创建一些东西,使我可以存储几乎任何类型的信息,该系统将包含标记条目的功能,以便我可以搜索主题。到目前为止,我看到的信息类型可能是关于书籍,DVD,网站等的推荐。或者也许是我所居住的地方的本地提示。总体思路是停止使这些信息以不同的格式散布在多台计算机/笔记本电脑/电话中。

    最佳答案

    从广义上讲,有两种方法。

  • 您使用顺序值。这些可以分为几类,交错的,随便什么。它们是最有效的方法,但需要协作和协调。
  • 您使用随机值(包括UID)。这些要简单得多,但需要更多空间。从“生日碰撞”中我们知道,如果您需要存储N个值,则必须从(大于)N * N-http://en.wikipedia.org/wiki/Birthday_problem范围中选择一个随机键。向后工作,如果用作随 secret 钥,则64位整数可以保存大约32位数据-大约40亿个值。但这有50%的碰撞可能性。您希望概率要低得多,因此实际限制是大约1000万个条目。

  • 因此,简单来说,如果您拥有64位 key ,则随机方法将适用于大约一千万个条目,而顺序方法则适用于更多方法。无论哪种情况,这都可能超出您的需要。

    如果您拥有32位 key ,则随机方法可处理大约一千个值(如上所述,顺序方法将达到约40亿个值)。

    显然,如果您有一个文本值,则需要进行相应的修改,但无论如何,UUID被设计为具有“足够的”值http://en.wikipedia.org/wiki/Universally_unique_identifier

    通常,数据库将提供一个顺序ID,而这正是您所需要的。如果不是这样,则64位随机方法通常是最简单的,值得额外的空间。

    关于database - 分布式主键-UUID,简单的自动增量还是自定义的顺序值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7258619/

    相关文章:

    android - 每次运行后如何清除数据库中的数据?

    c# - 如何从数据库中检索数据 C# Windows 窗体应用程序?

    distributed - 如何创建分布式文件系统

    database - cakephp 错误。连接到数据库...不是... : Access denied for user 'my_app' @'localhost' (using password: YES)

    php - 从 SQL 数据库中排序类别列表中的一组子类别

    redis - 如何创建分布式 'debounce' 任务来排空 Redis 列表?

    c# - 处理在线和离线

    indexing - 使用 Liquibase 创建具有降序键列的索引

    sql - 将数据库字符串枚举转换为整数值得吗?

    数据库独立性