Him*_*ors 1 postgresql database-design
我正在从Dropbox API检索文件树。在api中,每个文件夹都是通过单独的api调用读取的,因此我将遍历整个文件树以获取所有文件夹。这是通过cron-job完成的。
从Dropbox检索数据的函数如下所示:
function renderFolderTree($myobject, $path){
$entry = $myobject->getMetadataWithChildren($path);
foreach ($entry['contents'] as $child) {
if ($child['is_dir']){
$folderpath = $child['path'];
//this will retrieve the child-folder
renderFolderTree($myobject, $folderpath, $filetree);
//here I need something that saves the folder
}else{
print_r($child);
//here I need something that saves the file
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想将文件树保存到postgres数据库中,以便以后可以将其作为表示它的json对象输出。
我是数据库设计的新手,不确定如何保存数据。我假设每个文件和文件夹都应该有自己的数据库条目。我可以让每个孩子引用它的父母ID,也可以让每个父母都包含它的孩子列表。
因为我是新手,所以我想提供一个相当简单的解决方案,并且阅读速度比书写更重要!
有几种方法可以将树存储在关系数据库中。为了获得良好的概述,我推荐Bill Karwin 的幻灯片。
既然您提到读取速度是最重要的,那么闭包表将是一种适当的,功能强大的编码。闭合表是一个多对多关系,它为每个路径(例如,/ a / b / c)(传递地)存储所有父/子。这样,可以通过一个SQL查询(非递归)完成对树的许多查询。
看起来像
create table nodes (
path varchar primary key
/* your other attributes here, can be null */
);
create table parents_children (
parent_path varchar,
child_path varchar,
primary key(parent_path,child_path),
foreign key (parent_path) references nodes (path),
foreign key (child_path) references nodes (path)
);
Run Code Online (Sandbox Code Playgroud)
要在目录/ a / b /下插入一个新文件/ a / b / c,请执行以下操作:
insert into nodes values ('/a/b/c');
insert into parents_children
select parent_path, '/a/b/c' from parents_children where child_path = '/a/b/'
union all select '/a/b/c','/a/b/c';
Run Code Online (Sandbox Code Playgroud)
例如,要递归查询'/ a'中的所有子级,您可以执行以下操作:
select *
from nodes join parents_children on path = child_path
where parent_path = '/a';
Run Code Online (Sandbox Code Playgroud)
一个更详尽的示例,它存储以下文件树:
/
/a/
/a/b/
/a/b/d
/a/c
/b
Run Code Online (Sandbox Code Playgroud)
要插入数据:
insert into nodes values ('/');
insert into parents_children values ('/','/');
insert into nodes values ('/a/');
insert into parents_children
select parent_path, '/a/' from parents_children where child_path = '/'
union all select '/a/','/a/';
insert into nodes values ('/a/b/');
insert into parents_children
select parent_path, '/a/b/' from parents_children where child_path = '/a/'
union all select '/a/b/','/a/b/';
insert into nodes values ('/a/c');
insert into parents_children
select parent_path, '/a/c' from parents_children where child_path = '/a/'
union all select '/a/c','/a/c';
insert into nodes values ('/a/b/d');
insert into parents_children
select parent_path, '/a/b/d' from parents_children where child_path = '/a/b/'
union all select '/a/b/d','/a/b/d';
insert into nodes values ('/b');
insert into parents_children
select parent_path, '/b' from parents_children where child_path = '/'
union all select '/b','/b';
Run Code Online (Sandbox Code Playgroud)
查询/ a /的所有子级
select node.*
from nodes join parents_children on path = child_path
where parent_path = '/a/';
path
----------
/a/
/a/b/
/a/b/d
/a/c
Run Code Online (Sandbox Code Playgroud)