![](/img/trans.png)
[英]How should I present a cost field to the user, and store it in the database?
[英]How should I store sorted items in a database?
在我的应用程序中,用户可以按照他们选择的顺序重新排列他们喜爱的书籍。
我的数据库中有一个“书籍”表,每本书都有一行。 目前,有一个名为“position”的整数列,用于存储每本书的位置:1为顶级书籍,2为下一本书,等等。
问题是,如果有人将书从位置#11000拖到位置#1,那么我必须对数据库进行11,000次更新。 这似乎效率低下。 有一个更好的方法吗?
我曾经有过的一个想法就是让另一个名为“book_sort_orderings”的表或其他东西,每个用户都有一行。 一列是一个巨大的文本列,用于存储书籍ID的排序列表。 然后,当用户重新排列书籍时,我可以将此值拉出到我的代码中,在那里执行重新排列,并更新数据库行。 当然,每当添加或删除一本书时,我都必须更新这个数组。 这是处理事情的“正确”方式吗? 或者有什么聪明的我可以做的事情来加快速度而不改变我目前的设置?
假设您以“批量”方式执行此操作(而不是为每行进行单独的数据库往返),您会惊讶于一个体面的DBMS可以快速更新11,000行。
但是如果你想避免这种情况,那就使用旧的BASIC技巧(从BASIC的时候还有行号): 留下空白!
而不是使用位置: 1, 2, 3, 4, 5 etc...
使用10, 20, 30, 40, 50 etc...
所以当你需要将第一个项目移动到倒数第二个位置时,只需修改10到41,你最终会得到: 20, 30, 40, 41, 50 etc...
。 显然,如果差距被完全填满,你需要做一些摆弄,但这个策略应该能够几乎消除大量的UPDATE。
另一种可能性是实现双向链表:而不是订单,保留前一个和下一个项的ID。 重新排序可以通过简单地“重新链接”ID来完成,就像在内存列表中一样。 不幸的是,您还会阻止DBMS直接对项目进行排序(至少没有笨拙且可能效率低下的递归查询) - 您必须在应用程序级别进行排序,所以我建议再次对它进行排序
一列是一个巨大的文本列,用于存储书籍ID的排序列表。
请不要这样做。 你违反了1NF并且有很好的理由不这样做,包括数据的一致性和性能(你必须重写整个字段,以便对它的任何部分进行任何单一更改)。
您当前的解决方案似乎不适用于多个用户设置。 如果在Book
表中设置了图书的订单,那么它对所有用户都不是永久性的吗?
正如其他人所提到的,通常最好将数据标准化,这需要您添加另一个表,就像您所建议的那样。 所以你可以有一个新的BookOrdering
表。 所以它有一个book_id
,一个user_id
和position
列。 这样,每个用户和每本书都有一个指定的位置。
因此会有一个默认排序(不会存储在此表中),但用户可以更改顺序。 该表仅记录默认值的更改。 如果要加载用户的书籍,首先要检查此表格中是否有某个user_id,然后相应地切换/调整顺序。
使用几个SQL语句更新示例中的所有行并不是很难。 您不需要在DBMS上发出11,000个更新(我认为这是您想要说的)。
首先,更新所有正在洗牌的书籍:
UPDATE book
SET position = position + 1
WHERE position < 11000
AND position >= 1
...然后设置你正在移动的书的位置:
UPDATE book
SET position = 1
WHERE id = whatever
在列表中标识新的varchar列(orderCode)。 此列以char格式存储每个项目的顺序,如下:
'1','2','3','4','5','6', '7', '8', '9', '91', '92',....
现在,如果要插入1到2之间的项,则orederCode的值将为“11”。列表顺序为:
'1','11','2','3','4','5','6', '7', '8', '9', '91', '92',....
现在我们假设您将插入11和2之间,您将插入orderCode value ='12':
'1','11','12','2','3','4','5','6', '7', '8', '9', '91', '92',....
最后,如果要插入“11”和“12”中的项目,则订单值将为:'111':
'1','11','111','12','2','3','4','5','6', '7', '8', '9', '91', '92',....'99','991,...
您可以不时运行查询以将订单值修复为一个char。
使用浮点数据类型而不是varchar。 所以这个清单:
'1', '11', '111', '12', '2', '3', '4', '5', '6', '7', '8', '9', '91', '92',....
就像吼叫:
0.1, 0.11, 0.111, 0,12, 0.3, 0.4, 0.5, 0.6, ......,0.9,0.91,....
反之,浮点排序比varchar排序更快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.