1. Помимо Adjacency List (как в вашем случае) существуют другие типы деревьев, такие как Nested Sets, Materialized Path, Closure Table и т.д. Различаются они в скорости/сложности различных операций (добавление, удаление, перемещение, выборка). Хотя все проблемы решаются кешированием.
2. Зачем выносить изображения товара в отдельную таблицу? Достаточно создать поле images и хранить там сериализованный массив путей.
3. Также не понятна структура корзины. Проще создать в таблице basket (*carts) поля customer_id и поле products (так же сериализованный список товаров в корзине). А еще лучше хранить данные корзины в сессии.