哪个更有效:多个MySQL表还是一个大表?

Pet*_*aig 100 mysql database-table

我在MySQL数据库中存储了各种用户详细信息.最初它设置在各种表中,这意味着数据与UserIds链接,并通过有时复杂的调用输出,以根据需要显示和操作数据.建立一个新系统,将所有这些表组合成一个相关内容的大表几乎是有意义的.

  • 这会成为一种帮助还是障碍?
  • 调用,更新或搜索/操作时的速度考虑因素?

这是我的一些表结构的示例:

  • 用户 - UserId,用户名,电子邮件,加密密码,注册日期,IP
  • user_details - cookie数据,名称,地址,联系方式,从属关系,人口统计数据
  • user_activity - 贡献,上次在线,上次观看
  • user_settings - 配置文件显示设置
  • user_interests - 广告可定位变量
  • user_levels - 访问权限
  • user_stats - 点击,统计

编辑:到目前为止,我已经提出了所有答案,它们都有基本上回答我问题的元素.

大多数表具有1:1的关系,这是使它们非规范化的主要原因.

如果表格跨越100多列,当这些单元格的大部分可能保持空白时,是否会出现问题?

小智 62

多个表有以下方式/案例帮助:

(a)如果不同的人正在开发涉及不同表格的申请,则将它们分开是有意义的.

(b)如果你想为不同的人提供不同类型的权限来处理数据的不同部分,分割它们可能会更方便.(当然,您可以查看定义视图并对其进行适当授权).

(c)为了将数据移动到不同的地方,特别是在开发过程中,使用表格来缩小文件大小是有意义的.

(d)当您在单个实体的特定数据收集上开发应用程序时,较小的足迹可能会给您带来舒适感.

(e)这是一种可能性:你认为单一价值数据在未来可能会变成多个价值.例如,信用额度是截至目前的单一值字段.但是明天,您可以决定将值更改为(日期,日期,信用值).拆分表现在可能会派上用场.

我的投票将是多个表格 - 数据适当分割.

祝好运.

  • @RohitKhatri:据我所知,拥有多个表会在大多数情况下提高性能. (3认同)
  • 有多个表会降低性能吗? (2认同)

Qua*_*noi 35

组合表称为非规范化.

它可能(或可能不)帮助使一些查询(其中许多JOINs)以更快的速度运行,但代价是创建维护地狱.

MySQL只能使用JOIN方法,即NESTED LOOPS.

这意味着对于驱动表中的每个记录,MySQL在循环中的驱动表中找到匹配的记录.

定位记录是一项非常昂贵的操作,可能需要几倍于纯记录扫描的时间.

将所有记录移动到一个表中将帮助您摆脱此操作,但表本身会变大,表扫描需要更长时间.

如果在其他表中有大量记录,则表扫描的增加可能会使顺序扫描的记录的权益超重.

另一方面,维护地狱是有保障的.

  • 如果您有 10000 个用户,并且您正在与正确设置了外键的数据库进行联接,那么您应该只需要通过执行诸如 select * from users where name="bob" 之类的操作来进行密集查找。一旦你有了 bob,那么你就可以使用索引来查找 bob 的连接表,这会明显更快,因为你使用的是 bob 的 id。无论您是在查询中进行联接还是查询 bob 然后单独查询表,都会发生这种情况。当然,希望您的第二个查询是基于 bob 的 id 而不是其他内容。 (3认同)

Dav*_*und 17

他们都是1:1的关系吗?我的意思是,如果用户可能属于,例如,不同的用户级别,或者用户兴趣被表示为用户兴趣表中的多个记录,那么合并这些表将立即成为问题.

关于关于规范化的先前答案,必须说数据库规范化规则完全忽视了性能,并且只关注什么是整洁的数据库设计.这通常是您想要实现的目标,但有时候为了追求性能而积极地反规范化是有意义的.

总而言之,我想问的问题归结为表中有多少字段,以及它们访问的频率.如果用户活动通常不是很有趣,那么出于性能维护原因,总是将它放在同一记录上可能会很麻烦.如果某些数据(如设置)经常被访问,但只是包含太多字段,那么合并表也可能不方便.如果您只对性能提升感兴趣,可以考虑其他方法,例如将设置保持独立,但将它们保存在自己的会话变量中,这样您就不必经常查询数据库.


Eri*_*lje 14

难道所有这些表都一个1-to-1关系?例如,每个用户行只有一个对应的行user_statsuser_levels?如果是这样,将它们组合成一个表可能是有意义的.如果关系不是 1 to 1,虽然,它可能是没有意义的结合(非规范化)他们.

除非您拥有数十万或数百万的用户记录,否则将它们放在单独的表与一个表中可能对性能几乎没有影响.您将获得的唯一真正收获来自于通过组合它们来简化查询.

ETA:

如果你担心的是有太多的列,那么考虑一下你通常使用哪些东西并将它们组合起来,将其余的东西放在一个单独的表中(如果需要的话,还是几个单独的表).

如果你看一下你使用数据的方式,我猜你会发现80%的查询都会使用20%的数据,其余80%的数据只是偶尔使用.将经常使用的20%合并到一个表中,并将80%不经常使用的表留在单独的表中,您可能会有一个很好的折衷方案.


小智 9

创建一个大型表违反了关系数据库主体.我不会将它们全部合并到一个表中.您将获得重复数据的多个实例.例如,如果您的用户有三个兴趣点,那么您将拥有3行,并使用相同的用户数据来存储三个不同的兴趣.明确地采用多重"标准化"表格方法.有关数据库规范化,请参阅 Wiki页面.

编辑: 我已经更新了我的答案,因为你已经更新了你的问题......我现在更赞同我的初步答案,因为......

这些细胞的很大一部分可能仍然是空的

例如,如果用户没有任何兴趣,如果你正常化,那么你就不会在该用户的兴趣表中有一行.如果你有一个大型表中的所有东西,那么你将有只包含NULL的列(显然很多).

我曾在一家电话公司工作,那里有大量的表,获取数据可能需要很多连接.当从这些表中读取的性能至关重要时,创建的过程可以生成一个平面表(即非规范化表),该表不需要报告可以指向的连接,计算等.然后将这些用于与SQL服务器代理一起以特定间隔运行作业(即,每周运行一次的一些统计信息,依此类推).


Rud*_*cia 7

为什么不通过使用户表用户的基本信息,每个人都有,然后添加一个"user_meta"表基本上可与用户ID相关联的任何键,值对使用同样的方法做的WordPress.因此,如果您需要为用户查找所有元信息,您只需将其添加到查询中即可.如果登录等事情不需要,您也不必总是添加额外的查询.这种方法的好处还使您的桌子可以向用户添加新功能,例如存储他们的Twitter句柄或每个人的兴趣.您也不必处理关联ID的迷宫,因为您有一个规则所有元数据的表,并且您将其限制为仅一个关联而不是50.

WordPress的专门这样做是为了允许通过插件来增加功能,从而允许您的项目更具可扩展性,如果你需要添加新的功能将不会要求一个完整的数据库检修.


Tun*_*dey 5

我认为这是“视情况而定”的情况之一。拥有多个表更干净,理论上可能更好。但是,当您必须连接 6-7 个表以获取有关单个用户的信息时,您可能会开始重新考虑这种方法。