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

Database design 维护数据库表行的排序顺序,database-design,Database Design,假设我有一个包含每行新闻文章信息的数据库表。该表有一个整数“sort”列,用于指定文章在网站上的显示顺序。如何最好地实施和维护此排序顺序 我想避免的问题是文章编号为1,2,3,4,…,100,当文章编号50突然变得有趣时,它将其排序编号设置为1,然后它们之间的所有文章的排序编号都必须增加1 当然,将初始排序编号设置为100200300400等会留下一些移动空间,但在某个点上会中断 有没有一种正确的方法,或者完全不同的方法 新增-1: 所有文章标题都显示在链接到内容的列表中,因此所有排序的项目都

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

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

当然,将初始排序编号设置为100200300400等会留下一些移动空间,但在某个点上会中断

有没有一种正确的方法,或者完全不同的方法


新增-1:

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

新增-2:


项目不一定会移到列表的顶部;任何项目都可以放置在已排序列表中的任何位置。

使用降序排序,即最高排序编号显示在顶部

如果一篇旧文章应该放在列表的顶部,只需将其排序列设置为MAX(Sort)+1即可。不需要把整张桌子重新编号

评论后更新


将排序顺序更改为浮点。如果在其他两个项目之间重新排列项目的排序顺序,则新的排序值将设置为((上一个项目的排序)+(下一个项目的排序))/2。否则,如果我正确理解您的问题,请将Sort设置为MAX+1。

;我会使用一个列,其中包含某种类型的排名索引号。这个数字不必是唯一的。您需要想出某种类型的算法来计算排名

然后只需在排名列上排序,第二列处理排名关系(可能是创建日期或其他)

我想避免的问题是 文章编号了 1,2,3,4,100

我建议您不要尝试将排序键作为主键或唯一键。如果它们的键不唯一,则可以有多个具有相同值的项。您可能希望简单地将排序键设置为一个简单的1-10刻度

所以也许10级的事情会非常有趣,5级是正常的,1级是非常无聊的。当某件事情变得无聊或更有趣时,只需将排序键的值向下或向上调整即可。

忘记更正--您希望避免的问题不是什么大问题,而是取决于您的RDBMS的几个更新语句(我假设Oracle和您将文章移到列表的“上”):

最大的警告是集合功能在所有RDBMS中的工作方式不同

如果你真的想考虑正确,考虑重新考虑数据结构方面的问题——你可能要问的是如何在数据库中实现链表。 维护排序号列的另一种方法是维护父ID列。这可能更正确,因为它保留了数据的序列化,但缺点是查询数据不美观或效率不高(例如,想想Oracle中的CONNECT BY)


如果问题是最好的,也许你想考虑两个正确的父ID列,通过导出排序号列的值,可能是从父ID数据或从第一个解决方案中去数据化。

< P>。然后使用存储的进程移动项目。该过程包含两个参数,即项的当前索引和要将其移动到的新索引。它执行一个更新项目集index=index+符号(@newidx-@oldidx),其中itemMax(@newidx,@oldidx)和itemMin(@newidx,@oldidx)之间的索引来更新中间的项目,然后执行一个将实际项目更改为新索引的更新。这不是实际的代码,只是来自内存。在我们的表中,我们有两列,id和索引,因此即使在某一点上,您在同一索引中有两个项目,我们也可以通过id来区分它们。这可以通过更新要移动到的项目和索引-1来避免,然后更新其余部分,最后将-1处的新项移动到新索引。

我同意大多数人所说的答案,即表中应该有一个单独的列,其中包含记录的排序/兴趣值。如果您想在保持健壮性的同时考虑某种时间参数,您可能需要尝试在给定的时间段内合并一个数据“视图”

也就是说,每晚午夜,您创建主表的表视图,但仅使用过去2或3天的文章创建,然后严格维护该表上的排序/利息计数。如果有人选择了不在该表中的旧文章(比如一周前的文章),您可以随时将其插入当前视图。这样你就可以得到年龄的影响


整个要点是在表上保持较小的索引,其中排序/兴趣值的插入和更新应该保持相对较快的速度。在视图创建过程中,您只需提前支付一次复杂连接的费用,然后就可以将其保持平坦以优化过度读取。你能看到的最大值是多少,几百,几千?比每次有人提出请求时尝试对十万个进行排序要好。

根据链表数据结构对表进行建模。去掉“sort”列,而是有一个next_article_id列,它指向它后面的下一篇文章。然后,当你想在第50位添加一篇新文章时,你只需更新文章49以指向你的新文章,然后将你的新文章指向先前指向的那篇文章。

使用实数似乎是计算效率最高的选择。你可以
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;
Do nothing
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 = sort_number - 1
WHERE sort_number BETWEEN :current_sort_number + 1 and :new_sort_number;
UPDATE Articles
SET sort_number = :new_sort_number
WHERE article_id = :article_id;