我有两张桌子:
Avatars:
Id | UserId | Name | Size
-----------------------------------------------
1 | 2 | 124.png | Large
2 | 2 | 124_thumb.png | Thumb
Profiles:
Id | UserId | Location | Website
-----------------------------------------------
1 | 2 | Dallas, Tx | www.example.com
这些表可以合并为:
User Meta:
Id | UserId | MetaKey | MetaValue
-----------------------------------------------
1 | 2 | location | Dallas, Tx
2 | 2 | website | www.example.com
3 | 2 | avatar_lrg | 124.png
4 | 2 | avatar_thmb | 124_thumb.png
这对我来说可能是一个更清洁,更灵活的设置(至少乍一看)。例如,如果我需要允许“用户状态消息”,我可以不触及数据库。
但是,用户的头像将远远超过其个人资料信息。
所以我想我真正的问题是:
这会产生什么样的表现??
合并这些表只是一个非常糟糕的主意吗?
答案 0 :(得分:2)
这几乎总是一个坏主意。你在做什么是Entity Attribute Value模型的一种形式。当系统需要灵活的属性系统以允许在生产中添加属性(和值)时,有时需要此模型。
这种类型的模型基本上建立在元数据上,而不是真正的关系数据。这可能导致参照完整性问题,孤立数据和性能不佳(取决于相关数据量)。
一般情况下,如果您的属性是预先知道的,您希望将它们定义为真实数据(即具有实际类型的实际列),而不是基于字符串的元数据。
答案 1 :(得分:1)
我坚持使用原始布局。以下是用一个大键表对替换现有表结构的缺点:
低效存储 - 由于存储在元数据列中的数据是混合的,因此必须使用最坏情况数据类型声明该列,即使您需要保留的所有数据都是某些键的布尔值。登记/>
搜索效率低下 - 如果您需要在将来从值中进行查找,数据的混乱将使索引成为一场噩梦。
读取效率低 - 现在读取单个用户记录意味着对多行进行索引扫描,而不是拉一行。
写作效率低 - 写出单个用户记录现在是一个多行的过程。
争用 - 将您的用户数据和头像数据混合在一起,您强制只有一个人关心其中一个或另一个的线程在同一个桌面上操作,从而增加了遇到锁定问题的风险。
缺乏执行 - 您的数据约束现已进入业务层。数据库无法再确保所有用户都具有应该具有的所有属性,或者这些属性属于正确的类型等。
答案 2 :(得分:1)
在这种情况下,看起来用户可能有一个大型头像和一个小型头像,那么为什么不在用户表上创建这些列?
我们有一个类似的工作表,可能是以良好的意图开始的,但现在很难处理。这是因为它现在有100个不同的“MetaKeys”,并且没有关于允许的内容和每个内容的良好文档。您基本上必须查看代码中每个代码的使用方式并从中进行计算。因此,在走下去之前,弄清楚如何为未来的开发人员记录这一点。
此外,要检索有关每个用户的所有信息,它不再是1行查询,而是n行查询(其中n是用户上的字段数)。此外,一旦掌握了这些数据,就必须根据元键对每个数据进行后期处理,以获取有关用户的详细信息(这通常更像是一项开发工作,因为你必须做一堆字符串比较)。接下来,许多数据库只允许从查询返回一定数量的行,因此您可以一次检索的用户数除以n。最后,根据以这种方式存储的信息订购用户将更加复杂和昂贵。
一般情况下,我会说你应该创建任何具有特殊功能的字段或要求排序为表中的列。由于它们无论如何都需要开发工作,因此您可以在实现它们时将它们添加为额外的列。我会说你的头像照片属于这个类别,因为你可能每个都有一个,并且总是希望在某些地方显示大的,在其他地方显示小的。但是,如果你想允许用户创建他们自己的字段,这将是一个很好的方法,虽然我会使另一个表可以从用户表加入。以下是我建议的表格。我假设“状态”和“收藏颜色”是用户2输入的自定义字段:
User:
| Id | Name |Location | Website | avatarLarge | avatarSmall
----------------------------------------------------------------------
| 2 | iPityDaFu |Dallas, Tx | www.example.com | 124.png | 124_thumb.png
UserMeta:
Id | UserId | MetaKey | MetaValue
-----------------------------------------------
1 | 2 | Status | Hungry
2 | 2 | Favorite Color | Blue