2011-09-21 10 views
10

各テーブルのコンテンツプロバイダーを持っているか、すべてのための1つを使用するためにSQLiteデータベースへのアクセスのためにアンドロイド:各テーブルののContentProvider /ハンドリング1対多の関係

  1. それが良い習慣ですが、コンテンツプロバイダを使用してテーブル?
  2. 新しいレコードを作成するときに1対多の関係を処理する方法は?
+0

"人と人との関係をどのように扱うか"という意味について、もう少し詳しく説明できますか?SQLデータベース設計、CREATEステートメントについて話しているのですか、コンテンツプロバイダ側でこれを行う方法がわかりますか? – AGrunewald

答えて

15

AのContentProviderは

AのContentProviderの方法であるデータベースではないコンテンツとして公に(または半公的)アクセスデータへ。これは、ファイルアクセス、SQLite、Webアクセスなど、さまざまな方法で行うことができます。 ContentProvider自体はデータベースではありませんが、データベースのプログラミングが可能です。同じデータベースにアクセスする複数のContentProviderを持つこともできますが、要求者に応じてさまざまなレベルのアクセスや同じコンテンツをさまざまな方法で配布できます。

あなたが本当に求めていることのContentProviderの質問ではありませんが、SQLiteOpenHelperと類似した他の経由にそれを指示しない限りのContentProviderは、任意のデータベース・コードを使用しないため、データベースの質問は、「どのようにSQLiteのデータベース内の関係を処理するために」クラス。したがって、データベースアクセスを正しくプログラムするだけで、SQLiteデータベースは必要に応じて動作します。

データベースは昔データベース

で、データベースは、各テーブルには、成長を可能にするために、多くの場合、独自のエンティティただけでフラットファイルでした。今、DBMSでは、これを行う理由はほとんどありません。 SQLiteは他のデータベースプラットフォームと同じように、テーブルを格納するスペースを確保できるだけの数のテーブルを格納することができます。

SQLiteの

は、それが扱ういくつかのことを、SQLiteのはうまく処理し、特定の機能があります - もなく、そしていくつかは、それがすべてで処理しないこと。関係は、外部キーのサポートなしで出荷されたため、AndroidのSQLiteのいくつかのバージョンから除外されたものの1つです。これは高度に要求された機能であり、Android 2.2まで出荷されなかったSQLite 3.6.22で追加されました。しかし、初期の化身ではまだ多くのバグが報告されています。

アンドロイド事前2.2

はありがたいことに(この時点ではないRDBMS)に準拠しており、シンプルなDBMS SQLされて、この問題を回避するためにいくつかの簡単な方法がありますが、すべての後に、外部キーがでちょうどフィールドです別のテーブル。

  1. あなたは、あなたのCREATE TABLEステートメントを使用する場合CONSTRAINT Sを作成することにより、データベースINSERTUPDATE文を強制することができます。
  2. 外部キーを取得するために、適切な_idを他のテーブルに問い合わせることができます。
  3. 適切なSELECTステートメントを使用してソーステーブルを照会し、INNER JOINを使用して疑似関係を実行できます。

AndroidのバージョンのSQLiteは直接関係を強制しないので、CASCADE ON DELETEにする必要があります。手動で行う必要があります。しかし、これは別の簡単なSQL文で行うことができます。私は本質的に、この種の関係を強制するために自分のライブラリを作成しました。しかし、SQLiteとSQLの効率が非常に迅速かつ簡単になると言わざるを得ない。次のように

は本質的には、任意の強制関係のためのプロセスが行く:

  • JOINを使用し、外部キーを必要とするクエリで。 INSERT
  • は、別のTABLEの外部キーである主キーフィールドにUPDATENOT NULL
  • の外部キーフィールドにCONSTRAINTを使用する外部キーを持つ関連TABLEに第UPDATEを実行します。 (カスケード更新)
  • 同じパラメータのDELETEの場合は、DELETEのどこにforeign_key = _idがあるかを確認してください(最初にDELETE行になる前に_idになるようにしてください)。

のAndroid 2.2以降

外部キーはサポートされていますが、デフォルトでオフになっています。まず、それらを有効にする必要があります。

db.execSQL("PRAGMA foreign_keys=ON;"); 

次に、関係TRIGGERを作成する必要があります。これは、別のTRIGGERステートメントではなく、TABLEを作成するときに行われます。以下を参照してください。

// 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 official siteを参照してください。これは、あなたが他のRDBMSで行うすべてのJOINを持っていないので重要です。 AndroidのSQLiteクラスに関する具体的な情報については、the documentationをご覧ください。

+0

どのようなクラッキングの答え、よかった。私は多くのデータベース(MySQL、MSSQL、Postgres、Ingres、SQLiteなど)に精通していますが、これは私の最初のアンドロイドアプリです.JAVAについてもっと忘れてしまいました。本当に苦労しているのはアンドロイド特有の構文ですが、私はそれをより明確にする必要がありましたが、私の知識の中で特に重大な欠点を強調しました。私はあなたの答えを受け入れるでしょう。私は今、より具体的な質問をフレーズするのに十分な情報を持っています。そして、私は他の人がこれを非常に役に立つと感じるでしょう。再度ありがとう – jamesc

+0

あなたは大歓迎です。こちらこそ、ありがとう。 –

5

最初の質問としては、すべてのテーブルのコンテンツプロバイダを作成する必要はありません。複数のテーブルを使用することもできますが、各テーブルのプロバイダの複雑さが増します。

+0

ありがとうございます、私はすべての質問に答えがありませんが、あなたの情報は非常に高く評価されているので、私はあなたの質問に答えとしてマークしたくありません – jamesc

+0

あなたは大歓迎です。 –

1

コンテンツプロバイダは、データベースの概念とほぼ同じです。データベースには複数のテーブルがあるので、コンテンツプロバイダに複数のテーブルを置くことは理にかなっています。

1対多リレーションシップは他のデータベースと同様に処理できます。他のデータベースと同様に、参照と外部キーを使用します。 CASCADE ON DELETEのようなものを使用して、他のテーブルで参照するレコードも削除されたときにレコードが削除されるようにすることができます。