我希望使用SQLite FTS3(实际上是FTS4)来索引一个拥有整数列的表格,概念上类似于这样:
CREATE VIRTUAL TABLE whole (document INTEGER, page INTEGER, content TEXT,
UNIQUE(document, page)) USING fts4();
我知道FTS3将除rowid以外的所有列视为TEXT,因此我需要使用两个表:
CREATE VIRTUAL TABLE data USING fts4();
CREATE TABLE metadata(document INTEGER, page INTEGER, UNIQUE(document, page));
我希望能够查询文档或给定文档中的页面。
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';
我认为NATURAL JOIN需要确保行标保持同步,但最好的方法是什么?我应该使用FOREIGN KEY或其他约束吗?子查询比联接更好吗?
我想要对已经在数据库中的文档和页面进行插入以覆盖文本内容。这是否可以通过SQL进行编程或者是否必须检查信息表中的行是否已存在?
我还想删除给定文档的两个表中的数据,有没有一种方法可以用单个语句实现?
非常感谢任何建议,但由于我是SQL新手,尤其欢迎代码示例!
更新:我不确定如何在此处创建外键约束。如果我选择将metadata
作为父表(在没有双向约束的情况下这将是我的首选):
PRAGMA foreign_keys = ON;
CREATE TABLE metadata (document INTEGER, page INTEGER);
CREATE VIRTUAL TABLE data USING fts4(content TEXT, docid REFERENCES metadata);
我遇到了 Error: vtable constructor failed: data
错误(并不奇怪,因为docid
是rowid
的别名,但是除rowid
之外,所有列都必须是TEXT
类型,所以我不能使用另一列)。
而如果我尝试倒过来:
PRAGMA foreign_keys = ON;
CREATE VIRTUAL TABLE data USING fts4();
CREATE TABLE metadata (document INTEGER, page INTEGER, docid REFERENCES data);
表格构建成功,但如果我尝试:
INSERT INTO data (docid, content) VALUES (123, 'testing');
INSERT INTO metadata (docid, document, page) VALUES (123, 12, 23);
我遇到了错误:外键不匹配
。