RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
Visa 
4274 3200 2453 6495 

Small. Fast. Reliable.
Choose any three.
Архитектура SQLite

Введение

Этот документ описывает архитектуру библиотеки SQLite. Информация здесь полезна для тех, кто хочет понять или изменить внутренние работы SQLite.

Соседняя диаграмма показывает главные компоненты SQLite и как они взаимодействуют. Текст ниже объясняет роли различных компонентов.

Обзор

SQLite работает, собирая код на SQL в байт-код, затем управляя этим кодом с использованием виртуальной машины.

sqlite3_prepare_v2() и связанные интерфейсы действуют как компилятор для преобразования кода на SQL в байт-код. Объект sqlite3_stmt это контейнер для единственной программы, которая осуществляет единственный SQL-оператор. sqlite3_step() передает программу в виртуальную машину, и управляет программой, в ходе чего формирует строку результата, который будет возвращен, получает фатальную ошибку или обрабатывает прерывание.

Интерфейс

Большая часть C-интерфейса находится в исходных файлах main.c, legacy.c и vdbeapi.c, хотя некоторый код рассеян в других файлах, где у них может быть доступ к структурам данных. sqlite3_get_table() осуществляется в table.c . a href="c3ref/mprintf.html">sqlite3_mprintf() в printf.c. Интерфейс sqlite3_complete() в complete.c. Интерфейс TCL реализован в tclsqlite.c.

Чтобы избежать столкновений имени, все внешние символы в библиотеке SQLite начинаются с префикса sqlite3. Те символы, которые предназначаются для наружного применения (другими словами, те символы, которые формируют API для SQLite) добавляют подчеркивание, и таким образом начинаются с sqlite3_. Дополнительный API иногда добавляет дополнительное имя до подчеркивания, например: sqlite3rbu_ или sqlite3session_.

Токенизатор

Когда последовательность, содержащая SQL-операторы, должна быть оценена, ее сначала посылают в токенизатор. Он делит код на SQL в символы и передает их один за другим анализатору. Находится токенизатор в файле tokenize.c.

Обратите внимание на то, что в этом дизайне токенизатор вызывает анализатор. Люди, которые знакомы с YACC и BISON, могут быть приучены к выполнению вещей наоборот: анализатор вызывает токенизатор. Принятая здесь схема тем не менее лучше, потому что это может быть сделано ориентированным на многопотоковое исполнение и работает быстрее.

Парсер

Парсер назначает значение на символы на основе их контекста. Анализатор для SQLite произведен, используя Lemon parser generator. Лимон делает ту же самую работу, как YACC/BISON, но это использует различный входной синтаксис, который менее подвержен ошибкам. Лимон также производит анализатор, который ориентирован на многопотоковое исполнение. Лимон определяет понятие нетерминального деструктора так, чтобы это не пропускало память, когда сталкивается с синтаксическими ошибками. Файл грамматики, который ведет Лимон, для определения языка SQL, который понимает SQLite, находится в parse.y.

Поскольку Лимон программа, которой на машине обычно нет, полный исходный код Lemon (всего один файл на C) включен в дистрибутив SQLite в подкаталоге "tool".

Генератор кода

После того, как анализатор собирает символы в дерево синтаксического анализа, запускается генератор кода, чтобы проанализировать дерево синтаксического анализа и произвести байт-код, который выполняет работу SQL-оператора. Подготовленный объект запроса это контейнер для этого байт-кода. Есть много файлов в генераторе кода, включая attach.c, auth.c, build.c, delete.c, expr.c, insert.c, pragma.c, select.c, trigger.c, update.c, vacuum.c, where.c, wherecode.c и whereexpr.c. В этих файлах выполняется большая часть серьезной работы. expr.c обращается с генерацией кода для выражений. where*.c обращается с генерацией кода для операторов Where в SELECT, UPDATE и операторах удаления. Файлы attach.c, delete.c, insert.c, select.c, trigger.c update.c и vacuum.c обращаются с генерацией кода для SQL-операторов с теми же самыми именами. Каждый из этих файлов вызывает код в expr.c и в where.c, если надо. Все другие SQL-операторы закодированы в build.c. Файл auth.c осуществляет функциональность sqlite3_set_authorizer().

Генератор кода и особенно логику в where*.c и в select.c иногда называют планировщиком запроса. Для какого-то конкретного SQL-оператора могли бы быть сотни, тысячи или миллионы различных алгоритмов, чтобы вычислить ответ. Планировщик запроса это AI, который стремится выбрать лучший алгоритм из этих миллионов выбора.

Механизм байт-кода

Байт-кодом, созданным генератором кода, управляет виртуальная машина.

Сама виртуальная машина полностью содержится в единственном исходном файле vdbe.c. Файл vdbe.h определяет интерфейс между виртуальной машиной и остальной частью библиотеки SQLite, а vdbeInt.h определяет структуры и интерфейсы, которые являются частными для самой виртуальной машине. Различные другие vdbe*.c это помощники виртуальной машины. Файл vdbeaux.c содержит утилиты, используемые виртуальной машиной и интерфейсными модулями, используемыми остальной частью библиотеки, чтобы построить программы VM. Файл vdbeapi.c содержит внешние интерфейсы к виртуальной машине, такие как sqlite3_bind_int() и sqlite3_step(). Отдельные значения (последовательности, целые числа, числа с плавающей точкой и BLOB) сохранены во внутреннем объекте под названием "Mem", который реализован в vdbemem.c.

SQLite осуществляет функции SQL, используя вызовы для функций C. Даже встроенные функции SQL осуществляются так. Большинство встроенных функций SQL (например abs(), count(), substr() и т.д.) находятся в файле func.c. Функции преобразования даты и времени найдены в date.c. Некоторые функции, например, coalesce() и typeof(), осуществляются как байт-код непосредственно генератором кода.

B-Tree

База данных SQLite сохраняется на диске, используя B-tree в файле btree.c. Отдельные B-деревья используются для каждой таблицы и каждого индекса в базе данных. Все B-деревья сохранены в том же самом дисковом файле. Формат файла стабилен и четко определен и, как гарантируют, будет совместим и далее.

Интерфейс к подсистеме B-дерева и остальной части библиотеки SQLite определяется заголовочным файлом btree.h.

Кэш страницы

Модуль B-дерева запрашивает информацию у диска на страницах фиксированного размера. По умолчанию page_size = 4096 байт, но может быть любым значением между 512 и 65536 байт. Кэш страницы ответственен за чтение, запись и кэширование этих страниц. Кэш страницы также обеспечивает обратную перемотку и абстракцию атомной передачи, а также заботится о захвате файла базы данных. Драйвер B-tree запрашивает конкретные страницы от кэша и уведомляет кэш, когда хочет изменить страницы или передать изменения. Кэш страницы обращается со всеми грязными деталями проверки, поэтому запросы обработаны быстро, безопасно и эффективно.

Основной код кэша страницы находится в файле pager.c. Логика WAL mode вынесена в отдельный файл wal.c. Кэширование в памяти осуществляется в файлах pcache.c и pcache1.c. Интерфейс между подсистемой кэша страницы и остальной частью SQLite определяется заголовочным файлом pager.h.

Интерфейс с OS

Чтобы обеспечить переносимость, SQLite использует абстрактный объект, названный VFS. Каждый VFS предоставляет методы для открытия, чтения, записи и закрытия файлов на диске, а также для других определенных для OS задач, таких как нахождение текущего времени или получение случайных значений, чтобы инициализировать встроенный генератор псевдослучайного числа. SQLite в настоящее время обеспечивает VFS unix (в файле os_unix.c) и Windows (в файле os_win.c).

Утилиты

Выделение памяти, установленный порядок сравнения строк, портативный код преобразования чисел и текста и другие утилиты расположены в util.c. Таблицы символов, используемые анализатором, сохраняются хэш-таблицами в hash.c. utf.c содержит конверсионные подпрограммы Unicode. У SQLite есть свое собственное частное внедрение printf() (с некоторыми расширениями) в printf.c и собственный генератор псевдослучайных чисел (PRNG) в random.c.

Тестовый код

Файлы в подкаталоге "src/" исходного дерева, имена которых начинаются с test, нужны только для тестирования и не включены в стандартную сборку библиотеки.