Файл Sqlitedb, чем открыть
Обновлено: 22.11.2024
Возможна ли частичная загрузка файла базы данных при его открытии, а не его полное чтение в память? У меня есть вариант использования, когда мне нужно получить доступ только к одной небольшой таблице из ряда файлов базы данных, некоторые из которых довольно велики, и процесс занимает много времени, потому что, по-видимому, весь файл загружается до того, как можно будет получить доступ к любой таблице. В частности, мне нужно получить доступ только к таблице sqlite_master из этих файлов.
Спасибо за любую помощь, Йохан
(2) Ларри Брасфилд (larrybr) 28 мая 2021 г., 14:08:58 в ответ на 1 [источник]
по-видимому, весь файл [базы данных] загружается до того, как можно будет получить доступ к какой-либо таблице.
Что заставляет вас в это верить? Я думаю, как только вы обнаружите настоящую причину задержки, которой хотите избежать, вы не почувствуете необходимости вызывать «частичную загрузку файла» (что происходит без особых усилий).
(4) Йохан Ламменс (jlammens) 2021-05-28 14:29:12 в ответ на 2 [ссылка] [источник]
Что наводит меня на мысль, что это время, необходимое для открытия файла db в любом клиенте, который я пробовал (например, SQLite Expert или интерфейс python sqlite3), и соответствующая активность диска, которую я вижу, пока база данных не станет доступной. Большие файлы БД (несколько ГБ) занимают минуты, маленькие файлы (несколько МБ) — секунды. Последовательность операций: открыть файл базы данных, запустить скрипт sql ниже, закрыть файл базы данных:
SELECT 'n'||'='||count(*)||'+'||group_concat(namelen,'+') as db_schema FROM ( select name, name||'='||length( sql) как namelen, введите из sqlite_master ГДЕ тип = 'таблица' и имя не похоже на 'Persistent%' порядок по имени) группировать по типу;
(6) Ларри Брасфилд (larrybr) 28 мая 2021 г., 14:44:02 в ответ на 4 [ссылка] [источник]
Исходя из этих свидетельств, разумно предположить, что SQLite читает весь файл БД при открытии. Но делать такой вывод неразумно. Как говорит Ричард, SQLite считывает то, что необходимо для удовлетворения запросов. Он читает целые «страницы» за раз, так что «должен» включает части страниц, которые могут не быть строго обязательными. Возможно, ваши большие файлы БД имеют большие страницы, которые будут включать одну или несколько страниц, в которых находится таблица sqlite_schema (она же sqlite_master).
Вам нужно выяснить, почему происходит вся эта дисковая активность. В SQLite нет возможности избежать этого, потому что SQLite избегает этого без предупреждения. Возможно, виновата ваша оболочка библиотеки SQLite, или могут происходить вещи, которые вам еще не очевидны. (Это мои догадки.)
Эти подпрограммы открывают файл базы данных SQLite, как указано в аргументе имени файла. Аргумент имени файла интерпретируется как UTF-8 для sqlite3_open() и sqlite3_open_v2() и как UTF-16 в собственном порядке байтов для sqlite3_open16(). Дескриптор соединения с базой данных обычно возвращается в *ppDb, даже если возникает ошибка. Единственным исключением является то, что если SQLite не может выделить память для хранения объекта sqlite3, в *ppDb будет записано значение NULL вместо указателя на объект sqlite3. Если база данных успешно открыта (и/или создана), возвращается SQLITE_OK. В противном случае возвращается код ошибки. Подпрограммы sqlite3_errmsg() или sqlite3_errmsg16() можно использовать для получения описания ошибки на английском языке после сбоя любой из подпрограмм sqlite3_open().
Кодировкой по умолчанию будет UTF-8 для баз данных, созданных с помощью sqlite3_open() или sqlite3_open_v2(). Кодировка по умолчанию для баз данных, созданных с помощью sqlite3_open16(), будет UTF-16 в собственном порядке байтов.
Независимо от того, возникает ли ошибка при открытии, ресурсы, связанные с дескриптором подключения к базе данных, должны быть освобождены путем передачи их функции sqlite3_close(), когда они больше не требуются.
Интерфейс sqlite3_open_v2() работает так же, как sqlite3_open(), за исключением того, что он принимает два дополнительных параметра для дополнительного контроля над новым подключением к базе данных. Параметр flags для sqlite3_open_v2() должен включать как минимум одну из следующих трех комбинаций флагов:
SQLITE_OPEN_READONLY База данных открывается в режиме только для чтения. Если база данных еще не существует, возвращается ошибка.
SQLITE_OPEN_READWRITE База данных открывается для чтения и записи, если это возможно, или только для чтения, если файл защищен от записи операционной системой. В любом случае база данных уже должна существовать, иначе будет возвращена ошибка.
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE База данных открывается для чтения и записи и создается, если она еще не существует. Это поведение всегда используется для sqlite3_open() и sqlite3_open16().
Помимо обязательных флагов также поддерживаются следующие необязательные флаги:
SQLITE_OPEN_URI Имя файла можно интерпретировать как URI, если этот флаг установлен.
SQLITE_OPEN_MEMORY База данных будет открыта как база данных в памяти.База данных называется аргументом «имя файла» для целей совместного использования кеша, если включен режим общего кеша, но в противном случае «имя файла» игнорируется.
SQLITE_OPEN_NOMUTEX Новое соединение с базой данных будет использовать многопоточный режим. Это означает, что отдельные потоки могут одновременно использовать SQLite, если каждый поток использует другое соединение с базой данных.
SQLITE_OPEN_FULLMUTEX Новое соединение с базой данных будет использовать "последовательный" режим потоковой передачи. Это означает, что несколько потоков могут безопасно пытаться одновременно использовать одно и то же соединение с базой данных. (Мьютексы будут блокировать любой фактический параллелизм, но в этом режиме нет ничего плохого в попытке.)
SQLITE_OPEN_SHAREDCACHE База данных открыта с включенным общим кешем, переопределяющим настройку общего кеша по умолчанию, предоставленную sqlite3_enable_shared_cache().
SQLITE_OPEN_PRIVATECACHE База данных открыта, общий кеш отключен, переопределяя настройку общего кеша по умолчанию, предоставленную sqlite3_enable_shared_cache().
SQLITE_OPEN_EXRESCODE Соединение с базой данных устанавливается в "режиме расширенного кода результата". Другими словами, база данных ведет себя так, как если sqlite3_extended_result_codes(db,1) где вызывается при подключении к базе данных, как только соединение создается. Помимо установки режима расширенного кода результата, этот флаг также заставляет sqlite3_open_v2() возвращать расширенный код результата.
SQLITE_OPEN_NOFOLLOW Имя файла базы данных не может быть символической ссылкой
Если 3-й параметр sqlite3_open_v2() не является одной из обязательных комбинаций, показанных выше, необязательно объединенных с другими битами SQLITE_OPEN_*, тогда поведение не определено. Исторические версии SQLite молча игнорировали лишние биты в параметре flags для sqlite3_open_v2(), однако это поведение может не быть перенесено в будущие версии SQLite, поэтому приложения не должны полагаться на него. В частности, обратите внимание, что флаг SQLITE_OPEN_EXCLUSIVE не работает для sqlite3_open_v2(). SQLITE_OPEN_EXCLUSIVE *не* приводит к сбою открытия, если база данных уже существует. Флаг SQLITE_OPEN_EXCLUSIVE предназначен для использования только интерфейсом VFS, а не sqlite3_open_v2().
Четвертый параметр sqlite3_open_v2() — это имя объекта sqlite3_vfs, определяющего интерфейс операционной системы, который должно использовать новое подключение к базе данных. Если четвертый параметр является указателем NULL, используется объект sqlite3_vfs по умолчанию.
Если имя файла ":memory:", то для подключения создается частная временная база данных в памяти. Эта база данных в памяти исчезнет, когда соединение с базой данных будет закрыто. В будущих версиях SQLite могут использоваться дополнительные специальные имена файлов, начинающиеся с символа «:». Когда имя файла базы данных действительно начинается с символа ":", рекомендуется добавлять к имени файла префикс пути, например "./", чтобы избежать двусмысленности.
Если имя файла представляет собой пустую строку, будет создана частная временная база данных на диске. Эта частная база данных будет автоматически удалена, как только соединение с базой данных будет закрыто.
Имена файлов URI
Если интерпретация имени файла URI включена и аргумент имени файла начинается с «file:», то имя файла интерпретируется как URI. Интерпретация имени файла URI включена, если флаг SQLITE_OPEN_URI установлен в третьем аргументе sqlite3_open_v2() или если он был включен глобально с помощью параметра SQLITE_CONFIG_URI с методом sqlite3_config() или с помощью параметра времени компиляции SQLITE_USE_URI. Интерпретация имени файла URI по умолчанию отключена, но будущие выпуски SQLite могут включить интерпретацию имени файла URI по умолчанию. Дополнительные сведения см. в разделе «Имена файлов URI».
Имена файлов URI анализируются в соответствии с RFC 3986. Если URI содержит полномочия, это должна быть либо пустая строка, либо строка "localhost". Если полномочия не являются пустой строкой или "localhost", вызывающей стороне возвращается ошибка. Компонент фрагмента URI, если он присутствует, игнорируется.
SQLite использует компонент пути URI в качестве имени файла на диске, содержащего базу данных. Если путь начинается с символа «/», то он интерпретируется как абсолютный путь. Если путь не начинается с символа «/» (что означает, что раздел полномочий опущен в URI), то путь интерпретируется как относительный путь. В Windows первым компонентом абсолютного пути является спецификация диска (например, "C:").
Компонент запроса URI может содержать параметры, интерпретируемые либо самим SQLite, либо пользовательской реализацией VFS. SQLite и его встроенные VFS интерпретируют следующие параметры запроса:
-
vfs: Параметр "vfs" может использоваться для указания имени объекта VFS, предоставляющего интерфейс операционной системы, который следует использовать для доступа к файлу базы данных на диске. Если для этой опции задана пустая строка, используется объект VFS по умолчанию.Указание неизвестной VFS является ошибкой. Если используется sqlite3_open_v2() и присутствует параметр vfs, то VFS, указанный параметром, имеет приоритет над значением, переданным в качестве четвертого параметра функции sqlite3_open_v2().
Указание неизвестного параметра в компоненте запроса URI не является ошибкой. Будущие версии SQLite могут понимать дополнительные параметры запроса. Дополнительную информацию см. в разделе "Параметры запроса со специальным значением для SQLite".
Примеры имен файлов URI
Шестнадцатеричные управляющие последовательности URI (%HH) поддерживаются в компонентах пути и запроса URI. Шестнадцатеричная escape-последовательность состоит из знака процента — «%», за которым следуют ровно две шестнадцатеричные цифры, определяющие значение октета. Перед интерпретацией компонентов пути или запроса имени файла URI они кодируются с использованием UTF-8, и все шестнадцатеричные управляющие последовательности заменяются одним байтом, содержащим соответствующий октет. Если этот процесс создает недопустимую кодировку UTF-8, результаты не определены.
Примечание для пользователей Windows: кодировка, используемая для аргумента имени файла функций sqlite3_open() и sqlite3_open_v2(), должна быть UTF-8, а не какая-либо кодовая страница, определенная в настоящее время. Имена файлов, содержащие международные символы, должны быть преобразованы в UTF-8 перед передачей их в sqlite3_open() или sqlite3_open_v2().
Примечание для пользователей среды выполнения Windows: временный каталог должен быть установлен до вызова sqlite3_open() или sqlite3_open_v2(). В противном случае могут произойти сбои различных функций, требующих использования временных файлов.
Базы данных SQLite очень легкие. В отличие от других систем баз данных, для начала работы с базой данных SQLite Open не требуется настройка и установка.
Вам нужна библиотека SQLite размером менее 500 КБ. Мы приступим к работе непосредственно с базами данных и таблицами SQLite.
В этом руководстве по SQLite вы узнаете, как получить доступ к базе данных SQLite и использовать ее-
Создать базу данных SQLite
В отличие от других систем управления базами данных, в SQLite нет команды CREATE DATABASE. В этом руководстве по SQLite показано, как создать новую базу данных:
- Откройте инструмент командной строки Windows (cmd.exe) с самого начала, введите «cmd» и откройте его.
- “cmd” откроется в пользовательской папке по умолчанию, на моем компьютере это “C:\Users\MGA”:
- Ниже приведен основной синтаксис команды sqlite3 для создания базы данных.
- При этом будет создана новая база данных с именем «SchoolDB.db» в том же каталоге, куда вы скопировали файл .exe.
-
Если вы выберете файл SQLite и перейдете в каталог: «c:\sqlite», вы обнаружите, что файл «SchoolDB.db» создан, как показано на следующем снимке экрана:
SQLite СОЗДАЕТ базу данных в определенном месте с помощью Open
Если вы хотите узнать, как открыть файл SQLite и создать файл базы данных в определенном месте, а не в том же месте, где находится sqlite3.exe, вот как просмотреть базу данных SQLite:
- Вручную перейдите в папку, в которой находится sqlite3.exe, «C:\sqlite».
SQLite создает базу данных и заполняет ее таблицами из файла
Если у вас есть файл .SQL, содержащий схему таблиц, и вы хотите создать новую базу данных с теми же таблицами из этого файла, в следующем примере мы объясним, как это сделать.
Пример:
В следующем примере мы создадим образец базы данных. Мы будем использовать этот образец базы данных на протяжении всего руководства по SQLite с именем «SQLiteTutorialsDB» и заполним его таблицами. Как показано ниже:
- Откройте текстовый файл и вставьте в него следующие команды SQLite:
Приведенный выше код создаст четыре таблицы следующим образом:
- Таблица «Отделы» со следующими столбцами:
- «DepartmentId» — целое число, указывающее идентификатор отдела, и оно объявляется как ПЕРВИЧНЫЙ КЛЮЧ (объяснено далее в разделе «Ограничения столбцов»).
- "DepartmentName" — строковое название отдела, не допускающее пустых значений с использованием ограничения NOT NULL.
- Таблица «Студенты» со следующими столбцами:
- "StudentId" — целое число, объявленное как ПЕРВИЧНЫЙ КЛЮЧ.
- "StudentName" — имя учащегося, и оно не допускает нулевое значение с использованием ограничения NOT NULL.
- "DepartmentId" Целое число, которое относится к идентификатору отдела в столбце идентификатора отдела в таблице отделов.
- DateOfBirth — дата рождения учащегося.
- Таблица «Темы» со следующими столбцами:
- "SubjectId" — целое число, объявленное как ПЕРВИЧНЫЙ КЛЮЧ.
- "SubjectName" — это строковое значение, не допускающее пустых значений.
- Таблица «Марки» со следующими столбцами:
- Целое число «StudentId» указывает идентификатор учащегося.
- Целое число «SubjectId» указывает идентификатор субъекта.
- "Отметить" – оценка, которую учащийся получает по определенному предмету. Она также является целым числом и допускает нулевые значения.
Резервное копирование и база данных SQLite
Чтобы создать резервную копию базы данных, вы должны сначала открыть эту базу данных следующим образом:
- Перейдите к папке «C:\sqlite», затем дважды щелкните sqlite3.exe, чтобы открыть его.
- Откройте базу данных, используя следующий запрос
База данных SQLite Drop
В отличие от других систем управления базами данных, здесь нет команды DROP DATABASE SQLite. Если вы хотите удалить базу данных SQLite, все, что вам нужно сделать, это удалить файл базы данных.
Установите пакет SQLite NuGet
Используйте диспетчер пакетов NuGet для поиска sqlite-net-pcl и добавьте последнюю версию в проект общего кода.
Существует ряд пакетов NuGet с похожими именами. Правильный пакет имеет следующие атрибуты:
Настроить константы приложения
Пример проекта включает файл Constants.cs, содержащий общие данные конфигурации:
В файле констант указаны значения перечисления SQLiteOpenFlag по умолчанию, которые используются для инициализации подключения к базе данных. Перечисление SQLiteOpenFlag поддерживает следующие значения:
- Создать. Соединение автоматически создаст файл базы данных, если он не существует.
- FullMutex: соединение открывается в режиме последовательного потока.
- NoMutex: соединение открывается в многопоточном режиме.
- PrivateCache: подключение не будет участвовать в общем кэше, даже если оно включено.
- ReadWrite: соединение может считывать и записывать данные.
- SharedCache: подключение будет участвовать в общем кэше, если оно включено.
- ProtectionComplete: файл зашифрован и недоступен, пока устройство заблокировано.
- ProtectionCompleteUnlessOpen: файл шифруется до тех пор, пока не будет открыт, но после этого становится доступным, даже если пользователь заблокирует устройство.
- ProtectionCompleteUntilFirstUserAuthentication: файл шифруется до тех пор, пока пользователь не загрузит и не разблокирует устройство.
- ProtectionNone: файл базы данных не зашифрован.
Создайте класс доступа к базе данных
Класс-оболочка базы данных абстрагирует уровень доступа к данным от остальной части приложения. Этот класс централизует логику запросов и упрощает управление инициализацией базы данных, упрощая рефакторинг или расширение операций с данными по мере роста приложения. Приложение Todo определяет для этой цели класс TodoItemDatabase.
Отложенная инициализация
TodoItemDatabase использует асинхронную ленивую инициализацию, представленную пользовательским классом AsyncLazy, чтобы отложить инициализацию базы данных до первого обращения к ней:
Поле Экземпляр используется для создания таблицы базы данных для объекта TodoItem, если он еще не существует, и возвращает базу данных TodoItemDatabase как одноэлементную. Поле экземпляра типа AsyncLazy создается при первом ожидании. Если несколько потоков попытаются одновременно получить доступ к полю, все они будут использовать единую конструкцию. Затем, когда строительство завершится, все ожидают завершения операций. Кроме того, любые операции ожидания после завершения построения продолжаются сразу после того, как значение доступно.
Соединение с базой данных — это статическое поле, которое гарантирует, что на протяжении всего жизненного цикла приложения будет использоваться одно соединение с базой данных. Использование постоянного статического подключения обеспечивает более высокую производительность, чем многократное открытие и закрытие подключений в течение одного сеанса приложения.
Асинхронная ленивая инициализация
Чтобы начать инициализацию базы данных, избежать блокировки выполнения и иметь возможность перехватывать исключения, в примере приложения используется асинхронная ленивая инициализация, представленная классом AsyncLazy:
Класс AsyncLazy объединяет типы Lazy и Task для создания задачи с отложенной инициализацией, которая представляет собой инициализацию ресурса. Делегат фабрики, передаваемый конструктору, может быть синхронным или асинхронным. Фабричные делегаты будут запускаться в потоке пула потоков и не будут выполняться более одного раза (даже если несколько потоков пытаются запустить их одновременно). Когда фабричный делегат завершается, значение отложенной инициализации становится доступным, и все методы, ожидающие экземпляра AsyncLazy, получают это значение. Дополнительные сведения см. в разделе AsyncLazy.
Методы манипулирования данными
Доступ к данным в Xamarin.Forms
Класс TodoItemDatabase предоставляет поле Instance, через которое можно вызывать операции доступа к данным в классе TodoItemDatabase:
Расширенная настройка
SQLite предоставляет надежный API с большим количеством функций, чем описано в этой статье и примере приложения. В следующих разделах рассматриваются функции, важные для масштабируемости.
Журнал с опережающей записью
По умолчанию SQLite использует традиционный журнал отката. Копия неизмененного содержимого базы данных записывается в отдельный файл отката, затем изменения записываются непосредственно в файл базы данных. COMMIT возникает при удалении журнала отката.
Журнал с опережающей записью (WAL) сначала записывает изменения в отдельный файл WAL. В режиме WAL COMMIT — это специальная запись, добавленная к файлу WAL, которая позволяет выполнять несколько транзакций в одном файле WAL. Файл WAL снова объединяется с файлом базы данных в ходе специальной операции, которая называется контрольная точка.
WAL может быть быстрее для локальных баз данных, поскольку считыватели и писатели не блокируют друг друга, что позволяет выполнять операции чтения и записи одновременно. Однако режим WAL не позволяет изменять размер страницы, добавляет дополнительные ассоциации файлов в базу данных и добавляет дополнительную операцию контрольных точек.
Скопировать базу данных
Есть несколько случаев, когда может потребоваться копирование базы данных SQLite:
- База данных поставляется вместе с вашим приложением, но ее необходимо скопировать или переместить в доступное для записи хранилище на мобильном устройстве.
- Необходимо сделать резервную копию или копию базы данных.
- Вам необходимо изменить версию, переместить или переименовать файл базы данных.
В целом перемещение, переименование или копирование файла базы данных — это тот же процесс, что и для любого другого типа файла, за исключением нескольких дополнительных моментов:
Читайте также: