简体   繁体   English

在 SQL 中存储排序顺序的最佳方法是什么?

[英]What's the best way to store sort order in SQL?

The guys at the top want sort order to be customizable in our app.顶部的人希望在我们的应用程序中可以自定义排序顺序。 So I have a table that effectively defines the data type.所以我有一个有效定义数据类型的表。 What is the best way to store our sort order.存储排序顺序的最佳方式是什么。 If I just created a new column called 'Order' or something, every time I updated the order of one row I imagine I would have to update the order of every row to ensure posterity.如果我刚刚创建了一个名为“Order”之类的新列,那么每次我更新一行的顺序时,我想我都必须更新每一行的顺序以确保后代。 Is there a better way to do it?有更好的方法吗?

None of the answers so far have touched on the real problem with custom sort order and that is what happens when two different people want the same records sorted differently. 到目前为止,没有一个答案涉及自定义排序顺序的真正问题,当两个不同的人希望相同的记录排序不同时会发生这种情况。

If you need a custom sort order, you need a related table to store it in, not an additional field. 如果您需要自定义排序顺序,则需要一个相关表来存储它,而不是其他字段。 The table would have the userid, the recordId of the data and the sort order for the record. 该表将具有userid,数据的recordId和记录的排序顺序。 That way Joe Smith can have one order and Sally Jones another for the same data. 这样,Joe Smith可以拥有一个订单而Sally Jones可以获得相同的数据。 Now you have the problem of new records being added to the data set. 现在您遇到了将新记录添加到数据集的问题。 Do you put them at the beginning of the sort order or the end or do you require the person to set an order for them before they can be added to the set. 您是将它们放在排序顺序的开头还是结尾处,或者您是否需要此人为它们设置订单才能将它们添加到集合中。 This is in actuality a very complex problem that is generally not worth the amount of time it takes to implement because almost no one ever uses that system once it's in place (I mean do I really want to go through a hundred records and mark the individual order of each one?). 这实际上是一个非常复杂的问题,通常不值得花时间来实现,因为几乎没有人使用该系统一旦到位(我的意思是我真的想要通过一百条记录并标记个人每个人的顺序?)。 Now it gets complicated in terms of saving the order of all the records (which will of course require changes the next time the query is run since there will be new records.) This is very painful process of limited untility. 现在它在保存所有记录的顺序方面变得复杂(当然,在下次运行查询时需要更改,因为会有新的记录。)这是一个非常痛苦的有限直到过程。

I did this once in a proposal writing application because we needed to be able to sort the parts and tasks on the proposal in the order we thought would be most impressive to the customer. 我在提案编写应用程序中做了一次,因为我们需要能够按照我们认为对客户最令人印象深刻的顺序对提案中的部件和任务进行排序。 Even then, we had to institute a default order, so that they only need to move around the two or three things they really wanted to show up first instead of ordering 10,000 individual parts. 即便如此,我们还是要制定一个默认订单,这样他们只需要先移动他们真正想要出现的两三件事,而不是订购10,000件零件。

A better choice if you can get them to buy off on it, is to allow them to sort the data by columns (desc or asc). 一个更好的选择,如果你可以让他们买它,是允许他们按列(desc或asc)对数据进行排序。 Usually the user interface can be designed so that if you click on a column header, it will resort the data by that column. 通常可以设计用户界面,以便在单击列标题时,它将按该列求助数据。 This is relatively straightforward to do and meets most needs for custom ordering. 这样做相对简单,满足了定制订购的大多数需求。

You really need to discuss this requirement with management and get details of how they want it to work beyond, I want custom ordering. 你真的需要与管理层讨论这个要求,并获得他们希望如何工作的详细信息,我想要定制订购。 This is often one of those things people think they want, but don't really use. 这通常是人们认为他们想要的东西之一,但并没有真正使用。

The basic algorithm might be like one described below. 基本算法可能如下所述。 Initially the sort field varies from item to item by 1000 (you may consider another interval). 最初,排序字段因项目而异1000(您可以考虑另一个间隔)。 The items in the table are in ordered state just for the sake of simplicity. 为简单起见,表中的项目处于有序状态。 Btw, I've create Yii2 component to manage this stuff. 顺便说一下,我创建了Yii2组件来管理这些东西。 And this one if you need a sortable tree sortable tree . 如果你需要一个可排序的树可排序树,那么这个

id | sort
---+-----
1  | 1000
---+-----
2  | 2000
---+-----
3  | 3000
---+-----

Lets imagine we are going to add an item (id 4) after id 1: 让我们想象一下我们将在id 1之后添加一个项目(id 4):

id | sort
---+-----
1  | 1000
---+-----
4  | 1500
---+-----
2  | 2000
---+-----
3  | 3000
---+-----

So to calculate sort value for id 4 we took the sort value of the item before, which is 1000 and the item after - 2000 and took the mean. 因此,为了计算id 4的排序值,我们采用了之前项目的排序值,即1000和2000之后的项目并取平均值。 If you get a float, just round it to the nearest integer. 如果你得到一个浮点数,只需将它四舍五入到最接近的整数。 If you need to insert an item at the beginning of the list, then you take a mean of (1000 and 0, which is 500). 如果您需要在列表的开头插入一个项目,则取平均值(1000和0,即500)。

Now, if we need to insert an item (id 5) after id 1, we do the same: 现在,如果我们需要在id 1之后插入一个项目(id 5),我们也会这样做:

id | sort
---+-----
1  | 1000
---+-----
5  | 1250
---+-----
4  | 1500
---+-----
2  | 2000
---+-----
3  | 3000
---+-----

Later on, you might face to this scenario: 稍后,您可能面临这种情况:

id | sort
---+-----
1  | 1000
---+-----
15 | 1001
---+-----
...
---+-----
5  | 1250
---+-----
...
---+-----

So if you need to insert an item (id 16) between 1 and 15, first you should increment sort field by 1000 of all items followed by 1: 因此,如果您需要在1到15之间插入一个项目(ID 16),首先应该将排序字段增加1000个所有项目后跟1:

id | sort
---+-----
1  | 1000
---+-----
15 | 2001
---+-----
...
---+-----
5  | 2250
---+-----
...
---+-----

Now you can insert the item (id 16): 现在您可以插入项目(ID 16):

id | sort
---+-----
1  | 1000
---+-----
16 | 1501
---+-----
15 | 2001
---+-----
...
---+-----
5  | 2250
---+-----
...
---+-----

Use an int field. 使用int字段。 When you update the sort order of one row, you only have to update the field on the row you're updating and any rows between the row's old and new positions. 更新一行的排序顺序时,只需更新要更新的行上的字段以及行的旧位置和新位置之间的任何行。 This means that swapping two rows only involves touching those two rows. 这意味着仅交换两行涉及触摸这两行。 Also, for rows you're updating that aren't your "active" row, you only need to increment or decrement the field; 此外,对于您正在更新的不是“活动”行的行,您只需要递增或递减该字段; the queries are easy to write. 查询很容易编写。

您可以使用浮点数,只要您具有足够的精度,您始终只需将移动记录的序号列设置为两侧记录之间的中点即可。

Generally the application would add the approriate ORDER BY clause to the query. 通常,应用程序会将approriate ORDER BY子句添加到查询中。 If the result sets to be sorted are relatively small you can have keys on the selection criteria. 如果要排序的结果集相对较小,则可以在选择条件上使用键。 Even with large results it is often better to sort the selected data than retrieve in order by index. 即使有大的结果,通常最好对所选数据进行排序,而不是按索引按顺序检索。

If the requirement is to have orders like BAZTQMK, then you will need a column to place the relative order into. 如果要求是拥有像BAZTQMK这样的订单,那么您需要一个列来放置相对订单。 The appropriate value would need to be determined each time you add a row. 每次添加行时都需要确定适当的值。 However, this works well for code tables which are relatively static. 但是,这适用于相对静态的代码表。

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

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