2

我正在寻找一种策略,以阻止重复分支表的问题。例如,作为一个虚构的用例,假设我有一个包含用户名、登录名、密码和其他元数据的用户表。在这个特定的场景中,假设用户被限制为每个特定的 IP 子集登录。因此,我们有一个 1:M 的关系。每次出现诸如以下的用例时,您的正常工作流程包括拥有一个“用户”表和一个诸如“user_ips”之类的表,在这种情况下,您将拥有诸如 pk(ip_id)、fk( user_id) 和 user_ips 端的 IP。

对于类似的情况,你们通常会按照上面的方式扇出吗?这里有机会有效地去规范化吗?也许以某种 CSV 分隔的方式将 IP 存储在 BLOB 列中?你们今天正在部署哪些策略?

4

7 回答 7

13

非规范化的机会?我认为您可能误解了传统智慧 - 非规范化是一种优化技术。不是你出去寻找的东西。

于 2008-10-17T23:00:30.690 回答
5

我怀疑,当潜在相关项目的数量很大时,任何规范化的解决方案都会在正确索引的情况下执行非规范化的解决方案。我的策略是规范化数据库,然后提供视图或基于表的函数,利用索引连接来使成本可以承受。我会让性能要求决定向非规范化形式的转变。

请记住这一点。如果您需要对部分信息实施基于角色的安全访问,则基于表的安全性比基于列的安全性更容易实现,尤其是在数据库或数据层级别。

于 2008-10-17T22:37:15.197 回答
4

我强烈建议不要在一个字段中放置多个 IP 地址。没关系 3NF 这打破了 1NF。

Tvanfsson是对的,如果您索引 FKEY,您将获得相当可观的性能,除非“users_ips”表中有数百万条记录。

更好的是,通过保持这些表的规范化,您实际上可以在将来报告这些信息,这样当用户对为什么他们无法从某些 LAN 登录感到困惑时,编写应用程序(或 SQL)来排除故障并执行用户操作IP查找会容易得多

于 2008-10-17T22:52:32.983 回答
1

一种选择是将您的 IP 地址存储为 xml 字符串。我认为这会比逗号分隔的列表更好,并且允许您在需要时灵活地将其他元素添加到字符串中(想到端口)而无需更改数据库。

虽然,我认为在大多数情况下标准化的时尚更好。

于 2008-10-17T22:23:48.470 回答
1

与任何非规范化问题一样,您需要考虑与之相关的成本。特别是,如果您在主表中列出 IP 地址,您将如何回答“哪些用户可以与 IP 地址 wxyz 关联?”的问题。使用完全规范化的形式,这很容易并且与“哪些 IP 地址可以与用户 pqr 相关联?”对称。对于非规范化形式,问题的答案非常不同。此外,通常在非规范化版本中,确保应用正确的完整性规则要困难得多。

于 2008-10-17T22:59:53.593 回答
0

恕我直言,这完全是关于成本/收益分析。一切都取决于您正在使用的平台的要求(包括可能的要求)和功能。

例如,如果您有“显示系统中记录的所有唯一 IP 地址”之类的要求,那么您最好现在“分支”并创建一个单独的表来存储 IP 地址。或者,如果您需要对 IP 地址进行某些限制(例如“给定用户的所有 IP 地址必须是唯一的),那么您可能会从单独的表和对其应用适当的限制中受益匪浅。(请注意,您甚至可以同时满足这两个要求如果您使用了非规范化设计和适当的与 XML 相关的机制;但是,针对这些要求的基于 RelDB 的解决方案似乎实现和维护起来要便宜得多。)

显然,这些并不是要求规范化解决方案的唯一示例。

同时,我认为“显示用户的所有 IP 地址”或“显示与给定 IP 地址关联的所有用户”之类的要求可能不足以证明标准化解决方案的合理性。

您可以尝试进行更深入的分析(寻找第一类需求),或者仅仅依靠您对项目上下文(当前和未来)的理解以及您的“直觉”。

在这种特殊情况下,我自己的“胆量”是第一种类型的要求(亲规范化要求)极有可能,因此从一开始就使用规范化解决方案会更好。但是,您已经说过这个用例是虚构的,因此在您的实际情况下,结论可能完全相反。

永远不要说“从不”:3NF 并不总是最好的答案。

于 2008-11-19T00:22:06.610 回答
0

您可能需要考虑一个用户属性表和属性类型表,您可以在其中定义用户可以拥有的属性类型。每个新的用例都将成为一种属性类型,并且数据将简单地添加到用户属性表中。

使用您的 IP 地址示例,您将拥有 IP 属性类型并将相应的 IP 存储在用户属性表中。这使您可以灵活地添加其他类型,例如 MAC 地址,并且不需要您创建新表来支持新的数据类型。对于每个新用例,您不必添加任何数据。

不利的一面是,鉴于此属性结构,您的查询会稍微复杂一些。

于 2008-10-17T23:16:42.123 回答