繁体   English   中英

根据ID列表对记录进行特定排序? 与MySQL和PHP

[英]Specific ordering of records based on list of IDs? with MySQL & PHP

我在MySQL中有一个“用户”表

当用户登录到我的应用程序时,他们可以看到所有其他用户的列表,并且可以通过某些javascript-drag-drop来安排其他用户出现的顺序。我们要保存该顺序。

并将其保存到他们的记录中(即'order_pref'= 4,3,5,23 ...按照指定顺序排列的user_ids列表)。

所以这很好,但是涉及显示时。我是否有一种简单的方法就可以仅使用一个查询基于该逗号分隔的user_ids列表进行排序?

您不能使用MySQL。 可以想象,您可以使用PHP,但这不是对这个问题建模的最佳方法。

您应该分配一个订单号,然后按该号码排序,而不是以固定的顺序存储ID。 假设:

  • 登录的用户是302
  • 用户ID的列表是11,432,788,343

您存储:

UserID  OrderNum  UserDisplay
 302      100       11
 302      200      432
 302      300      788
 302      400      343

然后问题变成了:

SELECT UserDisplay
FROM UserOrder
WHERE UserID = 302
ORDER BY OrderNum

简单得多 现在,更改订单需要更新OrderNum字段。 这就是为什么我不执行1的步骤,而是执行100的步骤,因此,如果要将343移至第二位,只需将OrderNum设置为150。您可能需要做大得多的间隔(例如1000000),并且可能需要偶尔重新编号这些值。

有几种方法可以做到这一点,最好的情况是使用第二张表来进行特定于用户的排序。 将单个列添加到“用户”表将不起作用,因为大概每个用户都有自己的顺序。

根据应用程序的规模和复杂性,您可以使用单个表(更易于管理,但对于数百万个用户而言则更慢)来完成此操作,或者为每个用户创建表(可扩展性更高)。 在以下示例中,当前用户为用户#2,顺序为4,3,5,23。

create table if not exists user_ordering (
  owner_id integer unsigned not null,
  user_id integer unsigned not null,
  order_index integer not null default '0',
  unique owner_user (user_id,owner_id),
  index owner_idx (owner_id,order_index)
) ENGINE=MyISAM;

要保存订单,请依次插入:

INSERT INTO user_ordering (owner_id,user_id,order_index) VALUES (2,4,0);
INSERT INTO user_ordering (owner_id,user_id,order_index) VALUES (2,3,1);
INSERT INTO user_ordering (owner_id,user_id,order_index) VALUES (2,5,2);
INSERT INTO user_ordering (owner_id,user_id,order_index) VALUES (2,23,3);

要选择,只需加入并为不在列表中的用户使用“默认”排序:

SELECT U.* FROM user U
LEFT OUTER JOIN user_ordering G ON U.id=G.user_id AND G.owner_id=2
ORDER BY G.order_index,U.name;

如果您想节省时间,则可以使用具有自动递增功能的双主键来使增量发生在“逐个所有者”的基础上,例如

create table if not exists user_ordering (
  owner_id integer unsigned not null,
  user_id integer unsigned not null,
  order_index integer not null AUTO_INCREMENT,
  unique owner_user (user_id,owner_id),
  PRIMARY KEY (owner_id,order_index)
) ENGINE=MyISAM;

如果获得要更新的列表,则可以执行快速操作:

DELETE FROM user_ordering WHERE owner_id=2;
INSERT INTO user_ordering (owner_id,user_id) VALUES (2,4);
INSERT INTO user_ordering (owner_id,user_id) VALUES (2,3);
INSERT INTO user_ordering (owner_id,user_id) VALUES (2,5);
INSERT INTO user_ordering (owner_id,user_id) VALUES (2,23);

您甚至可以使用多插入版本:

DELETE FROM user_ordering WHERE owner_id=2;
INSERT INTO user_ordering (owner_id,user_id) VALUES (2,4),(2,3),(2,5),(2,23);

对于大型数据库,最好为每个用户创建一个表,例如:

create table if not exists user_ordering_2 (
  user_id integer unsigned not null,
  order_index integer not null AUTO_INCREMENT,
  unique owner_user (user_id),
  PRIMARY KEY (order_index)
) ENGINE=MyISAM;

这就需要使用一些更高级的工具来使您的模式保持最新,但是它将更好地扩展。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM