J'utilise la bibliothèque de persistance de salle d'Android à partir des composants d'architecture Android récemment annoncés sur Google I/O. Les choses semblent fonctionner, mais j'obtiens l'erreur suivante:
Avertissement: la colonne tagId fait référence à une clé étrangère mais elle ne fait pas partie d'un index. Cela peut déclencher des analyses complètes de table chaque fois que la table parent est modifiée, il est donc fortement conseillé de créer un index qui couvre cette colonne.
Ma base de données comporte 3 tables: Note
, Tag
et JoinNotesTags
. Notes to Tags est une relation plusieurs-à-plusieurs, d'où la table JoinNotesTags pour gérer le mappage. Les tableaux sont simples:
Note.id
Et Tag.id
Sont les deux clés primairesJoinNotesTags.noteId
Références Note.id
JoinNotesTags.tagId
Références Tag.id
Les contraintes de clé étrangère sont définies sur la table JoinNotesTags
. Pour référence, voici l'instruction CREATE TABLE
Pour la table JoinNotesTags
:
"CREATE TABLE IF NOT EXISTS `JoinNotesTags` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`noteId` INTEGER,
`tagId` INTEGER,
FOREIGN KEY(`noteId`) REFERENCES `Note`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE ,
FOREIGN KEY(`tagId`) REFERENCES `Tag`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
)"
Et voici l'annotation @Entity
Correspondante pour cette classe:
@Entity(
indices = arrayOf(Index(value = *arrayOf("noteId", "tagId"), unique = true)),
foreignKeys = arrayOf(
ForeignKey(
entity = Note::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("noteId"),
onDelete = ForeignKey.CASCADE),
ForeignKey(
entity = Tag::class,
parentColumns = arrayOf("id"),
childColumns = arrayOf("tagId"))
)
)
Comme vous pouvez le voir dans l'annotation @Entity
, tagId
is inclus dans un index composite unique avec noteId
. J'ai confirmé que cet index est également correctement défini dans le fichier de schéma json généré automatiquement:
"CREATE UNIQUE INDEX `index_JoinNotesTags_noteId_tagId`
ON `JoinNotesTags` (`noteId`, `tagId`)"
Donc, ma question: cet avertissement est-il simplement un bogue dans la bibliothèque de salle (encore à version alpha) - c'est-à-dire que l'analyse au moment de la compilation manque le fait que tagId
fait partie de cet index composite? Ou ai-je vraiment un problème d'indexation que je dois résoudre afin d'éviter des analyses de table complètes?
Lorsque vous modifiez la table Tag
, la base de données peut avoir besoin de rechercher les lignes correspondantes dans la table JoinNotesTags
. Pour être efficace, ceci nécessite un index sur la colonne tagId
.
Votre index composite n'est pas utile pour cela; en raison de la façon dont les index fonctionnent , la ou les colonnes à rechercher doivent être les colonnes les plus à gauche de l'index.
Vous devez ajouter un index uniquement sur la colonne tagId
. (Vous pourriez permuter l'ordre des colonnes dans l'index composite, mais vous auriez alors le même problème avec noteId
.)
Vous devez ajouter un index aux colonnes pour des requêtes plus rapides Voici un exemple
@Entity(indices = {@Index("artist_id")})
public class Artist{
@NonNull
@PrimaryKey
@ColumnInfo(name = "artist_id")
public String id;
public String name;
}
en code kotlin:
avant
@Expose
@SerializedName("question_id")
@ColumnInfo(name = "question_id")
var questionId: Long
après
@Expose
@SerializedName("question_id")
@ColumnInfo(name = "question_id", index = true) //just add index = true
var questionId: Long