我的PHP应用程序具有函数product_fetch([parameters])
,该函数返回存储在数据库中的"Product"对象。
在我的管理区,有一个名为"特色产品"的页面,可以让我选择10种产品显示在主页上。
现在问题来了:我制作了10个选择/组合框,每个组合框允许我从400个中选择一个产品。因此,为了做出所有选项,必须进行查询:SELECT * FROM products
问:即使有数百行,进行这样的查询是否正确?
您提出的解决方案当然是可行的,与MySQL能够处理的上限相比,400行真的很温和。更令人担忧的是这里的用户体验。当然,这只会影响你,但我会为自己设计一个比一堆<select>
更好的东西。我的想法是从一个自动填写产品名称的文本框开始。如果产品标题具有全文索引,则可以实现这一点。然后您的自动完成脚本可以使用以下查询:
SELECT * FROM Products WHERE MATCH(title) AGAINST ('contents of textbox' IN BOOLEAN MODE);
有很多像Autocomplete这样的jQuery插件可以处理JS端(向服务器查询自动完成结果)。我刚才提到的添加了一个term
GET参数,您可以很容易地获取该参数并将其放入查询中:
// You might want to only select the relevant columns
$stmt = $pdo->prepare('SELECT * FROM Products WHERE MATCH(title) AGAINST (:search IN BOOLEAN MODE)');
$stmt->execute(array(':search' => $_GET['term']);
// Output JSON results
echo json_encode($stmt->fetchall());
一旦你在一个文本框中输入(或点击自动完成结果),另一个应该出现在它的下面,焦点应该指向它。从那里你可以输入另一个产品,然后继续,直到你达到10。每个文本框(除非只有一个)旁边都应该有一个删除链接,将该产品从特色列表中删除。
我将寻找一个实现这种功能的网站,这样你就可以更好地理解我在说什么。基本上,在这里,你所寻找的已经实现了。您不必有10个包含400个选项的选择框,也不需要SELECT * FROM Products
。
您最好在查询中指定您想要的产品,并且只有在根本不打算使用其他产品的情况下才返回这些产品。
您可以使用多种方法来完成此操作。一个简单的方法是在in
语句中使用ID字段,如下所示:
select col1, col2 from products where id in(1,4,12,5)
这似乎没有什么不同,但如果你的监考表上有十万行呢?
你也可以在表中有一个标志,表明这些项目是特色,这将允许你使用这样的东西:
select col1, col2 from products where featured='Y'
或者,你甚至可以有一个只包含特色项目(甚至只有他们的ID)的表,并将其加入到你的主列表中,如下所示:
select
a.col1,
a.col2
from
products a
join featured b
on a.id=b.id
如果你想遍历整个表,你甚至可以使用一个简单的limit
子句,它从表中提取一定数量的行,并可以重用以获得下一个集合:
select col1, col2 from products limit 10;
// Will pick the first 10 rows of data.
select col1, col2 from procuts limit 30,10;
// Will pick rows 31-40 (skipping first 30, then returning next 10)
不过,简短的版本是,无论你怎么做,在PHP中提取一整张数据表来进行筛选都是一件坏事,必须不惜一切代价避免。它使数据库工作更加困难,在数据库和PHP之间使用更多的网络(即使它们在同一台机器上,它也会在它们之间传输更多的数据),并且默认情况下会使PHP使用更多的资源来处理信息。
SELECT * FROM tbl LIMIT $page,10;
上述查询将从偏移$page
中选择10个条目获取所有行是个坏主意,因为无论如何都只使用10行。当您的表扩展到数百万行时,您将看到明显的差异。
如果你想这么做,那么选择所有行并没有什么根本性的错误。就性能而言,数百行对查询来说也应该不是问题。然而,如果您的数据库增长到如此之大,可能会有数千或数百万。
想想用户,他们能滚动浏览数百种产品吗?可能如果不是,那么可能是UI设计出错,而不是查询。