这是一个糟糕的数据库实践吗?

时间:2015-07-01 16:13:29

标签: database-design relational-database

所以我不是一个真正的贸易数据库开发人员,它只是我工作职能的一部分。但我注意到我最近一直偏爱某个特定的数据库设计方案而且我对这种直觉感到不满。假设如下:

我有Customer

Id  |  Name  |  etc...
----------------------
1   |  "Bob" |  etc...

最近,企业要求我们实施这些看似短命且与客户无关的任何其他数据;事情就像"IsPartOfGroupX""FriendCount"。为了适应这一点,我已经实现了如下表格(即Customer_Attributes):

Id  |  CustomerId  |  Name              |  Value  |  IsActive
-------------------------------------------------------------
1   |  1           |  "IsPartOfGroupX"  |  "True" |  1
2   |  1           |  "FriendCount"     |  "42"   |  0

我的两个问题是:

这是一个已知/实践的关系数据库设计模式吗?

它似乎是,因为它非常有用。此类策略的前一种策略是在Customer表中添加其他列,并在我们不使用时将其留在那里。

这是一种好的还是坏的做法?

我觉得真正的DBA会在这个领域有所作为。虽然它对我有用并且看起来很新颖,但感觉有点不对劲。基本上我只是翻转一个桌子并将所有列变成行。但我不知道!这就是我问你的原因。

提前感谢您提供的任何见解。

5 个答案:

答案 0 :(得分:1)

正如其他人所指出的那样,你的做法是一个EAV案例。 EAV通常(但并非总是)是一个错误。这可能是例外之一。

这里需要注意什么。这些"一次性属性"出于所有意图和目的,您的DBMS不受管理,因为它们没有被定义为列。这意味着组合使用此数据的查询与使用不在数据库中的数据执行相同操作一样困难。

如果您或您的管理层希望将这些数据转化为有用的信息变得容易,它应该在数据库中的方式,这就是它将要回归的地方咬你。

但是,如果您很少以标准方式使用一次性数据,那么您可能只是侥幸成功。

答案 1 :(得分:0)

添加另一个表是可以的,我认为调用它属性是可以的,但是你应该做3列,所以客户我只需要出现一次。像这样: 第X组的身份证成员。朋友数量。我假设第2列是布尔值,3是整数。你拥有它的方式是复杂查询问题的一个方法。

答案 2 :(得分:0)

您不是turning columns into tables,而是在normalized数据库方案中管理客户的属性。阅读更多关于这个主题的内容,因为这是“Codd and Date's book”关于数据库设计的精髓。

在你的例子中,我会为每个属性创建三列来存储'boolean',数值和文本值,以便利用数据库的功能将值限制为期望值。

Id |  CustomerId |  Name             |  BValue | Nvalue | Tvalue | IsActive
------------------------------------------------------------------------
1  |  1          |  "IsPartOfGroupX" |  True   |   null | null   |   1
2  |  1          |  "FriendCount"    |  null   |    42  | null   |   0
3  |  1          |  "Comment"        |  null   |  null  | "new"  |   1

所以你正朝着正确的方向前进。

但是,如果数据必须“始终填充”或始终与其他表结合使用,则最好将其移至客户数据库的列。

答案 3 :(得分:0)

关于你的问题。

1)是的,但不是恕我直言,除了关于变化量的小型项目或数据库 你会在futuro中做的没有关于表格中的数据和列的数量,这提到了很多原因 在你帖子中第一篇文章的链接中。

根据我个人的经验,我可以说,因为我相信这样一张桌子,你会很难拥有 欺骗1,2,3并且许多可能性需要切换到表格或调整您的值 适合所有情况的套装,这几乎是不可能的,或者至多是非常乏味的。

那么放置限制会忘记它不能完成。这会破坏你的BD的稳健性。

我记得为了调用表EAV值,我不得不创建一个代表主键代码的常量丢失, 类似硬核的东西。您需要一次,两次或更多次使用此通用表读取查询的图像 扣除f ***正在执行该查询的内容,直到您检查通用EAV'中的值为止。表

我可以肯定地说你的第二个问题取决于但是一般情况下是否已经提出,在你的情况下,你只需要再添加两列, 不需要将其用作坏模式。

我总是试着记住表作为一个实体,它的列是属性,这是最合乎逻辑的方式 关于做OOP,有时候更加繁琐的重新插入表,即使你有插入 这不包括表格的具体字段更糟糕,但最终,将永远是一个更清洁的做事方式 我重复恕我直言。

请勿忘记帖子第一条评论中的检查链接

答案 4 :(得分:0)

这是一个坏主意,正如已经提到的那样。但问题的根源在于认为必须对数据库中的所有信息进行建模。建模数据,而不是信息。信息来自数据。

IsPartOfGroupX为例。问的是"这个客户是该组的成员吗?"这是一个非常有效的问题。我不明白你为什么把它标记为“看似短暂而且无关紧要的任何东西而不是客户”#34;一块数据。您有客户,并且您的数据库中有组。 (如果您在您的数据库中拥有群组,那么问题就变得荒谬而不是您所描述的任何内容。)

所以我假设你有团体。在这种情况下,这是一个可以通过视图或UDF或两者的组合来回答的问题。相同的朋友数量问题。

数据库的目的是直接或间接提供有关数据的答案。视图和/或UDF将是直接答案;允许应用程序执行分析将是一个间接的答案。

您不会(实际上无法)为数据库提出的每个问题建模。您可以通过视图,存储过程和函数提供简单的方法来获得答案。