1

如果我有一个单独的成员资格提供程序 API,它不会在我的数据库中存储凭据和角色,我应该如何通过我的应用程序对用户的引用来维护引用完整性?

例如,我们与会员 API 交互,但向其传递了一个成员名称并基本上请求访问配置文件或角色,但我无权访问底层数据库。

然后,我们可以使用返回的角色或配置文件来控制应用程序内的访问。这种方法的问题在于,当我们保留有关该用户操作的信息(例如记录他们的更改或工作流中的任务分配)时,我们从我们的提供程序存储用户 ID,但由于信息不在我们的应用程序数据库中,我们不能对它进行 FK 以获得数据库完整性。

而且,真的,这是有道理的,因为会员提供者与我们没有合同来确保他们的更改不会违反我们应用程序数据库中的 FK。

但似乎我应该能够按用户在我自己的应用程序数据库中聚合信息,或者有一些东西可以强制对我的持久用户 ID 进行引用。

我正在考虑一个单独的“瘦”用户表,其中包含一些定性信息,例如来自我们提供商的名称和 ID……这个表可能会在第一次登录时填充。

好处是我现在可以仅在我的应用程序中针对某些用户信息汇总用户信息,并且可以在我的应用程序数据库中强制执行引用。缺点是我正在复制用户数据,这可能是陈旧的。

4

2 回答 2

3

这个问题实际上是关于两个不同的事情。

  1. 远程数据库的外键也应该是本地表的外键。
  2. 你能保持对外部数据库的引用完整性吗

这是完全不同的两件事,尽管对两者的快速回答实际上是相同的:

不。

但是让我稍微深入一点。

1. 使用外键到远程数据库

为了减少对远程数据库的依赖,您应该只将这些外键存储在数据库中的一个位置。

示例:假设您有一个用户可以发表评论的博客。这些用户将通过 Facebook 登录。您现在拥有一个远程数据库 (Facebook) 和一个存储用户评论的本地数据库。您现在可以遵循以下两种设计之一:

  • comments存储facebook_id为外键的表

或者

  • 一个单独的users表存储facebook_id一个本地id和一个comments使用本地 id 作为外键的表。

您不应该两者中都使用 facebook_id。虽然这实际上可行,但您在不需要的情况下引入了对远程数据库的依赖。您将无法添加来自非 Facebook 用户的评论,因为这会破坏您的设计。

2.与远程数据库的参照完整性

您可能不打算问这个问题,但该术语referential integrity暗示远程数据库的所有外键实际上是指现有的远程记录(即用户)。保持这种完整性的唯一方法是,如果远程数据库会通知您远程记录的更改或删除,通常情况并非如此。

示例:让我们回到上面提到的假设博客。一些 Facebook 用户发表了评论。后来,同一个人决定删除他们的 Facebook 帐户。Facebook 数据库可能不会通知您发生这种情况,从而在您的数据库中留下“死”记录,这些记录不再链接到远程数据库中的有效记录。这破坏了参照完整性。因此,除非您有一个真正维护完整性的好方法,例如接收删除通知等,否则您应该设计您的应用程序,以便在 Facebook 用户被删除时它不会中断。

于 2013-10-18T22:59:33.563 回答
1

建立对外部数据库的引用完整性不是一个好主意。如果您需要更快的查找,您应该保留自己的 ID,然后使用外部 ID,然后使用索引而不是外键约束。

原因是即使你设法以某种方式建立这种关系,它也会成为一种耦合,使你容易受到其他系统变化的影响。

恕我直言:您应该在业务层集成中维护您所请求的内容,而不是在数据库级别。

实现一个更改通知系统,理想情况下在身份验证系统中使用双向服务,您的系统可以订阅该服务将在身份验证系统的 BI 更改时被调用。但如果没有,如果您有业务层,请再次使用另一种方法,就是让提供者进行更改,但这很困难,因为总会有延迟,否则性能影响会很大。

我相信您最好的方法是使用身份验证系统更改日期戳在系统中返回的角色等方面复制答案,然后使用角色提供者 api 系统的更改日期来了解您是否可以使用自己的或必须再说一遍,该系统很容易实现,但应该发生在 DB 之外的另一层。

在 DB 中应该只是一个 ExternalID 列,例如,它可能与 VerificationDate 耦合,在成功使用时都会更新(或者如果没有则清除)只是为了保持简单,但不要使用跨数据库关系完整性,就像使用完全前缀的实例一样因为它是你的表现的杀手和无法控制的弱点(你的 BI 无法控制为什么其他 BI 想要更新)

于 2013-10-25T11:17:28.450 回答