Android:每个表的ContentProvider /处理一对多关系

jam*_*esc 10 android one-to-many android-contentprovider

使用内容提供程序进行SQLite数据库访问时

  1. 为每个表创建一个内容提供程序或为所有表使用一个内容提供程序更好吗?
  2. 如何在创建新记录时处理一对多关系?

Fuz*_*gic 15

ContentProvider不是数据库

ContentProvider是一种公开(或半公开)访问数据作为内容的方法.这可以通过多种方式完成,通过文件访问,SQLite甚至Web访问.ContentProvider本身不是数据库,但您可以为其编写数据库.您可能还有多个ContentProviders访问同一个数据库,但根据请求者以不同方式分发不同级别的访问或相同内容.

您真正要求的不是ContentProvider问题,而是数据库问题"如何处理SQLite数据库中的关系",因为ContentProvider不使用任何数据库代码,除非您通过一个SQLiteOpenHelper和其他类似的类告诉它.因此,您只需正确编程数据库访问,您的SQLite数据库就可以正常工作.

数据库是一个数据库

在过去,数据库只是简单的文件,其中每个表通常是自己的实体,以允许增长.现在,使用DBMS,没有什么理由可以做到这一点.SQLite就像这方面的任何其他数据库平台一样,可以容纳尽可能多的表,因为你有空间来容纳它们.

SQLite的

SQLite处理的某些功能很好,有些功能可以处理 - 但不是很好,还有一些功能根本无法处理.关系是Android SQLite的某些版本中遗漏的东西之一,因为它没有外键支持.这是一个高度要求的功能,它在SQLite 3.6.22中添加,直到Android 2.2才发布.然而,在其最早的版本中,仍然有许多报道它的错误.

Android前2.2

值得信赖的是SQL兼容和简单的DBMS(此时不是RDBMS),有一些简单的方法可以解决这个问题,毕竟,外键只是另一个表中的一个字段.

  1. 您可以在使用语句时通过创建s 来强制执行数据库INSERT和语句.UPDATECONSTRAINTCREATE TABLE
  2. 您可以查询其他表_id以获取适当的外键.
  3. 您可以使用任何适当的SELECT语句查询源表INNER JOIN,从而强制执行伪关系.

由于Android的SQLite版本不直接强制执行关系,因此如果CASCADE ON DELETE您愿意,则必须手动执行.但这可以通过另一个简单的SQL语句来完成.我基本上编写了自己的库来强制执行这些关系,因为它必须手动完成.但是,我必须说,SQLite和SQL作为一个整体的效率使得这非常快速和简单.

从本质上讲,任何强制关系的过程如下:

  • 在需要外键的查询中,使用a JOIN.
  • 在一个INSERT使用a CONSTRAINT的外键字段NOT NULL
  • 在作为UPDATE另一个外键的主键字段上,在具有外键的相关键上TABLE运行第二个字段.(CASCADE UPDATE)UPDATETABLE
  • 对于DELETE具有相同参数的a,DELETE使用where where进行另一个参数foreign_key = _id(确保在行_id之前得到DELETE第一个).

Android 2.2+

支持外键,但默认情况下处于关闭状态.首先,你必须打开它们:

db.execSQL("PRAGMA foreign_keys=ON;");
Run Code Online (Sandbox Code Playgroud)

接下来,您必须创建关系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)
Run Code Online (Sandbox Code Playgroud)

有关SQLite及其功能的更多信息,请查看SQLite官方站点.这很重要,因为您没有JOIN在其他RDBMS中执行的所有操作.有关Android中SQLite类的特定信息,请阅读文档.


Igo*_*pov 5

至于第一个问题:您不需要为每个表创建内容提供程序.您可以使用多个表,但随着每个表的增加,提供程序的复杂性也会增加.