【问题标题】:Data modeling question数据建模问题
【发布时间】:2010-10-07 08:14:27
【问题描述】:

我的客户在注册我的应用程序时使用以下其中一种:

  1. Foo API(需要“auth_key”、“password”、“email”)
  2. Acme API(需要“secure_code”、“用户名”、“密码”)
  3. Bar API(需要“xyz_code”、“pass_key”)

(假名,为简单起见,省略了大约 15 个)

我不希望我的数据库中只有 10 到 15 个表只是为了我提供的不同 API 集成选项(特别是当它们都用于同一事物并且他们只是从整个列表中选择 1 时)。

我的解决方案是这样的:

创建一个api_configuration 表,其中包含一个名为api_name 的列,其中包含特定API 的代码(例如"foo_api"

创建一个名为credentials_attribute 的表,其外键返回api_configuration、一个名为name 的列和一个名为value 的列。

然后我构建了一个用于选择 API 的 UI。如果他们选择 Acme API,它会要求提供“安全代码”、“用户名”和“密码”,并在 credentials_attribute 中为每个名称/值对创建一行。

在我的 api_configuration 的 ORM 模型上,我可以创建一种基于当前 api_name 查找 credentials_attribute 值的方法。

如果您必须为这个问题建模一个解决方案,这个解决方案是否感觉正确,或者有其他方法可以做到吗?请同时解释您的理由(即,性能更好等)

【问题讨论】:

  • 听起来不错,但你不能创建一个表吗?用户名/电子邮件是一回事(好吧,你可以这样表示)?
  • @RPM1984 - 我可以。我只是想对其他方式(例如您提到的方式)发表一些意见。我部分倾向于非平面版本,以便稍后我可以灵活地让客户使用多个 API,但我忽略了这一点,因为我不想基于不是的东西来偏见人们的答案暂时有问题。
  • 下面的 stackoverflow 讨论讨论了不同 ORM 方法的优缺点。即使您没有专门询问 ORM,许多 cmets 仍然适用,因为它们比较了单表方法与多表方法。 stackoverflow.com/questions/3413459/…

标签: database design-patterns database-design data-modeling


【解决方案1】:

如果我正确理解了这个案例,它看起来就像是 gen-spec 设计模式的又一个案例。查找“泛化专业化关系建模”。

对象建模教程通常涵盖 gen-spec,但关系建模教程通常不包含。不过很好理解,网上也有一些优秀的文章。

【讨论】:

    【解决方案2】:

    我可能更喜欢使用单个表来执行此操作

    有一个UserAuthentication 表,其中包含IdentificationKey, AuthenticationCriteria1, AuthenticationCriteria2 等列...

    AuthenticationCriteriaX 列数 = 任何 API 将拥有的最大条件数。我假设它会是合理的,最多可能是 5,但任何高达 15-20 的东西实际上仍然是一张很小的桌子。

    UserAuthentication 表还有一个 api_key 列,它是来自 MASTER_API 表的外键,该表是所有受支持 API 的列表

    至于问题的 UI 部分,即为UserAuthentication 表中的任何字段向用户显示什么标签,我认为这只是一个 UI 问题,因此您应该只拥有每个 api 特定的映射在你的 UI 层的某个地方。 api_key 列可根据需要用于翻译。 DB 不一定需要知道这些细节,IMO。

    【讨论】:

    • 您为什么推荐这种扁平化设计而不是另一种?我试图了解 DBA 和软件架构师在决定这些事情时使用的不同理由。
    • 我同意@InSane - 我宁愿有一张桌子。拥有 15 个具有相同最终结果的表是愚蠢的。是不是更灵活?是的。但有时您需要权衡灵活性与过度设计。您始终可以将所有 API 的“主要内容”(这三个字段)存储在一个表中,然后为“元数据类型”表创建一个 FK,该表可以包含额外的内容。
    • @orokusaki - 我更喜欢单个表的理由是因为逻辑上 - 至少对我来说 - 你拥有的是用于做同样事情的数据。 - 因此,为其设置单独的表格,甚至拥有一个水平表格,只是不必要地使其复杂化。这种设计允许我只为用户获取一条记录,并一次性将所有这些身份验证标准提供给我。即使从增长的角度来看,如果您将 IdentificationKey + api_key 作为组合键,您甚至可以轻松解决未来为同一用户支持多个 api 的问题。
    • @orokusaki - 总而言之,这种方式的实现更简单。与他的方法相比,拥有多个表/水平表似乎没有提供任何额外的好处,所以它似乎不值得额外的努力
    【解决方案3】:

    如果我理解正确的话,不同 API 中的所有这些属性在概念上都是同一 3 个事物的元组,但名称不同,对吧?

    您的描述是从数据库的角度来看的 - 我将描述我将在域方面做什么(可能直接映射到您的架构)。

    我会创建一个类,例如UserLogin,具有上述 3 个属性(例如 authenticationCodeuserIdpassword),以及 API 名称/代码到 GUI 属性名称的映射。当用户选择首选 API 时,我可以在 GUI 上显示具有适当名称的字段,并将值填充到 UserLogin 的相应属性中。如果需要,UserLogin 还可以存储该用户的首选登录 API。这种方式 UserLogin 映射到数据库端的单个表。我可能会使用另一个表来配置每个已知 API 的属性名称。

    【讨论】:

    • éter - 第一个问题不,我编辑了我的问题,以便更明确地了解每个 API 身份验证参数的不同性质。有些有 2 个、3 个,甚至有 4 个。
    • @orokusaki,API 属性(例如用户 ID 和密码)是否存在最低公分母?额外的字段可以很容易地分组/映射到一些常见的属性吗?如果是这样,我仍然会尝试使用包含一些必填字段和一些可选字段的单个类。否则,这种方法可能会变得笨拙且不可行。
    • éter - 我只是好奇推荐这个的原因是什么。我能想到几个原因,但我想听听你的。
    • @orokusaki,只要有可能,我更喜欢使用真实类的对象而不是名称-值对的集合。我是一个懒惰的 OO 程序员,仅此而已:-)
    猜你喜欢
    • 2019-06-29
    • 2017-10-13
    • 1970-01-01
    • 2021-02-02
    • 2011-11-22
    • 2011-03-28
    • 2010-11-17
    • 1970-01-01
    • 2012-07-30
    相关资源
    最近更新 更多