维护数据库表行的排序顺序

11 database-design

假设我在数据库表中包含有关每行中新闻文章的信息.该表有一个整数"排序"列,用于指定文章在网站上的显示顺序.如何最好地实施和维护此排序顺序.

我想避免的问题是编号为1,2,3,4,...,100的文章,当文章编号50突然变得有趣时,它的排序编号设置为1,然后它们之间的所有文章必须有它们的排序数量增加了一个.

当然,将初始排序数设置为100,200,300,400等会留下一些移动空间,但在某些时候它会破裂.

有没有正确的方法来做到这一点,也许是一种完全不同的方法?


添加-1:

所有文章标题都显示在链接到内容的列表中,因此所有排序的项目都会立即显示.

添加-2:

项目不一定移动到列表的顶部; 任何项目都可以放在有序列表中的任何位置.

Alk*_*ini 10

忘记正确 - 你要避免的问题不是什么大问题,而是只需要几个UPDATE语句,具体取决于你的RDBMS(我假设是甲骨文,而你正在将文章"移到"列表中):

UPDATE Articles
SET sort_number = sort_number + 1
WHERE sort_number BETWEEN :new_sort_number and :current_sort_number - 1;

UPDATE Articles
SET sort_number = :new_sort_number
WHERE article_id = :article_id;
Run Code Online (Sandbox Code Playgroud)

最大的警告是SET功能在所有RDBMS中都不起作用.

如果您真的想要考虑正确,请考虑根据数据结构重新思考问题 - 您可能会问的是如何在数据库中实现链表.

维护排序号列的另一种方法是维护父ID列.这可以说是更正确的,因为它保留了数据的序列化,但缺点是查询数据不是很好或不高效(例如,想想Oracle中的CONNECT BY).

相反,如果问题是最好的,也许你想要考虑父ID列的正确性,并通过从父ID数据或第一个解决方案中获取排序编号列的值对数据进行非规范化.


Joh*_*yre 8

如果我理解你的问题; 我会使用包含某种类型的排名索引号的列.这个数字不一定是唯一的.您需要提出某种算法来计算排名.

然后只需对排名列进行排序,使用辅助列来处理排名关系(可能是创建日期或其他内容).


小智 6

这很简单。您需要有一个“订单栏”。

要使用此方法,您至少需要有 2 列:

  1. id - 32 位 int
  2. orderValue - 64 位bigint (bigint,不是 double !!!)

插入/更新

  1. 当您插入第一条新记录时,您必须
    set orderValue = round(max_bigint / 2)

  2. 如果插入属于列表开头的行,则必须
    set orderValue = round("orderValue of previously inserted record" / 2)

  3. 如果插入属于列表末尾的行,则必须
    set orderValue = round("max_bigint + orderValue of final record" / 2)

  4. 如果您插入其他任何地方,则必须
    set orderValue = round("orderValue of record before + orderValue of record after" / 2)

此方法具有非常大的最大列表大小。如果您遇到约束错误,或者您认为您将无法解决问题,您可以随时重建 orderValue 列(标准化)。

如果您使用规范化来持续组织 orderValue 列,您可能可以使用 32 位 int。

它非常简单和快速!

记住 -不要使用双打!!!只有整数 - orderValue 列需要非常高的精度!


小智 5

在链表数据结构之后为表建模.摆脱"排序"列,而是有一个next_article_id列,指向后面的下一篇文章.然后,当您想要在第50位添加新文章时,您只需更新文章#49以指向您的新文章,然后将您的新文章指向之前指向的第49条文章.

  • 请给我一个SELECT查询,我可以使用它来获取所有文章,正确排序 (6认同)