我有一个会员系统的3个MySQL表。
users
:成为用户的最低要求,仅与帐户信息(电子邮件,密码,is_activated等)相关user_profiles
:用户提供的个人信息(姓名,地址,电话......)user_member_profiles
:由管理员严格管理的信息(已支付注册费,参加会议等)这些可以压缩到一个表格中,这样可以避免头痛并保持代码干净 - 但我觉得最好将它们分开,因为它们的用途略有不同。
选项1:保持这种方式并继续JOIN
和繁琐的UPDATE
s (这条数据转到此表,到另一个,等等。)。为我做更多的工作,但也许它更有意义?
选项2:将所有内容合并到一个表格中。
我会假设使用一个表会更快,不需要连接表。也许这取决于数据?每个表有大约12-20个字段,因此组合表将很大。
每个用户每张表的个人资料不超过1个,但可能根本没有个人资料(或者可能只有1个)。
为此添加一些上下文:它是用于用PHP编写的不断发展的CMS,我需要对每个安装的表进行调整。管理员需要以类似speadsheet的方式管理成员,因此我一次最多可以选择200个用户。
从绩效,设计或组织的角度来看,正确的方法是什么?
答案 0 :(得分:9)
使用宽表(许多列)时要考虑的另一个因素是对RDBMS缓存的影响。任何优秀的开发人员都知道你没有“从表中选择*”,因为它会通过网络从RDBMS向客户端传输不必要的数据。但是在磁盘和RAM之间可能会发生类似的影响,并且还会影响表缓存所需的RAM空间。
大多数RDBMSes分配给定量的内存来缓存数据,从而减少物理磁盘读取并加快对用户的响应。这是Oracle或SQL Server中的缓冲区缓存
如果你有一个宽表并以'select col1,col2,col3 from table'的形式发出查询,那么RDBMS会将完整的行加载到RAM中(而不是col1到3)。因为它会这样老化缓存数据。如果你的表很宽并且你加载50列你当然需要更多的RAM而不是相同的行数*一个窄表。这会对RDBMS性能产生显着影响。
很多宽表,从缓存中老化其他表,并且可以看到IO统计数据随着常用表格从缓存中老化而为宽表格腾出空间。
此因素应添加到标准化数据的其他优点中,并在表格设计时考虑。实际上,如果您有一个可能很宽的表,其中一些数据将被定期访问,而另一些数据很少,请考虑多个具有1对1关系的表。
答案 1 :(得分:2)
我的设计强烈要求保持分离,因为将来用户可能会有两个配置文件,但如果它们合并,性能可能会更好。如果真的存在一对一的关系,并且这种关系永远不会改变,那么我会合并它们。
答案 2 :(得分:2)
您不必使用那么多连接来检索数据。
您可以VIEW
显示来自users
和user_profiles
的所有列:
CREATE VIEW users2 AS
( SELECT u.id
, u.email
, u.password
, u.is_activated
, p.name
, p.address
, p.phone
FROM users u
LEFT JOIN user_profiles p
ON u.id = p.id
)
并在需要来自两个表的数据的查询中使用此VIEW。所有3个表的另一个VIEW等。
答案 3 :(得分:2)
设计问题是您是否需要在一个用户的任何表中拥有多条记录。如果是这样,请不要将它们合并。如果表格是一对一的关系,你可以将它们组合起来,但是如果它们有很多字段或者你的记录大小太宽会导致性能问题以及如果你不能添加数据超过单个记录的实际记录大小限制。如果你现在有很多代码可以访问它们作为serarate表和大量数据,那么重组它们可以获得很小的收益(在开发过程中保存一分钟左右,并且可能没有时间对用户表现不佳)似乎是个坏主意。你可以写一些观点,这样你就不必进行连接,但老实说这些很简单,我也不会打扰。
答案 4 :(得分:1)
将表格分开有两个原因,这与你保留每个用户的记录数量有关。
禁止这些情况,您希望将所有内容保存在一个表中,只需一个键。为了表达数据的多种用途,一个好的解决方案是使用视图 - 选择数据的子集并将其保存为视图,并使用合理的名称。如果您想要管理数据,请调用相应的视图。
答案 5 :(得分:-1)
除非您遇到奇怪的性能问题,否则您应该只有一个表格。
由于性能问题我正在谈论拥有如此多的数据,您希望在表之间对其进行分区以使其保持独立(物理磁盘,服务器等)。这显然不是这种情况。如果是这种情况,那么有很多更好的方法来处理这类事情。
每个人都希望他们拥有的那种表现问题而不是很多人......