在一个查询中加载引用数据的有效方法

时间:2015-06-11 21:31:53

标签: sqlite

我的应用程序使用数据库来保存其数据。我的表Objects看起来像

localID  |   title   |  content
1            Test       "1,embed","3,embed","5,append"

和另一个看起来像

的表Contents
localID  |  content
1           Alpha
2           Beta
3           Gamma
4           Delta
5           Epsilon

主要应用程序在主线程中运行,整个数据库在第二个线程中运行。因此,如果我的应用程序加载,我想将每个记录(QSqlRecord)传递给主线程,在那里进一步处理(加载到实际对象中)。我通过信号传递该记录。但我的数据分为2个表。我想返回一个包含两者的记录,可能类似于一个连接:

localID  |   title   |  content
1            Test       "Alpha,embed","Gamma,embed","Epsilon,append"

所以这样,只有一个线程返回值后,我会立即得到所有需要的信息。如果没有组合,我将不得不为每个引用的内容调用数据库。 我希望数据库包含少于100.000条记录,但有些内容可能很大(文件保存为blob,例如大小为300 MB左右的书)。

我有两个问题:

  • (如何)我可以这样在查询中(有效地)加入表吗?
  • 我是否也非常关注线程并应该使其成为单线程?  这样我就不需要打扰多个读取请求了。

作为sidenode,这是我在数据库管理员上的第一篇文章,我对这个网站不太确定,或者Stackoverflow是正确的问题。

1 个答案:

答案 0 :(得分:0)

对于任何实际问题,请在评论中使用@Vérace推荐的方式,
即“链接”表。就是这样。

但是,如果您被迫保留数据库结构
或为了好玩 或者用于学习(由迁移标题指示),
然而,学习肮脏的技巧,而不是良好的设计...... 看看这个:

select
    localID, title,
(      
    with recursive cnt(x) as
    (    select ','||a.content 
       union all 
         select replace(x, '"'||b.localID||',', '_"'||b.content||',') 
           from cnt, toy2 as b
    )
    select replace('_"'||replace(x, ',_"', ',"'), '_","', '"') from cnt 
    where not x like '%,"%' LIMIT 1
) as 'content' from toy as a; 
  • 使用递归方法灵活地使用 (不对AlphaBeta表中的条目数或其使用数量进行假设)
    用希腊语替换数字
  • 使用“_”命名方案来创建结束条件
  • 在内容前加上“_”,以便对其进行处理 并配合最终条件
  • 清理所需输出的结束条件“_”
  • 输出行开头的清理特例
  • 与其他所需输出一起选择递归结果

请注意您的表格自然不包含“__”或“_”的假设。如果发生这种情况,请选择更多“奇怪”的字符串。如果你的表中有各种各样的字符串,那么你看一下Verace所说的“发生灾难”的一个非常简洁的例子。实际上,这个非平凡的解决方案本身可能是一场灾难。

输出(.headers on.mode column):

localid     title       content
----------  ----------  --------------------------------------------
1           Test        "Alpha,embed","Gamma,embed","Epsilon,append"
2           mal         "Beta,append","Delta,embed"

这是我的mcve(.dump),还有一行“mal”用于测试目的:

BEGIN TRANSACTION;
CREATE TABLE toy (localid int, title varchar(20), content varchar(100));
INSERT INTO toy VALUES(1,'Test','"1,embed","3,embed","5,append"');
INSERT INTO toy VALUES(2,'mal','"2,append","4,embed"');
CREATE TABLE toy2 (localID int, content varchar(10));
INSERT INTO toy2 VALUES(1,'Alpha');
INSERT INTO toy2 VALUES(2,'Beta');
INSERT INTO toy2 VALUES(3,'Gamma');
INSERT INTO toy2 VALUES(4,'Delta');
INSERT INTO toy2 VALUES(5,'Epsilon');
COMMIT;

SQLite 3.18.0 2017-03-28 18:48:43