对于MySQL表我使用的是InnoDB引擎,我的表的结构如下所示:
表格用户
id | username | etc...
----|------------|--------
1 | bruce | ...
2 | clark | ...
3 | tony | ...
表格用户电子邮件
id | person_id | email
----|-------------|---------
1 | 1 | bruce@wayne-ent.com
2 | 1 | ceo@wayne-ent.com
3 | 2 | clark.k@daily-planet.com
为了从数据库中获取数据,我编写了一个小框架。例如。在__construct($id)
上它检查是否有一个具有给定id的人,如果是,则创建相应的模型并仅将字段id
保存到数组中。在运行时,如果我需要模型中的另一个字段,它只从数据库中获取值,将其保存到数组并返回它。例如。与字段emails
相同,我的代码访问表user-emails
并获取相应用户的所有电子邮件。
对于小型模型,这项工作正常,但现在我正在开发另一个项目,我必须立即获取大量数据以获取列表,这需要一些时间。另外我知道许多与MySQL和许多查询的连接对服务器来说非常紧张,所以..
我现在的问题是:我应该在构建模型时一次获取所有数据(使用左连接等)并将字段保存为数组,还是应该使用其他方法?
答案 0 :(得分:1)
为什么人们坚持将实体和域对象称为“模型”。
除非您的实体非常大,否则我会在您需要时填充整个实体。而且,如果“电子邮件列表”是该实体的一部分,我也会填充它。
正如我所看到的,问题更多地与“如何处理与外键相关的表”有关。
假设您有Users
和Articles
个表,其中每篇文章都有user_id
个外键的特定所有者关联。在这种情况下,在填充Article
实体时,我只会检索user_id
值而不是提取有关用户的所有信息。
但是在您使用Users
和UserEmails
的示例中,电子邮件似乎是User
实体的一部分,而您通常会通过$user->getEmailList()
调用该电子邮件。
<强> TL; DR 强>
在填充User
实体时,我会在两个查询中执行此操作:
User
实体User
实体。<强> P.S 强>
您可能希望查看data mapper模式中的“how”部分。
答案 1 :(得分:0)
在我看来,您应该一次性获取所有字段,并以一种使代码更易于阅读/管理的方式划分查询。
当我们谈论一个或两个查询时,除非组合查询(使用JOIN
或其他)过于复杂,否则差异通常可以忽略不计。通常一个或两个索引是非常慢的查询的解决方案。
如果我们谈论的是一对数百或数千个查询,那么当连接/传输开销变得更加重要时,减少查询数量就会产生影响。
您的框架似乎受到premature optimization的影响。你是一个超级担心从一行中获取太多字段,但为什么呢?你有成千上万的专栏吗?
查询的耗时部分几乎总是查找,而不是数据的传输。当您一次拉一个字段时,您正在使数据库一遍又一遍地执行“硬”部分。