ruby-on-rails - 我应该如何将已排序的项目存储在数据库中?

标签 ruby-on-rails database database-design activerecord relational-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等等...。显然,您需要进行一些调整以防间隙被完全填补,但这种策略应该能够几乎消除大量更新。


另一种可能性是实现双向链表:保留上一个和下一个项目的 ID 而不是顺序。重新排序可以通过简单地“重新链接”ID 来完成,就像在内存列表中一样。不幸的是,您还会阻止 DBMS 直接对项目进行排序(至少不会出现笨拙且可能效率低下的递归查询)——您必须在应用程序级别进行排序,所以我再次推荐它


And one column would be a huge text column that stores a sorted list of book ids.

请不要那样做。你会违反 1NF并且有非常好的理由不这样做,包括数据一致性和性能(您必须重写整个字段以对它的任何部分进行任何单个更改)。

关于ruby-on-rails - 我应该如何将已排序的项目存储在数据库中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13409121/

相关文章:

ruby-on-rails - 使用 rbenv 安装新的 ruby​​ 版本时出现 readline 错误

sql - 更新列的子字符串

php - MySql查询优化方法

sql-server - 在数据库的引用表中记录代表 "all other records"的记录是个好主意吗?

javascript - 使用 Ajax 更新 Rails 中的 'like' 计数

ruby-on-rails - 在 Rails 模块中显式调用模型对象?

ruby-on-rails - 你能选择一个浏览器目标服务器端吗?

C语言使用文件操作创建数据库

java - 如何使用Spring管理与多个数据库的连接

sql - 数据库中的货币兑换