SELECT *来自大表,还是拆分表并进行许多小查询?

时间:2014-08-05 18:14:38

标签: php mysql

我有一个个人项目(基于浏览器的游戏)和一个用于存储db上的玩家装备(武器/装甲和这些物品的统计数据)的表目前是102列。

每次看表时都会让我感到烦恼,因为它太大了,但使用它的页面主要需要所有信息,因此用户可以看到所有的东西'。 / p>

所以我在考虑对表进行规范化,但我基本上想知道在大表上有一个SELECT * from table WHERE user = user,或者将它分解成许多小表,并且有许多较小的查询,收集相同的信息。

或者可能有更好的方法使用连接或其他SQL wizadry?

如果我要将桌子分开,我想我最终可能会有12个桌子来替换1个大桌面,所以如果我单独打到所有桌面,我将不得不在页面上进行15次查询我需要的查询。如果页面小而有效,那么对于页面有15个查询吗?

7 个答案:

答案 0 :(得分:6)

你应该考虑去至少第3范式。我发现它可能是一张像你声称它包含冗余一样大的表。这会降低您的查询速度,而不是添加联接。

答案 1 :(得分:5)

您应该了解规范化以及它如何使您和您的模型受益。

SQL可以轻松处理JOIN。如果查询中有超过7个,则可能需要将其分解。

作为一名用户,我怀疑我是否希望一次处理多套100件物品。也许您应该考虑如何更好地呈现最重要的信息,并使用机会深入研究它。

性能和效率更可能取决于良好的索引。如果列出现在WHERE子句中,则最好有一个索引。

答案 2 :(得分:4)

如果要从更多表连接数据,则数据库规范化有时会影响选择的性能。另一方面,标准化可以提高性能,如果您只需要插入,更新或删除某些字段,因为它们位于较小的单独表中。但是,设计数据库完全规范化然后对某些部分进行非规范化以在需要时提高性能是一种很好的做法。

然而,对性能的影响总是非常依赖于特定情况:数据结构,对数据的主要操作等。

您的表是完全非规范化数据库的示例。它有时被用作某种缓存表 - 规范化表仍然存在,但也有非规范化的“缓存”表,以便更快地选择。

分别查询每个表真的不是一个好主意,JOIN已经过优化,可以从不同的表中收集数据。

尽可能减少一页所需的查询总是很好。

我认为研究规范化的良好开端可能是Database normalization on Wikipedia


在您的情况下,我会考虑将设备存储在行而不是列中。我的意思是基本上有3个表:用户设备 user_equipment

user_equipment 只有2列: user_id equipment_id ,这意味着经典的N到M关系。但它也可以包含特定于用户和设备的字段,例如 equipment_damage

每个设备在设备表中都是一行(而不是表 user_equipment 中的列),并且有自己的ID。如果需要添加新设备,只需将新行插入设备表,而不是更改数据库结构(添加列)。它更容易管理。

还要考虑一些命名约定。最好以单数形式命名表,并将N到M表命名为连接在一起的表名的组合。因此,表用户设备 user_equipment 。如果从他们的名字中完全清楚它们包含的内容。您有表 equiped_items ,它连接用户设备项目,但您必须查看内部才能实现什么在里面。

答案 3 :(得分:2)

取决于您对“更好”的定义。从数据冗余,一致性和可维护性的角度来看,最好将数据模型置于第三范式。 但是,从性能或代码复杂性的角度来看,从这个角度来看更好的并不总是更好。我的提示是:从正确规范化的数据库开始并加入查询。如果由于经过测量和证明的性能瓶颈而绝对必要,则归一化。

答案 4 :(得分:1)

嗯,我认为这取决于你的用户界面。如果在任何给定时间都需要所有102个项目,那么您将无法在这些表格中获得任何性能提升。但是,归一化实际上是一种好方法,因为冗余,数据不一致等。另一方面,如果您的UI只显示这102列的一部分,您应该将此表逻辑地拆分为具有共同点的小表。然后,您可以根据需要简单地整合"请求数据,如果你真的需要它们。请记住,您必须利用更多HTTP请求的性能与传输的更多数据。

答案 5 :(得分:1)

将大量数据存储在单个表中通常不是问题。

您可以对该表进行昂贵的查询,也可以制作一个轻量级的查询。

使用如此大的表(许多列),以下可能是一个昂贵的查询,并且您将要限制类似的查询(即使查询缓存可能会减轻一些费用)。

SELECT * FROM user WHERE user_id = 1

这是针对同一个表的轻量级查询:

SELECT lastname, firstname FROM user WHERE user_id = 1

在一个表中存储许多一对一用户属性很好。只询问你需要的是关键。

搜索(以及正确使用索引)通常是一个更大的问题。

答案 6 :(得分:0)

已经给出了很多很棒的答案,但没有人提到虚拟表也称为视图。在这种情况下,视图非常有用,其中来自本质上不同的实体(表)的信息经常被提取并一起显示。

只需规范化数据库,然后使用虚拟表将该页面上显示的所有列收集到一个视图中,然后就可以在该视图表上进行一次选择。

您可以在本教程http://www.mysqltutorial.org/mysql-views-tutorial.aspx或参考手册http://dev.mysql.com/doc/refman/5.0/en/views.html

中详细了解观看次数