Sql server 在两个连续行之间插入记录的最佳方法是什么?
我有一个简单的顺序表,如:Sql server 在两个连续行之间插入记录的最佳方法是什么?,sql-server,database,Sql Server,Database,我有一个简单的顺序表,如: ID | Name | Rank =======+======+===== 327 | Ali | 1 -------+------+----- 846 | Sara | 2 -------+------+----- 657 | Dani | 3 -------+------+----- ... ID是主键和索引,Rank也被索引。我有几条这样的记录,我想要的是在SQL Server中的这个表的记录之间插入一条记录,这样
ID | Name | Rank
=======+======+=====
327 | Ali | 1
-------+------+-----
846 | Sara | 2
-------+------+-----
657 | Dani | 3
-------+------+-----
...
ID
是主键和索引,Rank
也被索引。我有几条这样的记录,我想要的是在SQL Server
中的这个表的记录之间插入一条记录,这样可以在不破坏排名的情况下保持其序列
例如,我将Sahar
by插入排名为2的上表,这会导致更大的排名移动,因此:
ID | Name | Rank
=======+======+=====
327 | Ali | 1
-------+------+-----
196 | Sahar| 2 ----> Inserted
-------+------+-----
846 | Sara | 3
-------+------+-----
657 | Dani | 4
-------+------+-----
...
我已经搜索并找到了一些解决方案,例如:
UPDATE TABLE table SET Rank += 1 WHERE Rank >= 2;
INSERT INTO TABLE (Rank, ...) VALUES (2, ...);
在这种情况下,也可以采用另一种方法。我还找到了一些其他的答案,但所有这些答案都要付出沉重的代价
另外,我可能需要更改一些等级
或交换两个等级
so
另一方面,我必须在UPDATE
、Delete
和Insert
触发器中执行此操作,或者您推荐的其他操作
是否有诸如标识(1,1)
或其他内置的机制
SQL Server中的服务
哪个旨在解决此问题
谢谢。如果您的表中有
N
行的Rank
从1
到N
,并且您插入了Rank=2
的新行,那么您必须更新N-2
行中的值(即更改)。您必须对表写入大量更改。恐怕没有什么神奇的方法可以加快速度
如果您确实需要更新排名
,也就是说
但是,也许你不需要把列为一个没有空格的整数
排名的真正目的是定义特定的行顺序。要定义顺序,您需要知道每行后面是哪一行。因此,当用户说他想添加Sahar
排名2
时,实际上意味着Sahar
应该在Ali
之后,但在Sara
之前,所以新行的排名可以设置为,比如说,(1+2)/2=1.5
这样,如果您生成<代码> Reals一个浮点,您就可以在表中间插入新行,而不改变所有行的<代码>秩< /代码>的值。< /P>
如果要将
Rank
作为一个不带空格的整数序列呈现给用户,请使用以下方法:
ROW_NUMBER() OVER(ORDER BY FloatRank) AS IntegerRankWithoutGaps
此外,如果删除一行,也不需要更新表中的所有行。持久化的FloatRank
值将有一个间隙,但当应用行编号时,该间隙将消失
从技术上讲,您不能无限期地将8字节浮点间隔一分为二,因此您应该偶尔运行一个维护过程,以“规范化”浮点列并更新表中的所有行。但是,至少在系统负载最小的情况下,这个代价高昂的过程可能不会经常运行
此外,您可以从浮点值开始,而不是从1
,而是从更远的距离开始。例如,与从1000、2000、3000、4000、
开始的1、2、3、4…
不同,最简单和透明的方法是添加列,在其中定义表中的行序列,然后在该列上创建聚集索引。此索引将保留您想要的数据 你的排名是否基于其他因素,允许你重新计算?如果没有,你可能只需要做一个更新。不知道触发器在这方面有什么帮助。@JamesZ,没有。等级的概念是完全唯一的,它只取决于一个人,没有任何其他数据可以从中产生等级。更新应该在触发器中,因为我希望能够保证序列或排名。我投票给你的答案是因为减少了删除(以及任何操纵)操作成本。总之,您的方法的主要优点是数据操作成本较低。但由于秩规范化(第一个问题),它会导致数据读取成本增加。如果我们不正常化,那么排名可能会有差距,在我们的UI阶段(第二个问题)会很糟糕。无论如何,我会接受你的答案,但可能需要一些时间等待,以获得更好的答案!谢谢。在一般情况下,在插入和删除数据时,维护没有间隙的排名编号可能会非常昂贵,因为您必须确保没有两个不同的事务同时更新表。使用ROW\u NUMBER
是一种折衷方法,但它应该相对便宜,尤其是在基础列上有索引的情况下。如果有索引,ROW\u NUMBER
将不必进行排序。实际上,这取决于插入/删除/更新和读取的频率。如果插入次数很少,但读取次数较多,则最好在插入数据时重新计算并更新列组。您无法降低重新计算的成本,但有可能延迟支付此费用。欢迎您提出建议!:),这似乎是个好主意,但我需要了解有关您的解决方案的更多详细信息。您需要什么样的详细信息?我的意思是,您将我在问题中解释的排名保存在哪里?你如何处理这些差距?您如何声称您的方法在插入数据和读取数据方面具有更好的性能,即被授权人在没有任何间隙的情况下保持排名顺序?让我们将两个术语分开:表中的顺序和行排名。我认为您必须存储行序列/位置,而不是秩,并动态计算秩。如果您在插入/删除过程中计算排名,您的进程将在某一天因性能原因停止。RDBMS不适合这种操作。”RDBMS
不适合