0

親フォルダーで重複するファイル名をキャッチする最も効率的なコードを見つけようとしています。リネージ付きの親子モデルを使用して、MySQL データベースにファイル ツリーを保存しています。

CREATE TABLE `filetable` (
    `id` int(11) NOT NULL auto_increment,
    `name` varchar(50) NOT NULL,
    `parent_id` int(11) NOT NULL,
    `path_num` varchar(255) NOT NULL,
    `path_string` text() NOT NULL,  
    PRIMARY KEY  (`id`)
) ENGINE=InnoDB;

2 つの方法を検討
しています。 1. クエリを実行します。

INSERT INTO filetable (name, parent_id, path_num, path_string) 
    SELECT '$name','$pid','$path_num','$path_string' FROM DUAL
        WHERE NOT EXISTS
            (SELECT name FROM filetable WHERE name='$name');

そしてPHPで:

if (mysql_affected_rows() === 0) takeAction($name);

長所:単純なSQL、テーブルに行を追加する必要がない短所:
大きなテーブルで雪が降る可能性のある二重クエリ

2.フィールドに一意のインデックスを作成し、次を使用します。

INSERT INTO filetable (name, parent_id, path_num, path_string) 
    VALUES ('$name','$pid','$path_num','$path_string')
    ON DUPLICATE KEY UPDATE 0=0;

そしてPHPで:

if (mysql_affected_rows() === 2) takeAction($name); // Yes 2 for updates

長所: UPDATEnameが重複している場合にごく一部のクエリでトリガーされる短所:
テーブル内の余分な行

一意のフィールドは、ファイルへのフル パスである path_string です。私のファイルシステムでは、非常に長くなる可能性があるため、TEXT タイプのフィールドです。MySQL では、TEXT フィールドに一意のインデックスを作成できません。だから私がやろうとしていることは、列を作成することです

`problemsolver` varchar(62) = $parent_id . '_'.$name 

その上に一意のインデックスを作成します。

これらのクエリがデータベースへのすべてのクエリの 10% を占めると予想しています。

私の質問は、これら 2 つの方法のどちらを使用するか、またその理由は何ですか? または利用可能なより良いオプションはありますか?

4

1 に答える 1

1

どちらの方法も機能します。方法 1 は、クエリがより集中的であり、毎回実行されるため、理想的ではありません。

方法 2 は、必要なときにのみ余分な作業を行うため、より効率的であるため、望ましい方法です。

さらに、値が衝突する可能性を減らすために、保存された値にタイムスタンプまたはランダム データを組み込むことができます。

于 2013-09-06T04:25:17.567 に答える