Mysql 是否合并化身和个人资料表?

Mysql 是否合并化身和个人资料表?,mysql,database,Mysql,Database,我有两张桌子: Avatars: Id | UserId | Name | Size ----------------------------------------------- 1 | 2 | 124.png | Large 2 | 2 | 124_thumb.png | Thumb Profiles: Id | UserId | Location | Websi

我有两张桌子:

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
这对我来说可能是一个更干净、更灵活的设置(至少乍一看是这样)。例如,如果我需要允许一条“用户状态消息”,我可以在不接触数据库的情况下这样做

然而,用户的化身将被拉远超过他们的个人资料信息

所以我想我真正的问题是:
这将产生什么样的性能冲击?

合并这些表真的是个坏主意吗?

这几乎总是个坏主意。您所做的是模型的一种形式。当系统需要灵活的属性系统以允许在生产中添加属性(和值)时,此模型有时是必要的

这种类型的模型基本上是基于元数据而不是真实的关系数据构建的。这可能导致引用完整性问题、孤立数据和性能差(取决于所讨论的数据量)


一般来说,如果您的属性是预先知道的,那么您希望将它们定义为实际数据(即具有实际类型的实际列),而不是基于字符串的元数据。

我会坚持原始布局。以下是用一个大的键值对表替换现有表结构的缺点:

存储效率低下-由于存储在metavalue列中的数据是混合的,因此必须使用最坏情况的数据类型声明该列,即使您只需要为某些键保留布尔值。

低效的搜索-如果将来需要从值中查找,数据的混乱将使索引成为一场噩梦。 低效读取-读取单个用户记录现在意味着对多行进行索引扫描,而不是拉动一行。

低效写入-写入单个用户记录现在是一个多行过程。

争用-将用户数据和化身数据混合在一起后,您强制只有一个关注其中一个的线程在同一个表上运行,这增加了您遇到锁定问题的风险。


缺乏强制执行-您的数据约束现在已转移到业务层。数据库不能再确保所有用户都拥有他们应该拥有的所有属性,或者这些属性是正确的类型,等等。

在这种情况下,看起来用户可能有一个大化身和一个小化身,那么为什么不在用户表上创建这些列呢

我们在工作中有一个类似的桌子,可能一开始是出于好意,但现在却很头疼。这是因为它现在有100个不同的“元键”,并且没有关于什么是允许的以及每个元键做什么的好文档。基本上,您必须查看每一个在代码中的用法,并从中找出它。因此,在走这条路之前,先弄清楚如何为未来的开发人员编写文档

此外,要检索每个用户的所有信息,它不再是一个1行查询,而是一个n行查询(其中n是用户上的字段数)。此外,一旦你有了这些数据,你就必须根据你的元密钥对每一个数据进行后期处理,以获得关于你用户的详细信息(这通常是一项开发工作,因为你必须做一系列的字符串比较)。接下来,许多数据库只允许从查询返回一定数量的行,因此可以一次检索的用户数除以n。最后,基于这种方式存储的信息对用户进行排序将更加复杂和昂贵

一般来说,我想说的是,您应该使任何具有专门功能或需要排序的字段成为表中的列。因为它们无论如何都需要开发工作,所以在实现它们时,您最好将它们作为一个额外的列添加。我想说你的头像图片属于这一类,因为你可能每个都有一张,并且总是想在某些地方显示大的,在其他地方显示小的。但是,如果您希望允许用户创建自己的字段,这将是一个很好的方法,尽管我会将其创建为另一个可以从用户表连接到的表。下面是我建议的表格。我假设“Status”和“Favorite Color”是用户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

所有的答案都是正确的,谢谢大家的帮助@马特·托科利很高兴我能帮忙:)