7

我知道以前有人问过这类问题,但我找不到一个可以比较我想到的选项的问题。所以我把它们贴在这里,如果有重复,请发布链接。

这已经结束了一个相当长的帖子,如果你有时间请阅读它,因为问题在最后

EDIT2:我已经接受了一个答案,因为我认为这将是目前最好的解决方案。但我想我想回答我关于连接数字的查询的另外两个问题。它们可以在这里找到:结合两个整数来创建一个唯一的数字&在 C# 中连接整数。如果我要尝试对数字进行编码(如下所示,如 51122222),我认为这会很有用。虽然对于我的小型应用程序来说,也许只是在 c# 中使用类似 String.Format 之类的东西就足够快了。

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

我目前计划的程序将作为一个相当简单的程序来跟踪信息。第一个版本可能包含两个表:Items 和 ItemHistory。这是可能字段的示例:

物品
ItemID(PK) ?
名称字符串
内容字符串

ItemHistory
ItemHistoryID (PK) ?
物品 ID (FK) ?
EventName String
CreatedOn 日期时间

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

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

以下是我目前关于如何处理 ID 的想法:

  1. 对 ID 使用 UUID,这样就不会发生合并冲突
  2. 使用自动增量字段并以某种增量设置每个版本的应用程序的起始编号,例如,第一个应用程序为 1,第二个应用程序为 10000,第三个应用程序为 20000,等等
  3. 使用带有偏移值的自动增量字段来避免数字之间没有大间隙的冲突(mysql为此具有auto_increment_increment和auto_increment_offset)
  4. 生成我自己的 ID,为每个数据库编码一个 ID,这样它们就可以有自己的自动增量值而不会引起冲突。我发现其他人也有同样的想法:ID 列推荐使用哪种数据类型?

虽然选项 1 会起作用并且我过去曾使用过它,但我想看看其他选项的可能性以避免 UUID 的问题。我想要一个在调试时更易于阅读且可排序的解决方案。

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

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

我想知道是否可以为 DB ID 和自动增量使用一个数字。例如,PC = 1 和 PHONE = 2。然后我们有 11、12、13 等用于 PC,第 11 条记录可能有 111,而 PHONE 上的第 304 条记录可能有 2304。但我不知道这将如何完成,或者是否可以轻松完成并且不会导致产生价值的额外开销。

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

所以最后一个问题,有没有办法为分布式应用程序创建一个主键系统,允许排序并且不强制限制(除了数据类型本身的大小,例如最大整数)?

编辑:这是我计划编写的应用程序的更多信息。我想创建一些东西,让我可以存储我可能获得的任何类型的信息,系统将包括标记条目的能力,以便我可以搜索一个主题。到目前为止,我看到的信息类型可能是关于书籍、dvd、网站等的推荐。或者可能是我居住地的本地提示。一个总体思路是停止让这些信息以不同的格式分布在多台计算机/笔记本电脑/手机上。

4

1 回答 1

3

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

  1. 您使用顺序值。这些可以分成组,交错的,等等。它们是最有效的方法,但需要协作和协调。

  2. 您使用随机值(这包括 UID)。这些要简单得多,但需要更多空间。从“生日冲突”我们知道,如果您需要存储 N 个值,那么必须从(超过)一个 N*N 范围内选择一个随机键 - http://en.wikipedia.org/wiki/Birthday_problem。向后工作,如果用作随机密钥,一个 64 位整数可以保存大约 32 位数据 - 大约是 40 亿个值。但那是 50% 的碰撞概率。你想要一个低得多的概率,所以一个实际的限制是大约 1000 万个条目。

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

如果您有一个 32 位密钥,那么随机方法适用于大约一千个值(如上所述,顺序方法约为 40 亿)。

显然,如果你有一个文本值,那么你需要相应地修改它,但是 UUID 被设计为具有“足够”的值http://en.wikipedia.org/wiki/Universally_unique_identifier

通常,数据库会提供一个顺序 ID,这就是您所需要的。如果没有,64 位随机方法通常是最简单的,值得额外的空间。

于 2011-08-31T16:49:35.190 回答