。
は、次の例を考えてみましょう:
会社の階層は、エンティティの用語で表現されています
私のプロジェクトでは、論理的な構造を有しています。各エンティティは、階層のメンバーである一般的なケースで、または階層の特定のレベルのメンバーとして扱うことができます。
entity_structure (
id
name
parent_entity_structure_id
);
をとエンティティ自体はように表現されています:以下のように階層構造自体は、単一の木の枝のようにテーブルに定義されている私が作成したアルゴリズムを構築した使いやすくするため
entities (
id
name
entity_structure_id
parent_id
);
木の平面図。
SELECT * FROM entity_structure;
id | name | entity_structure_parent_id
-----------------------------------------------------------
1 | Company | null (special one that always exists)
2 | Division | 1
3 | Area | 2
4 | Store | 3
これは以下のフラット表現が生成されることになる:次の具体例は、私は何を意味するか示すdivision_idを有するであろう分割レベルである
entity_tree (
entity_id
division_id
area_id
store_id
)
エンティティをAREA_IDおよびNULLとしてSTORE_ID 、領域area_idとstore_idをNULLなどとする
これは、次のような文を使用して除算のすべての子を照会することができる点です。
SELECT * FROM entity_tree WHERE division_id = :division_id;
しかし、これは私が照会しているエンティティの構造レベルを知っていることを前提としています。やっていいだろう。
すべて同じレベルではないかもしれない、私はそれが単一のエンティティの構造レベルを把握することは難しいことではありませんけど、私は、エンティティのコレクションをループてると仮定し
SELECT * FROM entity_tree WHERE :structure = :entity_id;
。それが今であるように私には、階層の各レベルに別々のクエリを作成する必要がありますが、私はフィールドをパラメータ化することができれば、私は次のことを行うことができます:クリーンなコードが得られ
$children = array();
$stmt = $pdo->prepare('SELECT entity_id FROM entity_tree WHERE :structure = :entityId');
foreach ($entities AS $entity) {
$stmt->execute(array(
':structure' = $entity->getEntityStructureId(),
':entityId' = $entity->getId()
));
$children[$entity->getId()] = $stmt->fetchAll(PDO::FETCH_COLUMN);
}
を、唯一のプリペアドステートメント。
例全体では、ユーザー入力はまったく使用されません。
ちょっと考えてください。
お返事ありがとうございます。投稿した最初のクエリがうまくいかないことが判明しました。例えば、 '' title''を ':field'にバインドすると、フィールドの値ではなく 'title'という文字列が選択されます。 PDOが私のために扱うはずのセキュリティを追加する必要があるので、今やカラム/テーブルをバインドする方法がないというのは奇妙なことです。/ – DisgruntledGoat
これは背後にある考え方ではおそらく、ユーザーは、クエリが呼び出すフィールド/テーブルを直接選択します。しかし、私はそれがあなたの最後に少し余分な作業を追加することに同意します。 –
私はあなたのポイントを見ます。しかし、私はテーブルを指定するだけの状況で使用していますが、抽象的な方法で(例: 'displayTable( 'エピソード')'。私はこの場合、パラメータ/セキュリティについて本当に心配する必要はないと思う。 – DisgruntledGoat