Php 优化下一个和上一个元素的查询
我正在寻找在不运行完整查询的情况下检索记录的下一个和上一个记录的最佳方法。我有一个全面实施的解决方案,我想知道是否有更好的方法来实现这一点 假设我们正在为一个虚构的蔬菜水果商建立一个网站。除了他的HTML页面外,每周他都想在自己的网站上发布一份特价商品列表。他希望这些报价驻留在实际的数据库表中,用户必须能够以三种方式对报价进行排序 每个项目还必须有一个详细页面,包含更多关于报价的文本信息以及“上一步”和“下一步”按钮。“上一步”和“下一步”按钮需要根据用户为列表选择的排序指向相邻条目Php 优化下一个和上一个元素的查询,php,mysql,algorithm,data-structures,pseudocode,Php,Mysql,Algorithm,Data Structures,Pseudocode,我正在寻找在不运行完整查询的情况下检索记录的下一个和上一个记录的最佳方法。我有一个全面实施的解决方案,我想知道是否有更好的方法来实现这一点 假设我们正在为一个虚构的蔬菜水果商建立一个网站。除了他的HTML页面外,每周他都想在自己的网站上发布一份特价商品列表。他希望这些报价驻留在实际的数据库表中,用户必须能够以三种方式对报价进行排序 每个项目还必须有一个详细页面,包含更多关于报价的文本信息以及“上一步”和“下一步”按钮。“上一步”和“下一步”按钮需要根据用户为列表选择的排序指向相邻条目 (来源:
(来源:) 显然,在第一个示例中,“西红柿,一类”的“下一步”按钮必须是“苹果,一类”,在第二个示例中是“梨,一类”,在第三个示例中则没有 详细信息视图中的任务是确定下一个和上一个项目,而无需每次运行查询,列表的排序顺序是唯一可用的信息(假设我们通过get参数
?sort=offerof theweek\u price
,并忽略安全影响)
显然,首先想到的解决方案是将下一个和上一个元素的ID作为参数传递。毕竟,我们现在已经知道了ID。但是,这在这里不是一个选项——它在这个简化的示例中可以工作,但在我的许多实际用例中不起作用
我目前在CMS中使用的方法是我命名的“排序缓存”。加载列表时,我将项目位置存储在名为sortingcache
的表中的记录中
name (VARCHAR) items (TEXT)
offeroftheweek_unsorted Lettuce; Tomatoes; Apples I; Apples II; Pears
offeroftheweek_price Tomatoes;Pears;Apples I; Apples II; Lettuce
offeroftheweek_class_asc Apples II;Lettuce;Apples;Pears;Tomatoes
显然,items
列实际上填充了数字ID
在详细信息页面中,我现在访问相应的排序缓存
记录,获取项
列,分解它,搜索当前项ID,并返回上一个和下一个相邻项
array("current" => "Tomatoes",
"next" => "Pears",
"previous" => null
);
这显然很昂贵,只适用于有限数量的记录并创建冗余数据,但让我们假设在现实世界中,创建列表的查询非常昂贵(确实如此),在每个细节视图中运行它是不可能的,并且需要一些缓存
我的问题:
- 您认为查找不同查询顺序的相邻记录是一种好做法吗
- 在性能和简单性方面,您知道更好的实践吗?你知道什么让这个完全过时了吗
- 在编程理论中,这个问题有名字吗
- 对于这种技术,“排序缓存”的名称是否合适并且可以理解
- 有没有公认的通用模式来解决这个问题?它们叫什么
因此,您有两项任务:
PS:若有序列表可能太大,你们只需要实现寻呼机功能。可能有不同的实现,例如,您可能希望在查询中添加“限制5”,并提供“显示下一个5”按钮。按下此按钮时,会添加“价格<0.89限制5”之类的条件 这里有一个想法。当杂货商插入/更新新产品时,而不是当最终用户选择要查看的数据时,您可以将昂贵的操作转移到更新上。这似乎是一种处理排序数据的非动态方式,但可能会提高速度。而且,正如我们所知,性能和其他编码因素之间总是有一个权衡 为每个报价和每个排序选项创建一个表来保存下一个和上一个。(或者,如果您总是有三个排序选项,您可以将其存储在offer表中——查询速度是取消数据库规范化的一个很好的理由) 因此,您可以使用以下列:
- 排序类型(未排序、价格、类别和价格说明)
- 报价ID
- 上一个ID
- 下一个ID
每次插入、更新或删除报价时,您都需要运行一个流程来验证sorttype表的完整性/准确性 我不确定自己是否理解正确,如果没有,就告诉我;) 假设givens是对排序列表和该列表中当前偏移量的查询,即我们有一个
$query
和一个$n
一个非常明显的最小化查询的解决方案是一次获取所有数据:
list($prev, $current, $next) = DB::q($query . ' LIMIT ?i, 3', $n - 1)->fetchAll(PDO::FETCH_NUM);
该语句按当前排序顺序从数据库中获取上一个、当前和下一个元素,并将相关信息放入相应的变量中
但由于这个解决方案太简单,我想我误解了什么。我也做过噩梦。您当前的方法似乎是最好的解决方案,即使是对于包含10k项的列表。在http会话中缓存列表视图的ID,然后使用该ID显示(个性化到当前)
?sort=price
include(/sorts/$sort/tomatoes_class_1)
/*tomatoes_class_1 is probably a numeric id; sanitize your sort key... use numerics?*/
Item Next Prev
A B -
B C A
C D B
...
Type Class Price Sort1 Sort2 Sort3
Lettuce 2 0.89 0 4 0
Tomatoes 1 1.50 1 0 4
Apples 1 1.10 2 2 2
Apples 2 0.95 3 3 1
Pears 1 1.25 4 1 3
once_per_day
add/delete/update all records
recalculate sort orders