@乔什·莱泽尔
这种想法非常具有限制性(在我看来,这只是懒惰实施稳健解决方案的借口),尤其是对于在数据库中表达的动态树结构。
考虑以下示例:
我的项目有一个逻辑结构:
公司层次结构以实体表示。在一般情况下,每个实体都可以被视为层次结构的成员或层次结构的特定级别的成员。层次结构本身在表中定义为单个树分支,如下所示:
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
这将导致生成以下平面表示:
entity_tree (
entity_id
division_id
area_id
store_id
)
处于分区级别的实体将divide_id、area_id和store_id为NULL,一个区域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);
}
导致代码更简洁,并且只有一个准备好的语句。
整个示例不使用任何用户输入。
只是需要考虑的事情。