@ Джош Лейцель
Это мышление является очень ограничительным (и, на мой взгляд, просто оправданием того, что слишком ленив, чтобы реализовать надежное решение), особенно для динамических древовидных структур, выраженных в базе данных.
Рассмотрим следующий пример:
Мой проект имеет логическую структуру:
Иерархия компаний выражается в единицах сущностей. Каждый объект может рассматриваться в общем случае как член иерархии или как член определенного уровня иерархии. Сама иерархия определяется в таблице как одна ветвь дерева следующим образом:
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
)
Объекты, находящиеся на уровне деления, будут иметь Division_id, area_id и store_id как NULL, Area_id Area и 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);
}
, в результате чего получается более чистый код и только одно подготовленное утверждение.
Весь пример не использует никакого пользовательского ввода.
Просто кое-что рассмотреть.