我在数据库中有一组对象。 照片库中的图像,目录中的产品,书中的章节等。每个对象都表示为一行。 我希望能够任意地对这些图像进行排序,将这种排序存储在数据库中,这样当我显示对象时,它们的顺序就会正确。

例如,假设我正在写一本书,每一章都是一个对象。 我写了我的书,并按以下顺序列出章节:

简介,可访问性,表单与功能,错误,一致性,结论,索引

它转到编辑器,并返回以下建议的顺序:

简介,表格,功能,可访问性,一致性,错误,结论,索引

如何以强大,高效的方式将此排序存储在数据库中?

我有以下想法,但我对其中任何一个都不感兴趣:

  1. 阵列。 每行都有一个订单ID,当订单更改时(通过删除后插入),订单ID会更新。 这使得检索变得容易,因为它只是ORDER BY ,但它似乎很容易破解。

    // REMOVAL
    UPDATE ... SET orderingID=NULL WHERE orderingID=removedID
    UPDATE ... SET orderingID=orderingID-1 WHERE orderingID > removedID
    // INSERTION
    UPDATE ... SET orderingID=orderingID+1 WHERE orderingID > insertionID
    UPDATE ... SET orderID=insertionID WHERE ID=addedID

  2. 链接列表。 每行都有一列用于排序中下一行的id。 遍历在这里似乎很昂贵,尽管可能通过某种方式使用ORDER BY ,我没想到。

  3. 间隔阵列。 将orderingID(在#1中使用)设置为大,因此第一个对象是100,第二个是200,等等。然后当插入发生时,只需将它放在(objectBefore + objectAfter)/2 当然,这需要偶尔重新平衡,所以你没有太紧密的东西(即使有花车,你最终会遇到舍入误差)。

这些对我来说都不是特别优雅。 有没有人有更好的方法呢?

===============>>#1 票数:6

另一种替代方法是(如果您的RDBMS支持它)使用类型为array的列。 虽然这打破了规范化规则,但在这种情况下它可能很有用。 我知道有一个数组的数据库是PostgreSQL。

===============>>#2 票数:4

Rails中的acts_as_list mixin基本上按照您在#1中概述的方式处理。 它查找名为position的INTEGER列(当然可以覆盖其名称)并使用它来执行ORDER BY。 当您想要重新订购商品时,您需要更新头寸。 每次我使用它都很适合我。

作为旁注,您可以通过使用稀疏编号来消除总是在INSERTS / DELETES上重新定位的需要 - 类似于当天的基本类型...您可以编号您的位置10,20,30等。如果你需要在10到20之间插入一些东西,你只需要插入一个位置为15.同样在删除时你可以删除该行并留下空隙。 您只需要在实际更改订单时进行重新编号,或者如果您尝试执行插入操作,并且没有适当的间隙插入。

当然,根据您的具体情况(例如,您是否已将其他行已加载到内存中),使用间隙方法可能有意义也可能没有意义。

===============>>#3 票数:3

只考虑选项#1 vs#3 :没有间隔数组选项(#3)只推迟正常数组(#1)的问题? 无论你选择哪种算法,要么它已经坏了,要么你会在#3之后遇到问题,或者它可以工作,然后#1应该也能正常工作。

===============>>#4 票数:2

如果对象没有被其他表严格键入,并且列表很短,则删除域中的所有内容并重新插入正确的列表是最简单的。 但是如果列表很大并且你有很多限制来减慢删除,这是不切实际的。 我认为你的第一种方法真的是最干净的。 如果你在一个交易中运行它,你可以确定当你处于更新中间以搞砸订单时,没有什么奇怪的事情发生。

===============>>#5 票数:2

我在上一个项目中做到了这一点,但它只是偶尔需要特别订购的表,并且不经常访问。 我认为间隔数组是最好的选择,因为它在一般情况下重新排序最便宜,只涉及一个值的变化和两个查询。

此外,我认为ORDER BY将由数据库供应商进行相当大的优化,因此与链接列表实现相比,利用该功能对于性能将是有利的。

===============>>#6 票数:2

使用浮点数表示每个项目的位置:

第1项 - > 0.0

第2项 - > 1.0

第3项 - > 2.0

第4项 - > 3.0

您可以通过简单的二分法在任何其他两个项目之间放置任何项目:

第1项 - > 0.0

第4项 - > 0.5

第2项 - > 1.0

第3项 - > 2.0

(在第1项和第2项之间移动了第4项)。

由于浮点数在计算机系统中编码的方式,二分过程几乎可以无限期地继续。

第4项 - > 0.5

第1项 - > 0.75

第2项 - > 1.0

第3项 - > 2.0

(将项目1移动到项目4之后的位置)

===============>>#7 票数:1

我会做一个连续的数字,在桌子上有一个触发器,如果​​它已经存在,它会为优先级“腾出空间”。

===============>>#8 票数:1 已采纳

由于我主要使用Django遇到这个问题 ,我发现这个解决方案是最可行的。 似乎在关系数据库中没有任何“正确的方法”。

===============>>#9 票数:1

我也有这个问题。 我受到了很大的压力(不是我们所有人)而且我选择了#1,只更新了更改的行。

如果将项目1与项目10交换,只需执行两次更新即可更新项目1和项目10的订单号。我知道它在算法上很简单,并且它是O(n)最坏的情况,但最坏的情况是当你有列表的总排列。 这种情况多久会发生一次? 那是给你回答的。

===============>>#10 票数:0

我有同样的问题,可能至少花了一周的时间来讨论正确的数据建模,但我想我终于明白了。 使用PostgreSQL中的数组数据类型,您可以存储每个有序项的主键,并在订单更改时使用插入或删除相应地更新该数组。 引用单行将允许您根据数组列中的顺序映射所有对象。

它仍然有点不稳定的解决方案,但它可能比选项#1更好,因为选项1需要在订购更改时更新所有其他行的订单号。

===============>>#11 票数:0

INSERT写入之外,方案#1和方案#3在每个操作中具有相同的复杂性。 上方案#1具有O(N)写入INSERT和方案#3具有O(1)上写入INSERT

对于每个其他数据库操作,复杂性是相同的。

甚至不应该考虑方案#2,因为它的DELETE需要O(n)读写。 方案#1和方案#3对读和写都有O(1) DELETE

新方法

如果您的元素具有不同的父元素(即它们共享外键行),那么您可以尝试以下方法...

Django提供了一种与数据库无关的解决方案,用于在CharField()存储整数列表。 一个缺点是存储的字符串的最大长度不能大于max_length ,这取决于DB。

就复杂性而言,这将为INSERT提供Scheme#1 O(1)写入,因为排序信息将作为单个字段存储在父元素的行中。

另一个缺点是现在需要JOIN到父行来更新排序。

https://docs.djangoproject.com/en/dev/ref/validators/#django.core.validators.validate_comma_separated_integer_list

  ask by tghw translate from so

未解决问题?本站智能推荐:

1回复

django模型数据库架构

在Django中,像Instagram这样的社交媒体网站的数据库架构看起来如何? 例如,您如何使一个用户可以发布多个帖子,而他们只能拥有1个个人资料? 我想知道我应该拥有哪些不同的表 我想知道如何连接桌子 我想知道我应该写些什么来将个人资料链接到帖子(即外键)
2回复

没有这样的表Django数据库

因此,我创建了一个用于存储来自Gmail用户的凭据的模型。 我想进行迁移,但它说没有这样的表: 我的模特: 调用该模型以检查授权:
2回复

Django:将数据从一个数据库复制到另一个数据库

我有两个sqlite.db文件。 我想将db文件表中一列的内容复制到另一列。 例如: 我在db文件中有名为new.db的模型信息: 以及名为old.db的db文件中的以下信息模型: 我想将old.db列中的info_id和info_name中的所有数据复制到new.
1回复

如何将formwizard POST请求保存到数据库

如何将form_data保存到数据库? forms.py
2回复

为调查应用程序选择哪种数据库设计?

我正在创建一个调查应用程序,但我不知道如何设计数据库。 我需要包含多个问题和多种类型问题的调查。 我可以想到3种方式: a)为调查和每种问题创建数据库表,并将它们与Survey_id列联系起来。 b)为问题和调查创建数据库表,并将其存储在JSON之类的文本字段中。 这些“文本”
3回复

用于描述IT环境的数据库模型[关闭]

我正在编写一个Django应用程序来帮助记录相当小的IT环境。 我不知道如何最好地建模数据,因为每个设备的属性数量可能会有所不同,即使在相同类型的设备之间也是如此。 例如,SAN将具有一个或多个阵列,以及一个或多个卷。 然后,阵列将具有名称,RAID级别,大小,磁盘数量的属性,并且卷将具有
1回复

复杂的Django模型关系

我正在尝试建立一个在Django中使用的SQL数据库。 我从抽象的角度理解了该模型,但是对于如何构建数据库以了解我是否正确关联了这些对象,我还不够了解。 我想保留此摘要,以便自己实现代码。 说我有三种类型的对象: A , B和C A可能持有一个或多个B 一个B可以任意组合包含多个B
1回复

Django ORM:按类型1的相关动作计数排序,但当类型2的相关动作计数>类型1时排除

假设我们有以下模型: 类型= 1或2 我需要找到具有类型1动作 最多但类型2动作不超过类型1的前3个项目。 (动作计数1>动作计数2) 测试: 应该产生[1,2,3]而不是5。 由于动作和项目的数量非常大,因此查询必须非常有效。 基础数据库是MySQL
3回复

是否不建议将相同的数据保存在关系数据库中的两个位置?

我正在编写基于Django / Python的应用程序,因此我想避免编写代码或对数据库的请求超出我的要求。 将已经存储在较高级别的数据存储在较低级别是否不合理,从而更容易从较低级别访问? 希望这很清楚-请告诉我是否需要澄清。 谢谢!
1回复

数据库设计:订购多对多关系

在Django中,我有以下模型: 在某些时候,我需要在White定义Pinks的排序(为了得到White1.pinks: P1, P2, P3而不是随机的White1.pinks: P2, P3, P1 ) ,所以我创建了 问题1:这是更好的解决方案吗? 问题2:这显然是多