【问题标题】:Insert record into table with position without updating all the records position field将记录插入具有位置的表而不更新所有记录位置字段
【发布时间】:2012-05-15 05:05:13
【问题描述】:

我正在使用 MySQL,我没有很好的方法来做到这一点。

我有一个位置为field 的表,我需要跟踪它的值从 1 到 10,000。

假设我在中间的第 5000 个位置插入一条记录。所以位置5000到10000需要更新到新位置;老5000变成5001,5002变成5003……

当添加 1 个单个位置时,有没有一种好方法可以在不影响这么多记录的情况下实现这一点?

从第一个位置添加是最糟糕的。

【问题讨论】:

  • 仅供参考,这是一个糟糕的数据库设计。
  • 是的,同意。你会怎么做?
  • 不确定您的最终目标是什么,我在下面的答案中添加了一个假设示例。

标签: mysql algorithm


【解决方案1】:

我会重新考虑数据库设计。如果您将被限制在 10K 记录的数量级上,那还不错,但如果这将无限增加,那么您将想做其他事情。我不确定你在做什么,但如果你想要一个简单的排序(假设你没有做很多遍历),那么你可以有一个 prev_idnext_id 列来指示兄弟关系。不过,这里是您问题的答案:

update some_table 
set some_position = some_position + 1
where some_position > 5000 and some_position < 10000

【讨论】:

  • 我喜欢这种订单管理的 prev_id 、 next_id 设计。谢谢@Abdullah
  • @AbdullahJibaly 只是好奇,使用 next/prev id,在选择数据时它是如何工作的,按什么排序???
  • @Abdullah-Jibaly 谢谢。我也喜欢下一个/上一个 id,同样的问题,我们如何选择数据?
  • @Maulik Vora 我在这里找到了一些答案。 stackoverflow.com/questions/675117/…
【解决方案2】:
You can try the below approach :

USE tempdb;
GO

CREATE TABLE dbo.Test
(
ID int primary key clustered identity(1,1) ,
OrderNo int, 
CreatedDate datetime
);

--Insert values for testing the approach
INSERT INTO dbo.Test 
VALUES
(1, GETUTCDATE()),
(2, GETUTCDATE()),
(3, GETUTCDATE()),
(4, GETUTCDATE()),
(5, GETUTCDATE()),
(6, GETUTCDATE());

SELECT * 
FROM dbo.Test;

INSERT INTO dbo.Test 
VALUES
(3, GETUTCDATE()),
(3, GETUTCDATE());


SELECT * 
FROM dbo.Test;


--To accomplish correct order using ROW_NUMBER()
  SELECT ID, 
  OrderNo, 
  CreatedDate, 
  ROW_NUMBER() OVER(ORDER BY OrderNo, ID) AS Rno
  FROM dbo.Test;


--Again ordering change
  INSERT INTO dbo.Test 
VALUES
(3, GETUTCDATE()),
(4, GETUTCDATE());

  SELECT ID, 
  OrderNo, 
  CreatedDate, 
  ROW_NUMBER() OVER(ORDER BY OrderNo, ID) AS Rno
  FROM dbo.Test


   DROP TABLE dbo.Test;

【讨论】:

    猜你喜欢
    • 2014-12-16
    • 2015-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多