При использовании поставщика контента для доступа к базе данных SQLite
- Лучше ли вам иметь поставщика контента для каждой таблицы или использовать его для всех таблиц?
- Как обрабатывать отношения "один ко многим" при создании новых записей?
При использовании поставщика контента для доступа к базе данных SQLite
ContentProvider не является базой данных
ContentProvider - это способ публичного (или полупубличного) доступа к данным в качестве контента. Это можно сделать несколькими способами: через доступ к файлам, SQLite или даже доступ к сети. ContentProvider сам по себе не является базой данных, но вы можете запрограммировать для нее базу данных. У вас также может быть несколько ContentProviders, которые обращаются к одной и той же базе данных, но распределяют разные уровни доступа или же содержимое по-разному в зависимости от запрашивающего.
То, что вы действительно спрашиваете, не является вопросом ContentProvider, а вопросом базы данных "Как обрабатывать отношения в базе данных SQLite", потому что ContentProvider не использует код базы данных, если вы не скажете его через SQLiteOpenHelper
и другие аналогичные классы. Таким образом, вам просто нужно запрограммировать доступ к базе данных правильно, и ваша база данных SQLite будет работать по желанию.
База данных - это база данных
В старые времена базы данных были просто плоскими файлами, где каждая таблица часто являлась своей собственной сущностью, чтобы обеспечить рост. Теперь, с СУБД, есть очень мало оснований для этого. SQLite подобен любой другой платформе базы данных в этом отношении и может содержать столько таблиц, сколько у вас есть места для их хранения.
SQLite
Существуют некоторые функции, которые SQLite хорошо обрабатывает, некоторые из них обрабатываются - но не очень хорошо, а некоторые - вообще не обрабатываются. Отношения - это одна из тех вещей, которые были исключены из некоторых версий Android SQLite, поскольку она поставляется без поддержки внешнего ключа. Это была очень запрошенная функция, и она была добавлена в SQLite 3.6.22, которая не отправлялась до Android 2.2. Тем не менее, все еще есть много сообщений об ошибках, но в самых ранних воплощениях.
Android pre 2.2
К счастью, будучи совместимым с SQL и простой СУБД (а не RDBMS в это время), есть несколько простых способов обойти это, в конце концов, внешний ключ - это просто поле в другой таблице.
INSERT
и UPDATE
, создавая CONSTRAINT
, когда используете оператор CREATE TABLE
._id
, чтобы получить свой внешний ключ.SELECT
, используя INNER JOIN
, тем самым обеспечив псевдосвязь.Так как версия SQLite SQLite не обеспечивает прямое взаимодействие, если вы хотите CASCADE ON DELETE
, вам придется делать это вручную. Но это можно сделать с помощью другого простого оператора SQL. Я по существу написал свою собственную библиотеку, чтобы обеспечить соблюдение таких отношений, поскольку все это нужно делать вручную. Однако я должен сказать, что эффективность SQLite и SQL в целом делает это очень быстрым и легким.
По сути, процесс для любого принудительного отношения выглядит следующим образом:
JOIN
.INSERT
используйте CONSTRAINT
в поле внешнего ключа NOT NULL
UPDATE
в поле первичного ключа, являющемся внешним ключом в другом TABLE
, запустите второй UPDATE
в соответствующем TABLE
, который имеет внешний ключ. (ОБНОВЛЕНИЕ КАСКАДА)DELETE
с теми же параметрами выполните еще один DELETE
, где foreign_key = _id
(убедитесь, что вы сначала получили _id
перед тем, как DELETE
строка).Android 2.2 +
Внешние ключи поддерживаются, но по умолчанию отключены. Сначала вы должны включить их:
db.execSQL("PRAGMA foreign_keys=ON;");
Затем вам нужно создать связь TRIGGER
. Это делается при создании TABLE
, а не отдельного оператора TRIGGER
. См. Ниже:
// Added at the end of CREATE TABLE statement in the MANY table
FOREIGN KEY(foreign_key_name) REFERENCES one_table_name(primary_key_name)
Для получения дополнительной информации о SQLite и его возможностях посетите официальный сайт SQLite. Это важно, поскольку у вас нет всех JOIN
, которые вы делаете в других СУБД. Для получения конкретной информации о классах SQLite в Android читайте документацию.
Что касается первого вопроса: вам не нужно создавать контент-провайдера для каждой таблицы. Вы можете использовать его с несколькими таблицами, но сложность провайдера увеличилась с каждой таблицей.
Поставщик контента примерно эквивалентен концепции базы данных. У вас будет несколько таблиц в базе данных, поэтому наличие нескольких таблиц в вашем контент-провайдере имеет смысл.
От одного до многих отношений можно обращаться так же, как в любой другой базе данных. Используйте ссылки и внешние ключи, как и с любой другой базой данных. Вы можете использовать такие вещи, как CASCADE ON DELETE, чтобы убедиться, что записи удалены, когда записи, которые они ссылаются в других таблицах, также удаляются.