SQLite и JOIN

Обычно по работе, когда требуется сохранить какую-то информацию (вроде справочников абонентов) в компоненте, которая отвязана от основного проекта, я стараюсь использовать BerkleyDB. Она быстра, когда для доступа используется только какой-то ключ и вполне практична. Но в одном из проектов с ростом количества доступов к файлу базы от разных потоков стали происходить коллизии и терялись части данных (частично виню в этом механизм доступа, реализованный в PHP, частично – недоработки в компоненте). К тому же усложнялась структура данных, хранящихся в каждом ключе. Для разрешения вопроса был выбран SQLite, т.к. с ним возможно разрисовать структуру данных, и поддерживается одновременная работа с одной базой.

В ходе проверок запросов выяснился весьма интересный момент. В привычных мне ранее PostgreSQL или MySQL конструкция вида:

SELECT b.id, f.title as foo_title, b.title
FROM bar b LEFT JOIN foo f ON f.id=b.foo_id

будет отрабатывать вполне успешно. Но не в SQLite. И дело не только в том, что конструкцию с JOIN надо заключать в круглые скобки. Внутренняя логика SQLite превращает это выражение в один источник и не позволяет выделить из какой именно таблицы тебе нужно взять поле. И в данном примере значение title из foo перекроет значение title из bar. Т.е. результатом запроса вида:

SELECT id, title
FROM (bar b LEFT JOIN foo f ON f.id=b.foo_id)

Будут значения id и title из таблицы foo. Выход один: делать объединение таблиц в конструкции WHERE, тем более, как говорит документация потери быстродействия в этом случае не будет.

Leave a Reply