我有一个MySQL表,如下所示:
id | name | parent_id
19 | category1 | 0
20 | category2 | 19
21 | category3 | 20
22 | category4 | 21
......
Run Code Online (Sandbox Code Playgroud)
现在,我想要一个MySQL查询,我只提供id [例如说'id = 19']然后我应该得到它的所有子id [即结果应该有id',21,22']. ...而且,孩子们的等级不知道它可以变化....
另外,我已经有了使用for循环的解决方案.....如果可能的话,让我知道如何使用单个MySQL查询来实现相同的功能.
我已将链表实现为自引用数据库表:
CREATE TABLE LinkedList(
Id bigint NOT NULL,
ParentId bigint NULL,
SomeData nvarchar(50) NOT NULL)
Run Code Online (Sandbox Code Playgroud)
其中Id是主键,ParentId是列表中上一个节点的Id.第一个节点有ParentId = NULL.
我现在想要从表中进行SELECT,按照它们应该出现的顺序对行进行排序,作为列表中的节点.
例如:如果表包含行
Id ParentId SomeData
24971 NULL 0
38324 24971 1
60088 60089 3
60089 38324 2
61039 61497 5
61497 60088 4
109397 109831 7
109831 61039 6
Run Code Online (Sandbox Code Playgroud)
然后使用标准对其进行排序,结果应该是:
Id ParentId SomeData
24971 NULL 0
38324 24971 1
60089 38324 2
60088 60089 3
61497 60088 4
61039 61497 5
109831 61039 6
109397 109831 7
Run Code Online (Sandbox Code Playgroud)
你应该使用SomeData colum作为控件,所以请不要作为SomeData的ORDER …
我正在使用Django和PostgreSQL,但如果有更好的方法可以使用原始SQL或数据库特定的操作,那么我并不是完全依赖于Django ORM.
我有一个需要顺序排序的模型.查找操作通常会按顺序检索整个列表.对此数据最常见的操作是将一行移动到列表的底部,其中一部分介入项目冒泡以替换上一项,如下所示:
(operation on A, with subset B, C, E) A -> B B -> C C -> E D -> D E -> A Notice how D does not move.
通常,项目的子集不会超过约50个项目,但基本列表可能会增长到数万个条目.
实现此目的最明显的方法是使用简单的整数顺序字段.这似乎不是最理想的.它要求妥协使位置排序列不唯一,其中仅在修改操作的持续时间内需要非唯一性.要想看到这一点,想象使用A和子集B的最小操作:
oldpos = B.pos
B.pos = A.pos
A.pos = oldpos
Run Code Online (Sandbox Code Playgroud)
即使您已存储位置,但在第二行您违反了唯一性约束.此外,此方法使原子性成为问题 - 您的读取操作必须在写入之前发生,在此期间您的记录可能会发生变化.Django的默认事务处理文档没有解决这个问题,尽管我知道在SQL中使用"REPEATABLE READ"级别的事务锁定是可能的.
我正在寻找更适合这种使用模式的备用数据结构.我已经看过这个问题了.
一个提议是Dewey十进制样式解决方案,它使插入操作在现有值之间以数字方式发生,因此在B和C之间插入A会导致:
A=1 -> B=2 B=2 -> A=2.5 C=3 -> C=3
这解决了列唯一性问题,但引入了列必须是指定小数位数的浮点数的问题.要么我高估了,要存储的数据超出了我的需要,要么系统受到我施加的任意小数长度的限制.此外,我不希望使用甚至超过数据库 - 一些密钥将比其他密钥更频繁地移动,使得该解决方案更快地达到极限.我可以通过定期重新编号数据库来解决这个问题,但似乎一个好的数据结构应该避免需要这个.
我考虑过的另一个结构是链表(和变体).这样做的优点是可以直接进行修改,但我不确定它的SQL属性 - 在SQL查询中排序这样的列表似乎很痛苦,并且提取列表的非顺序子集非常糟糕检索属性.
除此之外,还有B树,各种二叉树等等.你对这个数据结构有什么建议?SQL中的此解决方案是否有标准数据结构?使用顺序整数的最初想法是否真的会出现扩展问题,或者我发现哪些问题没有?
我正在使用 CouchDB/PouchDB 构建可以被视为幻灯片应用程序的东西:每个“幻灯片”都是它自己的 Couch 文档,幻灯片可以重新排序或删除,并且可以在现有幻灯片之间或在开头或幻灯片结束。一个幻灯片可以从一张幻灯片增加到 10,000 张幻灯片,所以我对空间和时间效率很敏感。
我首先制作了幻灯片创建/编辑功能,完全低估了跟踪幻灯片排序的难度。这很难,因为每个幻灯片文档的顺序完全独立于幻灯片文档本身,也就是说,我无法按时间或文档中包含的某个数字对其进行排序。我在 StackOverflow 上看到了许多关于如何跟踪关系数据库中的排序的问题:
但所有这些都涉及
previous和next字段,其中包含文档的任一侧的主键;这些都不适合 CouchDB:#1 在 SQL 或 CouchDB 中会产生大量的偶然复杂性。#2 不可靠,因为缺乏原子事务(CouchDB 可能会用它的新文档更新前一个文档,next但同时另一个客户端可能已经更新了新的下一个文档,因此更新新的下一个文档将失败并显示 409,并且您的链表被保留在不一致的状态)。出于同样的原因,#3 是完全行不通的。
我正在评估的一种面向 CouchDB 的方法将创建一个仅包含幻灯片排序的文档:它可能包含一个主键到订单号的哈希对象以及一个将订单号转换为-的数组主键,并在幻灯片重新排序/插入/删除时更新此对象。这样做的缺点是 Couch 会为每次订单更改(重新排序/插入/删除)保留一份这个潜在大文档的副本——CouchDB 不支持压缩单个文档,我不想在我的文件上运行压缩整个数据库,因为我喜欢保留每个幻灯片文档的历史记录。另一个缺点是,在数千张幻灯片之后,每次对排序的更改都涉及将整个对象(数百 KB)从 PouchDB/客户端传输到 Couch。
这种方法的一个调整是创建第二个数据库来保存这个订购文档并打开它的自动压缩。跟踪两个数据库连接需要做更多的工作,而且我最终必须将大量数据放到网络上,但我将有一种强大的方式来在 CouchDB 中订购文档。
所以我的问题是:CouchDB 人们通常如何存储文档的顺序?更有经验的 CouchDB 人员能否看到我上面概述的方法中的任何缺陷?
database ×2
sql ×2
couchdb ×1
django ×1
linked-list ×1
mysql ×1
pouchdb ×1
python ×1
sorting ×1
sql-server ×1