簡體   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