Ответ 1
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 читайте документацию.