Me gustaría utilizar SQLite FTS3 (FTS4, en realidad) para indexar una tabla con columnas de tipo entero, conceptualmente algo como esto:FTS3 con columnas INTEGER
CREATE VIRTUAL TABLE whole (document INTEGER, page INTEGER, content TEXT,
UNIQUE(document, page)) USING fts4();
Sé que FTS3 trata a todos los demás columnas que rowid como texto, así que voy a tener que usar dos tablas:
CREATE VIRTUAL TABLE data USING fts4();
CREATE TABLE metadata(document INTEGER, page INTEGER, UNIQUE(document, page));
Quiero ser capaz de consultar los documentos, o para páginas en un documento dado:
SELECT DISTINCT document FROM metadata NATURAL JOIN data WHERE content MATCH 'foo';
SELECT page FROM metadata NATURAL JOIN data
WHERE document = 123 AND content MATCH 'foo';
Creo que NATURAL JOIN requiere que me asegure de que los rowids se mantengan sincronizados, pero ¿cuál es la mejor manera de hacerlo? ¿Debería usar una FOREIGN KEY u otra restricción? ¿Sería mejor una sub selección que una unión?
Me gustaría una inserción para un documento y página que ya están en la base de datos para sobrescribir el contenido del texto. ¿Es posible hacerlo mediante SQL o tendré que verificar si la fila ya existe en la tabla de información?
También voy a querer ELIMINAR DE ambas tablas para un documento dado - ¿hay alguna manera de hacer esto en una sola declaración?
Todos los consejos recibidos con gratitud, pero como soy un novato en SQL, los ejemplos de código son especialmente apreciados.
Actualización: No tengo muy claro cómo puedo crear una restricción de clave externa aquí. Si decido metadata
como la tabla primaria (que sería mi preferencia, en ausencia de una restricción bidireccional):
PRAGMA foreign_keys = ON;
CREATE TABLE metadata (document INTEGER, page INTEGER);
CREATE VIRTUAL TABLE data USING fts4(content TEXT, docid REFERENCES metadata);
consigo Error: vtable constructor failed: data
(como era de esperar, porque docid
es un alias para rowid
, pero por supuesto que puedo no use otra columna porque todas las columnas excepto rowid
deben ser TEXT
).
Mientras que si lo intento a la inversa:
PRAGMA foreign_keys = ON;
CREATE VIRTUAL TABLE data USING fts4();
CREATE TABLE metadata (document INTEGER, page INTEGER, docid REFERENCES data);
la construcción de la tabla tiene éxito, pero si trato:
INSERT INTO data (docid, content) VALUES (123, 'testing');
INSERT INTO metadata (docid, document, page) VALUES (123, 12, 23);
consigo Error: foreign key mismatch
.
¿Se las arregló para crear tablas virtuales con claves externas? – Maragues
@Maragues No, y tampoco puedes hacer cumplir las mismas restricciones; consulta mi respuesta a continuación. Las tablas virtuales AFAICT son solo programas con interfaces SQL. – hatfinch