为单点登录设计用户表以跨子域使用

时间:2016-05-26 08:35:28

标签: sql-server database-design architecture database-schema

我们的网站包含以下子域名:

  1. example.com - 主站点
  2. food.example.com
  3. fashion.example.com
  4. 每个域和子域都有不同的数据库,如下所示:

    1. exampleDB - 带有用户表的主数据库
    2. foodDB
    3. fashionDB
    4. 您尝试了什么?

      1. 目前,对于单点登录,我们已计划在主网站中重定向用户以进行注册。

      2. 虽然子域中的订单处理从主DB获取UserID并存储在相应的子域的Orders表中。

      3. 出于报告目的,我们将UserID FK constraint存储在Orders表中,因为我们有单独的数据库。

      4. 我可以看到here堆栈交换站点有单独的数据库,但它是否也有单独的users表?

        StackExchange Network配置文件是否存储在单独的数据库中?

        我可以从here看到每个网站的用户表都有StackExchange网络配置文件的AccountId。

        示例:

        1. Here是Nick Craver网络资料,ID为:7598

        2. 他在历史记录网站中的个人资料的帐户ID与相同的ID相关联:7598检查this查询。

        3. 我无法在data dumbs中的任何位置看到Accounts表格,因此存储了AccountId?如何使用AccountId在多个网站中完成SSO?

          我的问题:我们是否需要在主数据库中使用单个用户表,或者我们必须为子域的数据库和Link Main DB UserID创建单独的用户表,而不是FK约束?哪个是购物网站的最佳设计?

          任何帮助都会很棒。

4 个答案:

答案 0 :(得分:4)

您提到的UserID仅在单个DB中的特定Users表中相同。它实际上不是您域中任何用户的标识符。要识别跨多个数据库的用户,您需要为每个用户提供域级别ID。一种简单的方法是将另一个名为UID的属性(列)或类似的东西添加到User Class(表),Global Unique Id(GUID,请参阅https://msdn.microsoft.com/en-us/library/system.guid(v=vs.110).aspx)并将其用作域级ID来标识用户而不是UserId。这样,您就可以在域中的多个数据库中自由存储用户信息。所以:

  • 您只能在每个子域的数据库中保留域级别ID,并使用该ID从主域DB中查询完整的用户配置文件。优点:成本更低。权衡:在分布式系统中,从子域查询用户信息需要更长的时间,因为信息驻留在主DB中。
  • 您可以在所有数据库中保存完整的用户信息,包括main和subs'。亲:更快的查询。缺点:需要更多内存,当用户信息发生变化时,您必须在所有数据库中进行同步。

答案 1 :(得分:1)

1]您需要在所有三个数据库中都有单独的用户表,因为没有外键的参照完整性。如果有任何数据库出现故障,那么其他域将启动并运行。交易是,数据库管理需要更多维护但性能不会受到影响。

或者,您可以制作以下数据库计划。

1]为所有三个域(一个主域和两个子域)保留一个数据库

2]为food_order,fashion_order

创建一个具有两个状态标志的用户表

3]创建食品和时尚单独的订单表

4]用户订购的可能性有三种:i)食品或ii)时尚或iii)食品/时尚。

5]按照订购食品或时装或食品/时尚两种方式保持更新状态标志。

这里的权衡是,如果您的数据库出现故障,那么您的所有三个网站都会关闭。所以保持非常好的数据库灾难恢复模型。

答案 2 :(得分:1)

一些选项:

  1. 仅将用户存储在主数据库中。然后......

    • 使用加密的Cookie存储您关注的所有用户信息。所有其他子域都可以读取此cookie。
    • OR仅将user_id存储在cookie中,并通过API使用反向通道通信从主站点获取用户信息。
    • 或者使用许多现有的相当标准的用户信息共享协议之一将用户信息提取到其他站点,然后您可以将其存储在当前会话存储中。一些示例包括CAS和OAuth。
  2. 将您的用户信息存储在所有数据库中。您通常会使用其中一个来获取其他数据库的信息。

    • 定期安排的同步工作
    • 用户登录时的反向通道
    • 一个相当标准的用户信息共享协议(如上所述)
  3. 使用选项1,您的主数据库关闭会影响所有其他网站。对于选项2,非主DB是几乎缓存的副本,您需要处理缓存失效。

    您选择哪个选项主要取决于您的具体业务需求。

答案 3 :(得分:0)

我认为你在问题中的开始是最好的选择。

最好的办法是拥有一个用户表和三个配置表。 one users表将链接到SSO功能,该功能将验证用户,他们的整体配置文件和凭据信息。每个服务/网站与使用联合SSO验证用户cookie的域无关。即除非你使用谷歌网络联盟进行SSO,否则假装一切都是一样的。存储在谷歌中的数据你真的不在乎(除了你可能有的字段,可能是用户名等等)无论你在哪个域,你要做的第一件事就是拨打电话到SSO,看看用户是否已经登录,如果他们没有将他们引导到那里,当他们完成后,他们将重定向到你的子域。

如果他们已登录,则没有重定向,但您获得了jwt令牌,这将允许将保存的userIds(或UID)转换为实际信息。

比如说,登录的用户从fashion.example.com购买了一些东西。您可以在订单表中添加一行,该行恰好有一个名为" userId"的列。如果该站点想要在首页上发布"用户X命令Y",在从表中获取订单后,您将调用SSO服务以使用SSO令牌返回带有用户信息的jwt。如果由于某种原因您希望存储子域不同的配置,那么该子域将创建自己的"用户"或"配置"表,密钥将链接到SSO服务中的UID。是否有一个独特的PK取决于您(使用FX到UID)或者PK是否是UID。

这让您完全将域名彼此分开。让我们的子域名决定他们是否需要"用户"是否表。

TL; DR。您确实有4个域,而不是3个域,将其视为1个SSO身份验证域和3个站点。 SSO将具有auth表,并且如果需要,每个站点域可以具有或不具有其自己的用户表。该用户表将具有到SSO表的FK,而无需强制执行FX约束。 (FK约束,如果以某种方式可以强制执行实际上是不好的,因为你不想要SSO服务,在用户的帐户应该被删除时必须知道子域,这些都是不同的数据库已经很棒了。)

相关问题