leo*_*ora 9 sql database database-design data-modeling
我正在创建一个数据库表,该表将存储最终将显示在网页上的菜单链接.
我的问题是我想控制菜单项的顺序.我可以有一个名为order的字段,但每次我有一个新的菜单链接我都必须插入订单并将所有更高顺序的记录更改为+1.
例如,假设我想要链接(按此顺序):
Home About Products Shopping
我可以有一个名为MenuLinks的表,并有列:Name,Order
我的数据看起来像这样:
Name Order Home 1 About 2 Products 3 Shopping 4
但如果我现在想添加一个名为ContactUs的新链接,但我想在家里出现.
任何人都可以想到一种更好的方法来存储需要在数据库表中排序的列表,而无需这种繁琐的维护工作.
我觉得这与使用数组与链表的一般问题有关.如何在同一个表中存储引用下一条记录的外键?这是链接列表之类的方法.
对于您的示例,没有太多选项卡,因此基于数组的方法应该可以正常工作.但对于拥有数百条记录的人来说,使用自引用外键可能很有用.
ID Name NExT
1 Home 2
2 About 3
3 Products 4
4 Shopping NULL
Run Code Online (Sandbox Code Playgroud)
添加和删除行将类似于链接列表的插入和删除.
更新:修改表
ID Name NExT
1 Home 5
2 About 3
3 Products 4
4 Shopping NULL
5 Contact us 2
Run Code Online (Sandbox Code Playgroud)
订单将是1> 5> 2> 3> 4,由下一栏确定.您还可以使用prev列,使其类似于双向链接列表.
如果没有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)
Run Code Online (Sandbox Code Playgroud)
...或删除现有记录,然后在新订单中重新插入列表.
您应该考虑到,当您使用链接列表时,当您想要重新排序其中一项时,您还必须更新其他记录,并且这需要在根本不快的事务中完成。(您需要事务,因为所有更新都必须完全完成,或者都必须更新)
对于此问题还有其他适用于小列表的解决方案。
要使用此方法,您需要为每条记录指定一个编号。例如:
Name Number
Home 5
About 10
Products 15
shopping 20
Run Code Online (Sandbox Code Playgroud)
数字较小的行位于列表的开头,数字最大的行将是列表的最后一项,如果您想对“产品”行重新排序并将其插入 “主页”和“关于您所有”之间,那么现在这里是技巧。所要做的就是将产品的编号字段更改为等于主页编号和关于编号之间的编号
,主页编号为 5,关于编号为 10,因此产品的编号字段将为 (5+10)/2 = 7.5
Name Number
Home 5
About 10
Products 7.5
shopping 20
Run Code Online (Sandbox Code Playgroud)
现在您可以根据“数字”字段对最终列表进行排序