嗯,这听起来像是一个蹩脚的问题,我知道。这可能是最明显的事情之一,但我一直试图想出一种在数据库中对条目进行排序的好方法。
图片表看起来像这样:
entry_id | entry_data
-------------------------
1 | data1
2 | data2
... | ...
n | datan
entry_id当然是具有AI选项的主键,因此所有条目都具有唯一ID。 现在。我想订购那些数据。假设我希望entry_id = 2成为第一个而不更改其entry_id。然后该表需要另一列来存储订单号。 我尝试了两种方法。
entry_order_no :这基本上会保留商品的订单号。任何新项目将始终添加到最后。
left_id + right_id :这种方法由phpBB使用。不知道为什么它需要right_id呢?
我似乎更喜欢第一种方法,但是你如何在以后对数据进行排序。 让我们假设我想从最后一个位置新增项目移动,再说第二个。 方式我一直这样做我使用索引表,其中索引是订单号。每个索引都包含具有entry_id的关联数组。这样我“简单地”在第二个位置的所有条目上使用UPDATE进行foreach循环。这可能适用于几行。也许甚至数十个。但是,当你有数百个?这似乎非常低效。第二个看起来好一点。但有些事情仍然告诉我有更好的方法。
请建议。
答案 0 :(得分:2)
我不确定你为什么要尝试这样做的本质,所以很难说,但就你的低效foreach循环而言,停止在集合上使用迭代方法 - 使用set操作,他们'更快,更准确地说是DB的意思。所以不是......
for row in db>2
entryorderno += 1
这样做......
UPDATE Table
SET entryorderno = entryorderno + 1
WHERE entryorderno > 2
另外,从Alex Martelli所说的那里开始,这样做一段时间应该是相当不错的,但最终你将不得不用新的间距重新安装所有内容......但是该字段上的聚集索引会使事情按顺序排列那个ID ....当然它也意味着如果它是一个大表,那么插入到表的中间可能是资源密集的。
答案 1 :(得分:1)
phpBB正在使用更智能的方法:left_id和right_id对应于树的节点,作为嵌套集的一部分。如果性能成为一个问题,这可能是您想要采取的路线(因为您似乎担心这一点)。这是一个 very thorough implementation walkthrough of nested sets 。
但请注意,数据库通常用于无序数据。要获取已排序的数据,通常会检索您感兴趣的所有行,然后进行后处理 - 例如,使用ORDER BY
子句或者在结果返回后对结果进行排序。
也就是说,您需要将排序存储为数据本身的一部分(例如,因为它无法计算或基于用户首选项),这通常使用另一个保存排序的表或通过嵌套集方法中的其他列,如上所述。
答案 2 :(得分:0)
当我们在原始基础编程时,我们编号为“10,20,30,......”,所以如果我们需要在现有的行之间插入一行,我们可以将它编号,比方说25,而不需要重新编号所有其他的。你可以对你的“入门订单”使用类似的技巧,如果它的唯一目的是保持行的顺序,然后让你以最小的麻烦改变那个顺序,而不重新编号一切(mysql内部将不得不更新索引)那个专栏,但这仍然比自己做的更快,更有可能 - 在你的设置上尝试一些基准来确认这一点。使用BIGINT
和大初始增量,比如1024,在您需要重建该列之前,您应该可以进行多次重新排序。
答案 3 :(得分:0)
一个有趣的问题。 left_id / right_id可能是嵌套集方法的一种实现,用于存储分层(而不是顺序)数据。请参阅Trees in SQL。
我为这个问题采取了两种方法。一个是您正在描述的蛮力,您可以根据需要在添加/更改/删除条目时调整所有数字。另一种是只维持一个等级,所以当一个条目的等级提高时,你只需增加其等级数而不修改任何其他条目的等级。例如,每次用户单击向上箭头时,条目的等级将添加1,并且您重新呈现按等级排序的列表,在这种情况下,节点在列表中向上移动一级。
一旦获得大量数据,这些方法都不是理想的,但通常在此时您不再手动维护排序顺序,并设计了一种算法来自动排序。
答案 4 :(得分:0)
如果您需要人工排序(您无法通过对某些列进行排序来创建动态排序),则必须添加Position
列。然后,当您重新排序两行时,如果使用密集编码,则必须更改它们之间的所有行。
您可以选择使用丢失编码 - 例如,第一行获取位置100,第二行获取第三行,第三行300,依此类推。这将增加逻辑的复杂性,但允许您执行大量重新排序操作,而无需修改多行。
答案 5 :(得分:0)
如何在数据库中存储简单的排序顺序列并使用触发器和存储的功能?
每当您更新order
列并将所有大于新订单的订单增加1时,触发器就会触发。
数百或数千条记录对于任何体面的数据库都不应该是一个问题,特别是当处理是在内部完成数据库时(我会不建议在您的应用程序中执行此操作),尽管一旦进入数千万,更新那么多行会很麻烦。
取决于您的数据大小。