我有一个物化的路径驱动的公告板.它使用以下查询来按顺序获取消息,
SELECT * FROM Board ORDER by root DESC, path ASC LIMIT 0,100
Run Code Online (Sandbox Code Playgroud)
where root是id线程的根消息,path是物化路径.
但是,我使用索引进行此查询的努力都没有取得任何成功.
mysql> explain extended select path from Board order by root desc, path asc limit 100;
+-------+---------------+----------+---------+------+-------+----------+----------------------------+
| type | possible_keys | key | key_len | ref | rows | filtered | Extra
+-------+---------------+----------+---------+------+-------+----------+-----------------------------
| index | NULL | rootpath | 261 | NULL | 21998 | 100.00 | Using index; Using filesort
Run Code Online (Sandbox Code Playgroud)
目前它显示列下表中所有行的数量rows.我想知道,有没有办法减少这个数字或以任何其他方式优化查询?
CREATE TABLE `Board` ( …Run Code Online (Sandbox Code Playgroud) 我在表格中有一个树形结构,它使用物化路径让我快速找到孩子.但是,我还需要对结果进行深度优先排序,正如人们对线程论坛回复所期望的那样.
id | parent_id | matpath | created
----+-----------+---------+----------------------------
2 | 1 | 1 | 2010-05-08 15:18:37.987544
3 | 1 | 1 | 2010-05-08 17:38:14.125377
4 | 1 | 1 | 2010-05-08 17:38:57.26743
5 | 1 | 1 | 2010-05-08 17:43:28.211708
7 | 1 | 1 | 2010-05-08 18:18:11.849735
6 | 2 | 1.2 | 2010-05-08 17:50:43.288759
9 | 5 | 1.5 | 2010-05-09 14:02:43.818646
8 | 6 | 1.2.6 | 2010-05-09 14:01:17.632695
Run Code Online (Sandbox Code Playgroud)
所以最终的结果实际上应该像这样排序:
id | parent_id | matpath | …Run Code Online (Sandbox Code Playgroud) 你可能知道有一个名为ltree的PostgreSQL模块.此外,您还可以使用数组类型作为整数(*1,请参阅下面的注释),在此测试中显示,与ltree相比,其递归查询实际上执行速度稍慢 - 除了字符串索引(*2,见下面的评论).
我不太确定这些测试结果的可信度.
这里我最大的问题实际上是关于相对未知的,几乎没有文档的树模块.这里描述(文档也可以找到!!)如下:
支持分层数据类型(类型的词典树),应该转到contrib/tree,因为缺少适当的文档而待决 .
阅读完文档后,我有点困惑,我是否应该以我的大应用程序为基础(一个CMS,一切都将存储在一个层次结构树结构中 - 不仅是内容,还有文件等,所以你可以看到这快速扩展)在ltree,普通物化路径(Path Enumeration)周围用分隔字符串或整数数组作为路径 - 或者理论上相对未知的"树"模块应该是更快,更可扩展和更好的解决方案.
我已经分析了不同的树结构模型,由于查询性能,节点和子树的可伸缩性和重新排序是我的主要要求,我已经能够排除邻接列表(递归CTE不会解决性能,因为树缩放巨大),嵌套集/间隔(在一些查询中不够快,考虑到它在填充树时的缺点),闭包表(在复杂的树中非常大的缩放 - 对我这样的大型项目没有用)等等并决定采用物化路径,对于读取操作来说非常快,并且可以轻松地在子层次上移动子树和节点.所以问题只是关于物化路径的最佳建议实现.
我对在PostgreSQL中听到你对"树"的理论或经验感到特别好奇.
我正在阅读SQL server 2008圣经,它说物化路径模式明显快于hierarchyid.这是真的吗?如何使hierarchyid具有相同或更好的性能.
hierarchyid sql-server-2008 materialized-path-pattern c#-4.0
我打算在MongoDB中使用物化路径来表示树,并且需要将物化路径转换回JSON树.
恩.//物化路径
var input = [
{"id": "0", "path": "javascript" },
{"id": "1", "path": "javascript/database" },
{"id": "2", "path": "javascript/database/tree" },
{"id": "3", "path": "javascript/mvc" },
{"id": "4", "path": "javascript/mvc/knockout.js"},
{"id": "5", "path": "javascript/mvc/backbone.js"},
{"id": "6", "path": "c++" },
{"id": "7", "path": "c++/c0xx"},
{"id": "8", "path": "c++/c0xx/lambda expressions"},
{"id": "9", "path": "c++/c0xx/vc10" }
];
Run Code Online (Sandbox Code Playgroud)
结果将是:
[
{
"id": "0",
"name": "javascript",
"children": [
{
"id": "1",
"name": "database",
"children": [
{
"id": "2",
"name": "tree",
"children": []
}
]
}, …Run Code Online (Sandbox Code Playgroud) 我具有使用PostgreSQL的ltree模块构建的这种物化路径树结构。
我当然可以轻松地使用ltree从整棵树或特定路径/子路径中获取所有节点,但是当我这样做时,自然地,我得到的是很多行(等于节点中的节点的数组/切片)结束.. Golang /您使用的任何编程语言)
我要做的是将树(理想情况下是从某个起点和终点的路径/点)作为树状JSON树对象等来获取
{
"id": 1,
"path": "1",
"name": "root",
"children": [
{
"id": 2,
"path": "1.2",
"name": "Node 2",
"children": [
{
"id": 3,
"path": "1.2.3",
"name": "Node 3",
"children": [
{
"id": 4,
"path": "1.2.3.4",
"name": "Node 4",
"children": [
]
}
]
},
{
"id": 5,
"path": "1.2.5",
"name": "Node 5",
"children": [
]
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
我从线性(非分层)行/数组/切片结果集中知道,我当然可以在Golang中进行分解,并在其中进行创建此json的必要业务逻辑,但是如果有方便的话,肯定会好得多直接通过PostgreSQL实现此目标的方法。
那么,您如何在PostgreSQL中将ltree树形结构输出到json-从起始路径到结束路径都集中地?
如果您不知道ltree,我想这个问题可能会进一步推广到“分层路径树到分层json”
我也在考虑在ltree路径之外的所有节点上添加一个parent_id的想法,因为至少那样我就可以使用使用该id的递归调用来获取我猜的json ...我也考虑过根据父ID的更改发生时间在该parent_id上放置触发器以管理路径(保持更新)-我知道这是另一个问题,但是也许您也可以告诉我您的观点,对此吗?
我希望有一些天才可以帮助我。:)
为了方便起见,这里有一个示例创建脚本,可用于节省时间:
CREATE TABLE node …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 TypeORM 更新 SQLite3 数据库中的具体化路径。文件夹表(我正在更新)有parent 和parentId 列。当我更新父列时,parentId 列将更新,但 mpath 列不会更新。
我尝试使用 getRepository() 和 getTreeRepository() 进行更新。
我不太确定还要添加什么,请参阅下面所附的模型和更新方法。
模型
@Entity()
@Tree('materialized-path')
export class Folder {
@PrimaryGeneratedColumn()
id: number;
@Column({
type: 'varchar',
length: 50
})
title: string;
@TreeParent()
parent: Folder;
@TreeChildren()
children: Folder[];
@Column({
nullable: true
})
parentId: number;
Run Code Online (Sandbox Code Playgroud)
更新
await connection.getTreeRepository<Folder>(Folder).update(id, {
parent: await connection.getRepository<Folder>(Folder).findOne(parentId)
});
Run Code Online (Sandbox Code Playgroud) 我有一个列id,一个列和一个作为物化路径的parent列。path
看起来像
1 | \N | 1
2 | 1 | 1/2
3 | 2 | 1/2/3
4 | 3 | 1/2/3/4
5 | 3 | 1/2/3/5
6 | 2 | 1/2/6
7 | 6 | 1/2/6/7
8 | 2 | 1/2/8
9 | 1 | 1/9
10 | 9 | 1/9/10
11 | 10 | 1/9/10/11
12 | 11 | 1/9/10/11/12
13 | 11 | 1/9/10/11/13
14 | 11 | 1/9/10/11/14
15 | 14 …Run Code Online (Sandbox Code Playgroud) 我在使用 ruby 从物化路径构建树结构时遇到问题。
假设我有一个排序结果集(来自 couchdb):
[
{ :key => [], :value => "Home" },
{ :key => ["about"], :value => "About" },
{ :key => ["services"], :value => "Services" },
{ :key => ["services", "plans"], :value => "Plans" },
{ :key => ["services", "training"], :value => "Training" },
{ :key => ["services", "training", "python"], :value => "Python" },
{ :key => ["services", "training", "ruby"], :value => "Ruby" }
]
Run Code Online (Sandbox Code Playgroud)
我只需要它作为 ruby 中的树,以下哈希就足够了:
{ :title => "Home", :path => [], :children …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用"物化路径"模式在Android应用程序的SQLite数据库中存储目录结构.我的单个表有一个主键字段,即文件路径,如下所示:
PATH(PK)
/sdcard/foo
/sdcard/bar
/sdcard/foo/music
/sdcard/foo/films
/sdcard/bar/photos
Run Code Online (Sandbox Code Playgroud)
我想获得/ sdcard目录的直接子节点列表.我知道如何使用此SQL获取/ sdcard的所有(间接)后代:
WHERE PATH LIKE '/sdcard/%'
Run Code Online (Sandbox Code Playgroud)
它返回所有行.但是获取顶级子级的SQL是什么,所以只返回:
/sdcard/foo
/sdcard/bar
Run Code Online (Sandbox Code Playgroud)
这个问题的答案可能会提供深刻见解,但我的SQL不够强大,无法理解'Scrum Meister的回应: 基于mysql中的路径选择