tutorial - Aviso de compilación en la sala de Android sobre la columna en clave externa que no forma parte de un índice. Qué significa eso?
room database android (3)
Cuando modifica la tabla de Tag
, es posible que la base de datos deba buscar las filas correspondientes en la tabla JoinNotesTags
. Para ser eficiente, esto requiere un índice en la columna tagId
.
Su índice compuesto no es útil para eso; Debido a la forma en que funcionan los índices , las columnas que se deben buscar deben ser las columnas más a la izquierda en el índice.
Debería agregar un índice solo en la columna tagId
. (Puede cambiar el orden de las columnas en el índice compuesto, pero luego tendrá el mismo problema con noteId
).
Estoy usando la biblioteca de persistencia de habitaciones de Android de los componentes de la arquitectura de Android anunciada recientemente en Google I / O. Las cosas parecen estar funcionando, pero obtengo el siguiente error:
Advertencia: la columna tagId hace referencia a una clave externa, pero no forma parte de un índice. Esto puede desencadenar exploraciones completas de la tabla siempre que se modifique la tabla principal, por lo que le recomendamos que cree un índice que cubra esta columna.
Mi base de datos tiene 3 tablas: Note
, Tag
y JoinNotesTags
. Notes to Tags es una relación de muchos a muchos, de ahí la tabla JoinNotesTags para manejar la asignación. Las mesas son sencillas:
-
Note.id
yTag.id
son ambas claves principales -
JoinNotesTags.noteId
referencesNote.id
-
JoinNotesTags.tagId
referencesTag.id
Las restricciones de clave externa se definen en la tabla JoinNotesTags
. Para referencia, aquí está la declaración CREATE TABLE
para la tabla 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
)"
Y aquí está la correspondiente anotación @Entity
para esa clase:
@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"))
)
)
Como puede ver en la anotación @Entity
, tagId
se incluye en un índice único compuesto junto con noteId
. He confirmado que este índice también está correctamente definido en el archivo de esquema json generado automáticamente:
"CREATE UNIQUE INDEX `index_JoinNotesTags_noteId_tagId`
ON `JoinNotesTags` (`noteId`, `tagId`)"
Entonces, mi pregunta: ¿es esta advertencia solo un error en la biblioteca de la sala (aún de versión alfa)? Es decir, en el análisis en tiempo de compilación falta el hecho de que tagId
es parte de este índice compuesto. ¿O realmente tengo un problema de indexación que debo resolver para evitar exploraciones de tabla completa?
Debe agregar un índice a las columnas para consultas más rápidas Aquí hay un ejemplo
@Entity(indices = {@Index("artist_id")})
public class Artist{
@NonNull
@PrimaryKey
@ColumnInfo(name = "artist_id")
public String id;
public String name;
}
cuando en el código kotlin:
antes de
@Expose
@SerializedName("question_id")
@ColumnInfo(name = "question_id")
var questionId: Long
después
@Expose
@SerializedName("question_id")
@ColumnInfo(name = "question_id", index = true) //just add index = true
var questionId: Long