我刚刚阅读了一篇关于用户定义结果集排序的有趣博客文章。
一些应用程序,例如待办事项列表,需要维护用户定义的项目顺序。挑战在于顺序是任意的,并且可以在用户重新排列项目时更改
一个示例表可能是这样的:
create table items
(
itemid int primary key,
itemdata varchar(200),
...
...
userorder ???
);
使用可能的检索查询:
select * from items order by userorder asc;
鉴于我想将更新保持在最低限度,更新原子和检索查询尽可能简单和“高性能”,是否有任何方法可以考虑?
我最初的想法是使用一个额外的TIMESTAMP
列,并且只更新单行userorder
的值(检索查询使用ing by ),但是当您需要在具有相同值的其他两行之间移动一行时,这会失败.timestamp
ORDER
userorder asc, usertimestamp desc
没有考虑特定的数据库,因为我自己使用的范围很广。
我认为这是该博客文章中“真分数”方法的一种深奥变体——优点是不需要引入用户定义的类型(至少如果您使用的是 Postgres)。
这使用了自然排序属性
varbit
并将它们的序列映射到二叉树上,以便始终可以varbit
在任何两个现有相邻值之间生成另一个值:dbfiddle在这里
如果您最初加载大量有序行,您可能希望使用其他算法来生成初始
userorder
值,因为您将遇到空间使用的最坏情况(每行将比前一行多使用一位userorder
)。对于足够多的位,您可以逐步遍历相同长度的值(例如,对于 8 个值:B'0001'
、B'0011'
、B'0101'
、B'0111'
、B'1001'
、B'1011'
、B'1101'
、B'1111'
)。介绍
一些非常古老的 BASIC 语言要求每一行代码都有一个行号。
编程时,行号通常以 10 的倍数间隔。这使您可以在以后的行之间添加更多代码。
您的
items
表应遵循相同的概念。基本算法
userorder
10 开始userid
userorder
根据需要更新应用程序userorder
使用 Analyticscommit
数据变化。重枚举代码
这基本上是我用过的:
我假设此表包含每个人的 TODO 列表,并且每个用户都由
userid
.此示例使用
ROW_NUMBER()
来自 Oracle。您必须将它替换为您正在使用的任何 RDBMS。