考虑我有两个表surveys
和surveyQuestions
surveys
有一个主要索引surveyUniqueId
surveyQuestions
有一个主要索引questionUniqueId
,还有另一列surveyUniqueId
,可将其映射到survey
用户创建新的survey
,然后向其添加surveyQuestions
。每次添加surveyQuestion时,ajax调用都会在surveyQuestions
表中创建新行。
现在,这就是问题,用户可以重新排列调查问题的顺序。
为每项调查存储问题顺序的最佳方法是什么?
对我来说,有两种选择:
选项1:在questionOrder
表格上创建surveys
列,以存储questionUniqueId
的已排序数组。基本上,每次用户添加,删除或移动问题时,都会发送标准的ajax消息来保存问题,然后循环遍历UI中的所有问题,创建questionUniqueId
的有序列表并发送第二个ajax请求更新questionOrder
的{{1}}列。稍后,在构建UI时,我可以使用该列表以相同的顺序呈现问题
选项2:在survey
表格上创建questionIndex
列,以存储每个问题的索引。基本上,当用户添加新问题时,只需保存添加了适当索引的一个问题,然后,每次用户删除或移动问题时,循环UI创建和问题更新数组中的所有问题,并在服务器上,使用该更新数组中的问题索引,因为它是surveyQuestions
有些说明:
questionIndex
只能属于一个surveyQuestions
survey
永远不会有超过100个问题您将如何处理存储问题订单?其中一种,或其他一些我没想过的方式?
答案 0 :(得分:2)
关于在RDBMS表中存储/表示有序项的子问题:
另一种方法是用“下一个列表”来表示顺序,即“指定的元素在此之后” - 即一个链表:
所以最初你可能有这些数据:
Id Name SortOrder
--------------------------
101 Foo 3
102 Bar 1
103 Baz 2
可以存储为:
Id Name Next
--------------------------
101 Foo (NULL)
102 Bar 102
103 Baz 101
您需要某种方式来存储HEAD项目,或者遍历项目以查看哪些项目没有父项。
这种方法的优点是重新排序少量行或在给定位置插入行很便宜:您只需要更新两行而不是整个范围。缺点是您需要注意参照完整性以避免丢失Next
行,以及重复(表示图形周期)或值NULL
值不正确的行。幸运的是,这些可以使用自我外键和非NULL过滤的UNIQUE约束来强制执行,但是如果您在一个表中存储多个组,则还需要一个自定义CHECK约束来确保每个组中只有一行是尾(NULL),并使用复合键来防止一个组中的行引用另一个组的行。
如果您的应用程序代码只知道“insert at index”值而不是行的主键,那么您还需要CTE递归遍历Next
值以找到要插入的位置插入后。
答案 1 :(得分:1)
如果您曾想过在数据库的字段中存储“数组”,那真的非常怀疑它是不是一个好主意。
当然,有100个问题,您可能需要在最坏情况重新订购方案中更新100行。但那是100个INT(技术上甚至可能是SMALLINT)。如果要更新可变长度字符串值,可能会考虑这个问题;但是,与维护(和构造)这样的“阵列”字段同时保持参照完整性的努力相比,更新100个整数值的成本应该是微不足道的。
...然后你必须考虑数据库的功能牺牲;而不是SELECT [fields] FROM [child] WHERE [parent]_id = X ORDER BY [sequence field]
你需要拉X的数组,解析它,拉出子值,然后按解析的序列对它们进行排序。如果要更改该序列,则必须重新打包子标识符(这意味着您必须插入子数据才能获得标识符,然后“客户端”代码甚至可以对其进行排序。)
答案 2 :(得分:1)
(重写)
每个问题都应该有唯一的ID。此ID与屏幕上的排序无关。
订单是ID列表。这个列表(我假设)由UI维护,改组,添加,删除等,对吗?除了决定以什么顺序显示哪些问题之外,列表没有用处。
因此,UI获取,修改并存储一个问题ID的commalist。此列表的内容和顺序控制显示。它可能是TEXT
字段,因为它对MySQL没有用处,只能用于UI。大多数应用程序语言都可以轻易地破坏/爆炸列表。
答案 3 :(得分:0)
当我们用优化的话说话时,我们应该清楚地了解我们应该优化什么。
1)如果您使用调查为公共站点创建一些管理面板,则选项1是唯一正确的选择。编辑调查时所做的100 * x更新的开销与源代码的简单性和订单字段的优势相比没什么可比性。
2)如果你为用户的thoudsands创建了一些界面,这将创建数百万个带有数十亿个问题的调查 - 好的,需要进行优化,但订单字段仍然太好,不能拒绝它。所以@Dai解决方案在这种情况下可能很有用。