Почему одновременные записи не разрешены в базе данных SQLite?

79

Я занимаюсь программированием баз данных, используя Java с SQLite.

Я обнаружил, что только одно соединение одновременно с базой данных имеет возможность записи, в то время как многие соединения одновременно имеют возможность чтения.

Почему архитектура SQLite была разработана таким образом? Пока две записываемые вещи не записываются в одно и то же место в базе данных, почему две записи не могут происходить одновременно?

Стальной подносок
источник
5
Потому что SQLite был разработан, чтобы быть «облегченным». Низкая память и низкая обработка с производительностью. Подумайте, как заставить SQLite обрабатывать несколько записей в одном и том же файле. Текущий дизайн прост в реализации - весь файл заблокирован, и другим приходится ждать. Для обработки параллелизма записи на более низком уровне детализации требуется блокировка строк / страниц, которую вы получаете от RDMS. Если требование требует параллелизма записи, то SQLite не является кандидатом, и вместо этого вам следует обратиться к упрощенной СУБД: en.wikipedia.org/wiki/…
Томас Карлайл,

Ответы:

157

Поскольку «множественные одновременные записи» гораздо, намного сложнее выполнить в ядре базы данных, чем в режиме «один-пишущий-несколько-читатель». Это выходит за рамки параметров проектирования SQLite, и его включение, вероятно, подорвет восхитительно небольшой размер и простоту SQLite.

Поддержка высокой степени параллелизма записи является отличительной чертой таких больших баз данных, как DB2, Oracle, SQL Server, MySQL, PostgreSQL, NonStop SQL и Sybase. Но это технически сложно осуществить, требуя обширных стратегий управления и оптимизации параллелизма, таких как блокировка базы данных, таблицы и строки или, в более современных реализациях, управление многовариантным параллелизмом . Исследования по этой проблеме / требованию обширны и уходят вглубь десятилетий .

У SQLite совершенно иная философия проектирования, чем у большинства тех серверно-ориентированных СУБД, которые поддерживают несколько программ записи. Он предназначен для того, чтобы передать возможности SQL и реляционной модели отдельным приложениям и, в действительности, быть встраиваемым в каждое приложение. Эта цель требует значительных компромиссов. Не добавление значительной инфраструктуры и накладных расходов, необходимых для обработки нескольких одновременно работающих авторов, является одним из них.

Философия может быть подытожена утверждением на соответствующей странице использования SQLite :

SQLite не конкурирует с базами данных клиент / сервер. SQLite конкурирует с fopen ().

Джонатан Юнис
источник
41
+1. SQLite - это внутренняя база данных. Центрального арбитра не существует, как в серверной БД. Авторы должны были бы напрямую сотрудничать и доверять друг другу. Один злой писатель может нанести ущерб, просто не сотрудничая.
Йорг Миттаг
12
Кроме того, некоторые среды, в которых выполняется SQLite, могут даже не поддерживать несколько процессов.
david25272
1
Предположительно, злонамеренная запись уже может нанести ущерб, не сотрудничая. Они не могут использовать код SQLite для этого, но у них может быть свой собственный код, который может быть просто вызовом unlink ()
bdsl
12
В параллельных приложениях не так уж много среднего. Либо вы получаете правильность параллелизма, согласованности и целостности данных практически 100% времени, в том числе в сложных условиях и крайних случаях, либо нет. Если вы этого не сделаете, это хрупкий, медленный и подверженный сбоям, и люди перестают доверять ему очень быстро. Но сделать это правильно, как ни крути, трудно. Существует не так много обстоятельств, при которых авторы могут, при отсутствии поддержки ядра, координировать чередующиеся записи самостоятельно.
Джонатан Юнис
8
@bdsl Базы данных любого рода должны предполагать, что авторы не будут вести себя хорошо, поэтому они не теряют данные. Авторы SQLite позиционируют его как конкурента fopen(), поэтому рассмотрим все проблемы, которые возникают при одновременной записи в простой текстовый файл.
Blrfl
12

Потому что нет сервера, который мог бы сказать, должны ли вещи быть записаны в то же место или нет. Есть только два процесса, пытающихся записать в файл.

Как указано в комментарии, одновременная запись также может поддерживаться внутренним потоком. Не уверен, насколько хорошо это будет работать (не думал об этом тоже). В любом случае, вот почему SQLite не использует потоки: доктор Хипп считает, что потоки - это зло.

Тот факт, что DR Hipp считает потоки злыми, задокументирован в FAQ по SQLite .

Goyo
источник
2
Это объясняет техническую причину, по которой одновременные записи не допускаются, но не то, почему было принято проектное решение.
Роберт Харви
3
Решение спроектировать SQLite так, чтобы он обрабатывал только одну запись за раз.
Роберт Харви
7
@ Goyo сервер не обязан обрабатывать одновременные записи: так как сервер базы данных - это отдельный процесс, может быть отдельный поток внутри SQLite, который служит той же цели. Роберт Харви прав: команда разработчиков SQLite приняла решение о разработке, и оно не имеет ничего общего со способностью одной библиотеки обрабатывать параллельные записи (потому что теоретически это возможно).
1
Этот ответ мне кажется правильным. Для обработки одновременных записей, кажется, потребуется сервер или многопоточная реализация sqlite. Поскольку оба из них были исключены другими проектными решениями, выполнение одновременных записей было бы чрезвычайно трудным.
JPA
5
@jpa: SQLite удается синхронизировать блокировку между несколькими процессами / потоками без «сервера». «Сервер» не требуется - используется предоставляемая ОС блокировка / синхронизация / IPC / все, что достаточно, но получается комплекс очень быстро. «Внутренняя тема», упомянутая в посте, не имеет смысла.
Mat