2

ドロップボックス API からファイル ツリーを取得しています。API では、すべてのフォルダーが個別の API 呼び出しで読み取られるため、ファイル ツリー全体を反復処理してすべてのフォルダーを取得します。これは cron ジョブで実行されます。

ドロップボックスからデータを取得する関数は次のようになります。

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
        }
    }
}

ファイルツリーをpostgres-databaseに保存して、後でそれを表すjsonオブジェクトとして出力できるようにしたいと考えています。

データベース設計は初めてで、データを保存する方法がわかりません。すべてのファイルとフォルダーには、独自のデータベース エントリが必要だと思います。すべての子がその親 ID を参照できるようにするか、すべての親にその子のリストを含めることができます。

私は初心者なので、適度にシンプルで、読む速度が書くよりもはるかに重要な解決策が欲しいです!

4

1 に答える 1

10

ツリーをリレーショナル データベースに格納するには、いくつかのオプションがあります。概要については、Bill Karwinのスライドをお勧めします。

読み取り速度が最も重要であると述べたので、クロージャー テーブルは適切で強力なエンコーディングになります。クロージャ テーブルは、各パス (/a/b/c など) ごとにすべての親/子を (推移的に) 格納する多対多の関係です。このようにして、ツリーに対する多くのクエリを 1 つの 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)
);

ディレクトリ /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';

たとえば、'/a' のすべての子を再帰的にクエリするには、次のようにします。

select * 
from nodes join parents_children on path = child_path
where parent_path = '/a';

次のファイル ツリーを格納する、より包括的な例:

/
/a/
/a/b/
/a/b/d
/a/c
/b

データを挿入するには:

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';

/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        
于 2013-11-07T12:10:15.123 に答える