【问题标题】:How to keep ordering of records in a database table如何保持数据库表中记录的顺序
【发布时间】:2011-05-06 03:06:18
【问题描述】:

我正在创建一个数据库表,用于存储最终会显示在网页上的菜单链接。

我的问题是我想控制菜单项的顺序。我可以有一个名为 order 的字段,但每次我有一个新的菜单链接时,我都必须插入 order 并将所有具有更高 order 的记录更改为 +1。

例如,假设我想要链接(按此顺序):

家 关于 产品 购物

我可以有一个名为 MenuLinks 的表并包含以下列:Name, Order

我的数据如下所示:

名称顺序 首页1 约 2 产品 3 购物 4

但如果我现在想添加一个名为 ContactUs 的新链接,但我想显示在主页下方。

谁能想到一种更好的方法来存储需要在数据库表中排序的列表,而无需进行繁琐的维护工作。

【问题讨论】:

    标签: sql database database-design data-modeling


    【解决方案1】:

    我觉得这与使用数组与链表的一般问题有关。 如何在同一个表中存储引用下一条记录的外键?这是类似链表的方法。

    对于您的示例,没有太多选项卡,因此基于数组的方法应该可以正常工作。 但对于拥有数百条记录的人来说,使用自引用外键可能会很有用。

    ID Name      NExT  
     1 Home      2  
     2 About     3  
     3 Products  4 
     4 Shopping  NULL
    

    添加和删除行将类似于链表的插入和删除。

    更新: 修改表

    ID Name       NExT  
     1 Home       5  
     2 About      3  
     3 Products   4 
     4 Shopping   NULL
     5 Contact us 2
    

    顺序将是 1 > 5 > 2 > 3 > 4,由下一列确定。 您还可以使用 prev 列,使其类似于双向链表。

    【讨论】:

    • 这里的问题是它不能解决问题。进行一项更改需要您更新所有记录>该行
    • 没有一项更改不需要您更新所有行。如果您在主页之后添加联系我们,则表格将如图所示。更新了答案。
    • 但您正在更新每条记录中的 Next 列。 .我不明白你为什么说你没有更新所有行
    • 如何编写一个正确排序表的查询?似乎没有一个简单的(不是递归的)。
    • 是的,@RohitBanga,继续尝试排序:)
    【解决方案2】:

    如果没有 ORDER BY,则无法保证数据的顺序 - 通常,如果没有 ORDER BY,它将基于插入顺序。

    遗憾的是,没有适合用户自定义排序顺序的约定。
    使用 ROW_NUMBER 之类的分析/加窗/排名函数可以逃脱惩罚,但这取决于数据和数据库支持(MySQL 不支持分析函数,Oracle 9i+/PostgreSQL 8.4+/SQL Server 2005+ 支持)。但是,如果您希望以“B”开头的条目出现在“A”/etc 之前,则分析函数无济于事。

    您的选择是使用两条语句插入一条记录:

    UPDATE YOUR_TABLE
       SET sort_order = sort_order + 1
     WHERE sort_order >= 2
    
    INSERT INTO YOUR_TABLE
      (value, sort_order)
    VALUES('new value', 2)
    

    ...或删除现有记录,然后按新顺序重新插入列表。

    【讨论】:

      【解决方案3】:

      您应该考虑,当您使用链表时,当您想要重新排序其中一个项目时,您还必须更新其他记录,这需要在根本不快的事务中完成。(您需要事务,因为所有更新都必须完全完成,否则必须不更新)
      此问题还有其他解决方案适用于 small 列表。
      要使用此方法,您需要为每条记录指定一个编号。例如:

      Name    Number
      Home     5
      About    10
      Products 15
      shopping 20
      

      编号较小的行位于列表的开头,编号最大的行将是列表的最后一项 现在这是诀窍,如果您想重新排序 Products 行并将其插入 HomeAbout 之间,您所要做的就是将 Product 的 Number 字段更改为 HomeAbout Number
      之间的数字 Home number 为 5,About 数字为 10,因此 Product 的 Number 字段将为 (5+10)/2 = 7.5

      Name    Number
      Home     5
      About    10
      Products 7.5
      shopping 20
      

      现在您可以根据数字字段对最终列表进行排序

      【讨论】:

        【解决方案4】:

        更好的解决方案是按顺序创建一个元素 ID 数组,然后将其转换为 json 数组,并将其按原样存储到文件或表中或任何您想要的位置。然后,您可以从数据库中获取对象并将数组映射回元素列表。您一方面保留订单,另一方面保留数据。如果从数据库中删除一个元素,则可以从数组中删除映射为空的元素。如果您将新元素添加到数据库中,您也需要将它们添加到您的数组中,但如果您不这样做,则不会有任何损坏。

        长话短说:

        1.将订单作为 ids 的 json 数组保存到文件或表中或任何您想要的位置。

        2。将元素保存在数据库中,无需担心它们的顺序。

        3.当您需要时,取回您的 id 数组并将它们映射到数据库中各自的元素。

        【讨论】:

          【解决方案5】:

          您可以添加 2 列(之后,之前) 例如,联系我们是在 home 之后和 about 之前,如果您想在 contact us 和 home 之间添加一个新链接,您只需更改 3 条记录。 列更改为(新链接名称)之前的主页, 然后您插入新链接,然后在列更改为(新链接名称)后与我们联系。 对不起,我的英语不好。

          【讨论】:

            猜你喜欢
            • 2019-10-06
            • 2021-08-25
            • 2022-12-24
            • 1970-01-01
            • 2020-04-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多