简体   繁体   English

用户选择对MySQL表行进行排序的最佳方法是什么?

[英]What is the best approach to sort MySQL table rows by user choice?

Suppose we have a MySQL table (id , name) and a drag-and-drop-enabled list view of the table. 假设我们有一个MySQL表(id,name)和一个支持拖放的列表视图。 User drags 90th row and places it over 10th row. 用户拖动第90行并将其放在第10行。 What is the best approach to keep this new sorting? 保持这种新排序的最佳方法是什么?

  • I do not mean to keep sorting for every use separately
  • The HTML/JavaScript is not the problem

I have seen some programmers add a weight column to table, setting lower number upper in the table. 我见过一些程序员在表中添加一个权重列,在表中设置较低的数字。 In my example it will be 1 to 100. The problem is in case of above example (90 to 10) updating 81 rows is required. 在我的示例中,它将是1到100. 问题是在上述示例(90到10)的情况下,需要更新81行。 90 changes to 10 and each 10 to 89 increments. 90改为10,每增加10到89。 Is it efficient in MySQL? 它在MySQL中有效吗? Is there any better solution? 有没有更好的解决方案?
Another way maybe is saving new order as a string in another table, but in this case we lose MySQL sorting in retrieval phase! 另一种方法可能是将新订单保存为另一个表中的字符串, 但在这种情况下,我们会在检索阶段丢失MySQL排序!

I remember when we learned trie tree structure in university as an indexing tool, we said wow! 我记得当我们在大学里学习树形结构作为索引工具时,我们说哇! Even when we took advantage of every single bit of a byte, 1.5 GB of pure text data stored in less than 500KB!!! 即使我们利用一个字节的每一位,1.5 GB的纯文本数据存储在不到500KB! So right now I still search to find a better answer! 所以现在我仍然寻找更好的答案!

Even programming languages when updating indexes for an array that had an object added in a previously occupied index adds one to each index. 更新在先前占用的索引中添加了对象的数组的索引时,即使编程语言也会为每个索引添加一个。

You're going to have to end up updating the index for every single row. 您将不得不最终更新每一行的索引。

The cleanest way to do that however would be something like this (where people is a non trivial table of course): 然而,最干净的方法就是这样(当然人们是一个非常简单的表格):

UPDATE people
SET index = index + 1
WHERE index BETWEEN $newIndex AND $oldIndex;

depending on your database, between might include or exclude the high and low bound numbers. 根据您的数据库,可能包括或排除上限和下限数字。 Just make sure you know how it treats them! 只要确保你知道如何对待他们!

Rather than adding a weight column to the MYSQL table, add a next_object column to the table. 而不是向MYSQL表添加weight列,而是向表中添加next_object列。

It would function kind of like a linked list (if you're familiar with that). 它的功能类似于链表(如果您熟悉它)。 Every object entered will point to the next object. 输入的每个对象都将指向下一个对象。

Let's go through the scenario of moving a position 90 object to position 10. 让我们来看看将位置90对象移动到位置10的场景。

First, you need to update the 89th object so that it now points to the 91st object (the new 90th object) 首先,您需要更新第89个对象,使其现在指向第91个对象(新的第90个对象)

Then, you need to update the 9th object, and have it point to the 90th object (the new 10th object) 然后,您需要更新第9个对象,并指向第90个对象(新的第10个对象)

Last, you need to update the 90th object (the new 10th object), and have it point to the 10th object (the new 11th object) 最后,您需要更新第90个对象(新的第10个对象),并指向第10个对象(新的第11个对象)

And of course by point I mean, update the next_object field to the object I say I'm pointing to. 当然,我的意思是,将next_object字段更新为我说我指向的对象。

What exactly could you put as a value in the next_object field though? 你究竟能把它作为一个值放在next_object字段中? Just the object's ID, or something similar. 只是对象的ID,或类似的东西。

I just came up with this system as an alternative when I started writing this answer, so I'm not sure it's the most effective way. 当我开始写这个答案时,我只是想出了这个系统,所以我不确定这是最有效的方法。 But hey, updating 3 objects is better than a potential 100,000 (if you had 100,000 objects). 但是,嘿,更新3个对象比潜在的100,000个更好(如果你有100,000个对象)。

At last, I made the sort by this method: I created a weight column. 最后,我通过这种方法进行了排序:我创建了一个权重列。 Each row after insertion gets its id as weight value. 插入后的每一行都将其id作为权重值。 It ensures that new row will be at end. 它确保新行将结束。 weight column is type of FLOAT. 重量栏是FLOAT的类型。 Jquery helps to get new position of the row, plus prev() and next() table row. Jquery有助于获取行的新位置,以及prev()和next()表行。 Right new we have three situations that are commented in the fallowing snippet (After retriving IDs from rows and sending Ajax to PHP): 正确的新版本我们有三种情况在下面的代码片段中进行了注释(从行中检索ID并将Ajax发送到PHP之后):

    #table of DB
    $table = $_POST['table'];
    #the id of the row on top
    $t = $_POST['t'];
    #the id of the row on middle
    $m = $_POST['m'];
    #the id of the row on bottom
    $b = $_POST['b'];
    switch ('') {
        #top is empty, so the row is droped on top
        case $t:
            #we set middle weigh 0.5 lower than its bottom
            $query = "
                UPDATE `$table` m, `$table` b
                SET m.`weight` = b.`weight`-0.5
                WHERE m.`id` = $m
                AND b.`id` = $b
            ";
            break;
        #bottom is empty, so the row is droped on the end
        case $b:
            #we set middle weigh 0.5 upper than its top
            $query = "
                UPDATE `$table` m, `$table` t
                SET m.`weight` = t.`weight`+0.5
                WHERE m.`id` = $m
                AND t.`id` = $t
            ";
            break;
        #values are not empty, so the row is droped in the middle part
        default:
            #we set middle weigh exactly between top and bottom
            $query = "
                UPDATE `$table` m, `$table` t, `$table` b
                SET m.`weight` = (t.`weight`+b.`weight`)/2
                WHERE m.`id` = $m
                AND t.`id` = $t
                AND b.`id` = $b
            ";
            break;
    }
    Yii::app()->db->createCommand($query)->query();

Even after 45 times of dividing 1 to 2, float value will not drop to zero, so I this solution is a remedy right now! 即使经过45次除1到2次,浮点值也不会降到零,所以我这个解决方案现在就是一个补救措施!

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

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