简体   繁体   English

PHP / MySQL:选择所有产品/行的替代方法?

[英]Php/MySQL: Alternative for selecting all products/rows?

My PHP application has the function product_fetch([parameters]) which returns 'Product' objects which information are stored in database. 我的PHP应用程序具有函数product_fetch([parameters]) ,该函数返回“ Product”对象,这些对象的信息存储在数据库中。

In my admin area, there is a page called "Featured Products" which allows me to select 10 products to be displayed in the main page. 在我的管理区域中,有一个名为“特色产品”的页面,该页面使我可以选择10个要在主页上显示的产品。

Now comes the problem: I made 10 select/combobox, each allows me to select one product, out of 400. So in order to make all the options, a query has to be made: SELECT * FROM products 现在出现了问题:我做了10个select / combobox,每个都允许我从400个中选择一个产品。因此,要进行所有选择,必须进行查询: SELECT * FROM products

Question: Is it correct to make such a query, even though there's hundreds of rows? 问:即使有数百行,进行这样的查询是否正确?

The solution you proposed is certainly do-able, and 400 rows is really meek compared to the upper limits of what MySQL is capable of handling. 您提出的解决方案当然是可行的,并且与MySQL能够处理的上限相比,实际上只有400行是温柔的。 What is more concerning is the user experience here. 更重要的是这里的用户体验。 Granted this will only affect you, but I would design myself something a little nicer than a bunch of <select> s. 当然,这只会影响您,但我会设计自己一些比一堆<select>更好的东西。 My idea is to start with just one textbox that autocompletes the names of your products. 我的想法是从一个文本框开始,该文本框会自动完成您产品的名称。 This can be accomplished if the product title has a fulltext index . 如果产品标题具有全文索引,则可以完成此操作。 Then your autocomplete script could use this query: 然后,您的自动完成脚本可以使用以下查询:

SELECT * FROM Products WHERE MATCH(title) AGAINST ('contents of textbox' IN BOOLEAN MODE);

There are plenty of jQuery plugins like Autocomplete that will handle the JS side (querying the server for autocomplete results). 有很多jQuery插件( 例如自动完成功能)可以处理JS方面(查询服务器以获取自动完成结果)。 The one I just mentioned adds a term GET parameter which you could easily grab and throw into the query: 我刚刚提到的那个添加了一个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());

Once you type in (or click on an autocomplete result) in the one textbox, another should appear below it and the focus should go to it. 在一个文本框中键入(或单击自动完成结果)后,另一文本框应显示在其下方,焦点应移至该文本框。 From there you can type another product, and continue until you reach 10. Each textbox (unless there is only one) should have a delete link next to it that removes that product from the featured listing. 从那里,您可以键入另一种产品,并继续直到达到10。每个文本框(除非只有一个)都应在其旁边具有一个删除链接,该链接将从功能列表中删除该产品。

I'll look for a site that implements this kind of functionality so you can better understand what I'm talking about. 我将寻找一个实现这种功能的站点,以便您可以更好地理解我在说什么。 Basically here, what you're searching for is achieved. 基本上在这里,您正在寻找的东西就实现了。 You don't have to have 10 select boxes with 400 options and you don't need a SELECT * FROM Products . 您不必具有10个选择框和400个选项,也不需要SELECT * FROM Products

You would be much better of specifying which produts you want in the query and only returning those if you have no intention of using any of the others at all. 如果在查询中根本不打算使用其他任何产品,则最好指定在查询中需要哪些产品,然后仅返回这些产品。

You can do this using many methods. 您可以使用多种方法来执行此操作。 A simple one would be using an ID field in an in statement like this: 一种简单的方法是在in语句中使用ID字段,如下所示:

 select col1, col2 from products where id in(1,4,12,5)

It might seem to make little difference, but what if your procuts table had a hundred thousand rows in it? 这似乎没有什么区别,但是如果您的procuts表中有十万行呢?

You could also have a flag in the table to say that the items are featured which would let you use something like this: 您还可以在表中有一个标志来说明这些项目具有特色 ,这样您就可以使用以下内容:

select col1, col2 from products where featured='Y'

Or you could even have a table that only has featured items (even just their ID) and join it to your main listing like this: 或者,您甚至可以创建一个仅包含特色项目(甚至只是其ID)的表,然后将其加入到您的主列表中,如下所示:

select
    a.col1,
    a.col2
from
    products a
        join featured b
            on a.id=b.id

If you want to pick through your whole table, you can even use a simple limit clause that picks up a certain number of rows from the table and can be reused to get the next set: 如果要浏览整个表,甚至可以使用一个简单的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)

The short version is though, no matter how you do it, pulling back a whole table of data to pick through it within PHP is a bad thing and to be avoided at all costs. 简短的版本是,无论您如何做,在PHP中拉回整个数据表以进行选择都是一件坏事,并且不惜一切代价避免。 It makes the database work much harder, uses more network between the database and PHP (even if they are on the same machine, it is transferring a lot more data between the two of them) and it will by default make PHP use a lot more resources to process the information. 它使数据库工作更加困难,在数据库和PHP之间使用更多的网络(即使它们在同一台计算机上,它们之间也在传输更多的数据),并且默认情况下,它将使PHP使用更多的数据库处理信息的资源。

SELECT * FROM tbl LIMIT $page,10; 

The above query will select 10 entries from offset $page Fetching all rows is a bad idea as you are using 10 only anyway. 上面的查询将从offset $page选择10个条目获取所有行是一个坏主意,因为无论如何您仅使用10个。 When your table expands to millions of rows, you will see a noticeable difference. 当表扩展到数百万行时,您会看到明显的不同。

There is nothing fundamentally wrong with selecting all rows if that's what you mean to do. 如果您要这样做,那么选择所有行根本没有错。 Hundreds of rows also shouldn't be a problem for the query in terms of performance. 就性能而言,数百行也不应该成为查询的问题。 However, thousands or millions might if your database grows that big. 但是,如果数据库如此之大,则可能成千上万。

Think about the user - can they scroll through hundreds of products? 考虑用户-他们可以滚动浏览数百种产品吗? Probably. 大概。 If not, then maybe it's the UI design at fault , not the query. 如果不是,那么可能是UI设计有问题 ,而不是查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM