【问题标题】:how to maintain sort order cost effectively in database如何在数据库中有效地维护排序顺序
【发布时间】:2015-03-26 19:32:41
【问题描述】:

特定供应商的这种产品排序顺序存储在一个表中。

例如:

ITEM_ID SORT_ORDER
100         1
101         2
105         3
106         4
108         5

等等……

现在,如果供应商想要在其网页的第 5 位显示第一个产品 (100),他可以在最后执行此操作,为了显示他想要的结果,我们需要更改下表中的排序值,如下所示。

所有项目的新排序顺序值被更新,新表采用如下形式:

ITEM_ID SORT_ORDER
100         5
101         1
105         2
106         3
108         4

等等……

据观察,要更改 1 个产品的排序顺序,我们必须为该特定供应商更新此表的所有行。 这是一项昂贵的工作。

我们正在寻找解决这个问题的方法,以最优化和最具成本效益的方法维护该供应商的产品排序顺序。

以任何其他方式保持排序顺序的任何替代解决方案

【问题讨论】:

  • “代价高昂的练习”来更新几行?您的典型供应商有多少物品?
  • @JeffreyKemp 在最坏情况下大约缺少 1 个,平均情况下 1000+
  • 缺少?无论如何,如果你的平均数是 1000,那就太小了。
  • 主要问题是当 1 个缺货供应商在他们的订单中做了小的改动(假设每个供应商有 1000 件产品),那么我们需要更新 1 个缺货* 1000,这是非常糟糕的。
  • 10 万 = 10 万 source=en.wikipedia.org/wiki/Lakh

标签: database oracle oracle11g


【解决方案1】:

据观察,要更改 1 个产品的排序顺序,我们必须为该特定供应商更新此表的所有行。这是一项昂贵的工作。

嗯,是的,您需要更新所有行,但是,只需两步即可完成。在纯 SQL 中使用两个 UPDATE 语句

测试用例:

SQL> CREATE TABLE t
  2      (ITEM_ID int, SORT_ORDER int);

Table created.

SQL>
SQL> INSERT ALL
  2      INTO t (ITEM_ID, SORT_ORDER)
  3           VALUES (100, 1)
  4      INTO t (ITEM_ID, SORT_ORDER)
  5           VALUES (101, 2)
  6      INTO t (ITEM_ID, SORT_ORDER)
  7           VALUES (105, 3)
  8      INTO t (ITEM_ID, SORT_ORDER)
  9           VALUES (106, 4)
 10      INTO t (ITEM_ID, SORT_ORDER)
 11           VALUES (108, 5)
 12  SELECT * FROM dual;

5 rows created.

SQL>
SQL> COMMIT;

Commit complete.

SQL>

现在,第一次更新是为了将 ITEM_ID 100 设置为 SORT_ORDER 5

SQL> UPDATE t SET sort_order = 5 WHERE item_id = 100;

1 row updated.

SQL> SELECT * FROM t;

   ITEM_ID SORT_ORDER
---------- ----------
       100          5
       101          2
       105          3
       106          4
       108          5

SQL>

现在,第二次更新是为所有other ITEM_IDs设置为SORT_ORDER -1

SQL> UPDATE t SET sort_order = sort_order - 1
  2  WHERE item_id <> 100;

4 rows updated.

SQL>
SQL> SELECT * FROM t;

   ITEM_ID SORT_ORDER
---------- ----------
       100          5
       101          1
       105          2
       106          3
       108          4

SQL>

因此,只需两个更新语句即可完成任务。

更新根据 Jeffrey 在下面的评论,可以使用 CASE 语句在单个更新语句中完成。

例如,

UPDATE t
SET    sort_order = CASE item_id
                      WHEN 100 THEN 5
                      ELSE sort_order - 1
                    END;  

如果sort_order 列上有任何唯一约束,那么与我之前使用两个更新语句的演示相比,这种方法更好。

【讨论】:

  • 只有一个更新语句会更简单,例如:update t set sort_order = case item_id when 100 then 5 else sort_order - 1 end - 而且,这将避免违反表的唯一约束(如果存在)。
  • 但问题是它不能解决问题,即每个表更新的行数
【解决方案2】:

更好的解决方案是给出一个它们之间有很大差异的值,然后我们只需要更新一个值 例如。

ID SORT_ORDER 100 500 102 1000 103 1500 104 2000 如果我们改变顺序,我们只需要更新一行

ID SORT_ORDER 104 250 100 500 102 1000 103 1500

但我们需要跟踪可以执行的有效操作的数量,如果找不到更多可能性,则需要重置数据。

【讨论】:

  • 在排序顺序列中允许浮点数可能是个好主意,这样您就可以继续除以二,直到精度用完。
【解决方案3】:

据观察,为了更改 1 个产品的排序顺序,我们必须为该特定供应商更新此表的所有行。这是一项昂贵的工作。

您可以对前端进程中的所有项目进行排序,并将所有以逗号分隔的ITEM_ID 排序并在单个UPDATE 语句中将其保存在数据库中(使用Primary Key)。

【讨论】:

  • 更好的解决方案是给出一个它们之间差异很大的值,然后我们只需要更新一个值,例如。 ID SORT_ORDER 100 500 102 1000 103 1500 104 2000 如果我们更改订单,我们只需要更新一行 ID SORT_ORDER 104 250 100 500 102 1000 103 1500
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 2017-06-10
  • 2016-12-19
  • 2020-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多