Android: ContentProvider для каждой таблицы / обработка отношений «один ко многим» - PullRequest
10 голосов
/ 21 сентября 2011

При использовании поставщика контента для доступа к базе данных SQLite

  1. Лучше ли иметь поставщика контента для каждой таблицы или использовать один для всех таблиц?
  2. Как обращатьсяотношения один ко многим при создании новых записей?

Ответы [ 3 ]

15 голосов
/ 22 октября 2011

ContentProvider не является базой данных

ContentProvider - это способ публичного (или полуобщественного) доступа к данным как контенту.Это может быть сделано несколькими способами, через доступ к файлам, SQLite или даже веб-доступ.ContentProvider сам по себе не является базой данных, но вы можете запрограммировать базу данных для него.У вас также может быть несколько ContentProviders, обращающихся к одной и той же базе данных, но распространяющих разные уровни доступа или одно и то же содержимое по-разному в зависимости от лица, запрашивающего запрос.

То, что вы на самом деле спрашиваете, это не вопрос ContentProvider, а база данныхвопрос «Как обрабатывать отношения в базе данных SQLite», потому что ContentProvider не использует код базы данных, если вы не передадите его через SQLiteOpenHelper и другие подобные классы.Итак, вам просто нужно правильно запрограммировать доступ к вашей базе данных, и ваша база данных SQLite будет работать так, как вам нужно.

База данных - это база данных

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

SQLite

Существуют определенные функции, которые SQLite обрабатывает хорошо, некоторые из них он обрабатывает - но не хорошо, а некоторые - что он вообще не обрабатывает.Отношения - это одна из тех вещей, которые были исключены из некоторых версий SQLite для Android, потому что они поставлялись без поддержки внешнего ключа.Это была очень востребованная функция, и она была добавлена ​​в SQLite 3.6.22, которая не поставлялась до Android 2.2.Тем не менее, есть много сообщений об ошибках, связанных с ним, но в его самых ранних воплощениях.

Android pre 2.2

К счастью, SQL-совместимость и простая СУБД (не СУБД на данный моментвремя), есть несколько простых способов обойти это, в конце концов, внешний ключ - это просто поле в другой таблице.

  1. Вы можете применить операторы базы данных INSERT и UPDATE, создавCONSTRAINT s при использовании вашего оператора CREATE TABLE.
  2. Вы можете запросить в другой таблице соответствующий _id, чтобы получить ваш внешний ключ.
  3. Вы можете запросить исходную таблицу с помощью любого соответствующего оператора SELECT, используя INNER JOIN, таким образомприменение псевдосвязи.

Поскольку версия SQLite для Android не предусматривает непосредственное применение взаимосвязей, если вы хотите CASCADE ON DELETE, вам придется делать это вручную.Но это можно сделать с помощью другого простого оператора SQL.По сути, я написал свою собственную библиотеку для обеспечения таких отношений, поскольку все это должно быть сделано вручную.Однако я должен сказать, что эффективность SQLite и SQL в целом делает это очень быстрым и легким.

По сути, процесс для любых принудительных отношений выглядит следующим образом:

  • В запросе, для которого требуется внешний ключ, используйте JOIN.
  • . В INSERT используйте CONSTRAINT в поле внешнего ключа NOT NULL
  • В * 1057.* в поле первичного ключа, которое является внешним ключом в другом 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, которые вы делаете в других RDBMS.Для получения конкретной информации о классах SQLite в Android прочитайте документацию .

5 голосов
/ 21 сентября 2011

Что касается первого вопроса: вам не нужно создавать контент-провайдера для каждой таблицы. Вы можете использовать несколько таблиц, но сложность поставщика увеличивается с каждой таблицей.

1 голос
/ 20 октября 2011

Поставщик контента примерно соответствует концепции базы данных.У вас будет несколько таблиц в базе данных, поэтому наличие нескольких таблиц в вашем поставщике контента имеет смысл.

Отношения «один ко многим» можно обрабатывать, как и в любой другой базе данных.Используйте ссылки и внешние ключи, как и в любой другой базе данных.Вы можете использовать такие вещи, как CASCADE ON DELETE, чтобы убедиться, что записи удаляются, когда записи, на которые они ссылаются в других таблицах, также удаляются.

...