最有效的订购后数据库设计

Ara*_*avi 4 mysql database-design design-pattern

我有 post_order 列的帖子表。我将每个帖子的顺序存储在其中。当我将一行的顺序从 25 更改为 15 时,我应该将所有行从 15 更新到结尾。它适用于几行,但在数千行中最糟糕。

有没有更好的订购帖子的设计,更有效?

Mik*_*son 6

您可以将post_order列更改为 afloat并使用post_order您想要结束的帖子中的值进行计算来更新值。

例子:

PostID, PostOrder
1       1
2       2
3       3
Run Code Online (Sandbox Code Playgroud)

如果您想将 PostID = 3 移动到 1 和 2 之间进行排序,那就是

PostID, PostOrder
1       1
3       1.5
2       2
Run Code Online (Sandbox Code Playgroud)

这是一个带有一些代码的 SQL Fiddle,它使用存储过程移动帖子,您可以在其中传递PostID要移动PostID的帖子和您想要落后的帖子。

SQL小提琴

MySQL 5.5.30 架构设置

create table Post
(
  PostID int primary key,
  PostOrder float unsigned not null unique,
  check (PostOrder > 0)
);

insert into Post(PostID,  PostOrder) values (1, 1);
insert into Post(PostID,  PostOrder) values (2, 2);
insert into Post(PostID,  PostOrder) values (3, 3);
insert into Post(PostID,  PostOrder) values (4, 4);
insert into Post(PostID,  PostOrder) values (5, 5);
insert into Post(PostID,  PostOrder) values (6, 6);
insert into Post(PostID,  PostOrder) values (7, 7);
insert into Post(PostID,  PostOrder) values (8, 8);
insert into Post(PostID,  PostOrder) values (9, 9);
insert into Post(PostID,  PostOrder) values (10, 10);

//

create procedure MovePost(MovePostID int, AfterPostID int)
begin

  declare AfterPostOrder float;
  declare NextPostOrder float; 


  set AfterPostOrder = (select PostOrder 
                        from Post
                        where PostID = AfterPostID);

  if AfterPostOrder is null then
    -- Move first
    set AfterPostOrder = 0;
  end if;

  set NextPostOrder = (select min(PostOrder) 
                       from Post 
                       where PostOrder > AfterPostOrder);

  if NextPostOrder is null then
    -- Move last
    set NextPostOrder = (select max(PostOrder) + 2
                         from Post);
  end if;


  update Post
  set PostOrder = (AfterPostOrder + NextPostOrder) / 2
  where PostID = MovePostID;


end
Run Code Online (Sandbox Code Playgroud)

查询 1

call MovePost (7, 3);    -- Move 7 after 3
call MovePost (8, 3);    -- Move 8 after 3
call MovePost (9, null); -- Move 9 first
call MovePost (2, 10);   -- Move 2 after 10

select * 
from Post
order by PostOrder
Run Code Online (Sandbox Code Playgroud)

结果

| POSTID | POSTORDER |
----------------------
|      9 |       0.5 |
|      1 |         1 |
|      3 |         3 |
|      8 |      3.25 |
|      7 |       3.5 |
|      4 |         4 |
|      5 |         5 |
|      6 |         6 |
|     10 |        10 |
|      2 |        11 |
Run Code Online (Sandbox Code Playgroud)