【问题标题】:database design for distributed application分布式应用的数据库设计
【发布时间】:2012-10-11 13:57:14
【问题描述】:

在多个客户端和服务器环境中拥有分布式、非始终连接的数据库的最佳方式是什么?

我正在构建一个多租户 Web 应用程序,该应用程序还有一个独立的 Windows 客户端。系统中的实体包括联系人、任务、活动等。这些实体中有很多是在客户端创建的,而与服务器断开连接。如果客户端在独立模式下运行(这是当前版本),它可能永远不会连接到服务器。

现在我想确保在客户端创建实体时,它不会在服务器端产生冲突。这似乎是使用 GUID 作为主键的完美工作,虽然在实体数量可能很少的客户端不是问题,但我担心这可能会成为服务器端的问题GUID 的随机性会使查找效率非常低。

此外,在什么时候(即哪个表)您不再需要在主键上使用 GUID - 例如说一个任务有一系列注释 (1:N) - 注释没有什么特别之处,它们只是需要可访问 - 是否有一种有效的方法来键入这些实体?

【问题讨论】:

  • 您使用的是哪种多租户架构?用户是否共享表?也就是说,这些表是否存储来自多个用户的行?
  • 嗨 Catcall - 这就是意图。即每张表存储所有客户的数据
  • 也想知道为什么投反对票...

标签: database-design primary-key distributed-computing


【解决方案1】:

当您使用 GUID 时,性能损失不会出现在查找中,只有在将新数据插入索引时才会出现。这还取决于您的 dbms 如何处理 GUID 值。

我还是建议使用 GUID,至少作为转移 ID。

【讨论】:

  • 感谢指针 re:性能命中在哪里。您所说的“传输 ID”是什么意思 - 这是一个独立于客户端和服务器的 ID?如果是这种情况,您是否建议每个表都有一个(索引)传输 ID 列以用于同步?
  • 您可以使用 guid 作为每个表的主键/身份列,并为客户端和服务器数据库使用相同的 id 值。或者,如果您有主从表,请在每个主表中使用一个 guid 列(用作传输键),使用主记录移动您的详细表,并在服务器和客户端数据库上使用不同的 id 值。我会推荐第一个解决方案。第二种解决方案需要您以逻辑单元移动记录,并且不能很好地应对未来的变化。
【解决方案2】:

现在我想确保在客户端创建实体时, 它不会在服务器端产生冲突。这似乎是一个 使用 GUID 作为主键的完美工作

GUID 将保证每一行都是唯一的。但唯一的行通常不是真正的问题。

如果租户是公司,公司的身份证号会出现在每一行。如果同一公司的两个用户可以插入仅 GUID 不同的行,您仍然需要处理潜在的冲突。

例如,假设一家公司有两个用户在状态表中输入数据。

              guid    employer_id  state_code  state_name
              --
user1 enters  guid-1  12345        AL          Alabama
user2 enters  guid-2  12345        AL          Alabama

数据完整性需要更多的约束,只是 GUID 列上的主键约束。 (特别是如果断开连接的客户端正在通过外键引用相关的其他表中输入数据。)

希望 GUID 成为集群键。默认情况下,某些 dbms 会将主键设为集群键。如果您的 dbms 这样做,它可能有办法告诉它不要这样做,也许通过像 your_column_name guid primary key nonclustered 这样的声明。

【讨论】:

  • 谢谢 - 我不认为你提到的场景在我的特定应用程序中会成为问题,但我会密切关注它。关于集群 guids 问题 - 感谢您的提醒 - 我已经搜索了该问题(例如 stackoverflow.com/questions/583001/…),现在我知道了!
  • 一般情况下是这样的;说明我的做法更容易。数据完整性需要对对用户业务很重要的数据进行唯一的约束——上面的“state_code”和“state_name”。 (“guid”和“employer_id”对您的业务很重要,而不是对用户的业务。)
【解决方案3】:

好的。可以肯定的是,当您说客户创建它们时,我假设您并不是真的指“实体”。我猜你的意思是现有表中的行。如果这不是真的,请大喊。

无论如何,这里的问题是唯一命名。对于您的情况,请在所有行前面加上用户 ID。只要用户是唯一的,记录就不会冲突。

您现在剩下的问题是记录是否应该发生冲突。这通常不是可以自动解决的问题,并且可能超出了问题的范围。

【讨论】:

  • 是的,对不起,是的,我的意思是表格的行。这是一个很好的解释 - 所以基本上你是说,在客户端只使用 int,而在服务器端我们只是在所有主键前面加上用户 ID?
  • 如果用户安装了两次windows客户端怎么办?
  • @Marcin - 是的,尽管在两个位置都有用户标识可能更容易,因此它们保持完全相同。这完全取决于你。
  • @alikox - 我只允许每个用户同时存在一个客户端。如果做不到这一点,“clientid”可能是要走的路。它会很快,也可以很短。 GUID 往往很长。一如既往,试试吧!看看哪个最适合特定情况。
  • Alikox 提出了一个很好的观点 - 例如,拥有一个 windows 客户端和一个 ipad 客户端,等等。或者,如果他们使用 2 台不同的计算机,并且关联了同一个帐户。
猜你喜欢
  • 1970-01-01
  • 2019-09-23
  • 2012-11-22
  • 1970-01-01
  • 2011-02-04
  • 1970-01-01
  • 2018-09-10
  • 1970-01-01
  • 2017-05-23
相关资源
最近更新 更多