查找具有特定子行组合的父级 - SQLite与Python

时间:2016-08-06 00:54:53

标签: python sql database sqlite

这个问题有几个部分。我在Python 2.7中使用sqlite3,但我不太关心确切的语法,更多的是我需要使用的方法。我认为提出这个问题的最好方法是描述我当前的数据库设计,以及我想要实现的目标。我是一般的数据库新手,所以如果我不总是使用正确的命名法,我会道歉。

我正在建模制冷系统(使用Modelica - 知道并不重要),我正在使用数据库管理输入数据,结果数据和用于该数据的模型。

我的顶级父表是Model,其中包含以下列:

id, name, version, date_created

Model下的我的子表名为Design。它用于为设计输入参数和使用的模型的每个组合创建唯一ID。它包含的列是:

id, model_id, date_created

然后,我在Design下有两个子表,一个名为Input,另一个名为Result。我们现在可以看一下Input,因为一个例子就足够了。输入列是:

id, value, design_id, parameter_id, component_id

parameter_idcomponent_id是其自己的表的外键。Parameter表包含以下列:

id, name, units 

Parameter under名称的一些示例行是:长度,宽度,速度,温度,压力(还有几十个)。 Component表包含以下列:

id, name

名称下的Component的一些示例行是:compressor,heat_exchanger,valve。

最终,在我的程序中,我想在数据库中搜索特定的设计。我希望能够搜索特定设计,以便能够获取该设计的特定结果,或者知道先前是否已经运行过具有该设计的模型模拟,以避免重新运行相同的数据点。

我还希望能够获取给定设计的所有参数,并将其插入到我在Python中创建的类中,然后使用该类为我的模型提供输入。如果它有助于解决问题,我创建的类基于组件。因此,例如,我有一个压缩器类,其属性如compress.speed,compressor.stroke,compressor.piston_size。这些属性中的每一个都应该在Parameter表中有自己的行。

那么,我如何有效地查询这个数据库,以查找是否有一个设计与长列表(假设100+)具有特定值的参数相匹配?就像旁注,我的朋友帮我设计了这个数据库。他了解数据库,但不是我的应用程序。我有可能为我想要完成的事情设计得很差。

这是一个简单的图片,试图将特定值的某些参数组合映射到design_id,为简单起见,我已取出component_id:

Picture of simplified tables

1 个答案:

答案 0 :(得分:2)

只需加入必要的表格即可。您的模式正确地反映了规范化(将表分成逻辑分组)并且可以扩展为一对多关系。具体来说,回答你的问题 - 那么,我如何有效地查询这个数据库,以找出是否有一个设计与长列表(让我们假设100+)具有特定值的参数相匹配? - 考虑以下方法:

内部加入Where子句

对于少数参数,请使用带有WHERE...IN()子句的内部联接。下面返回由输入参数表连接的设计字段,针对特定参数名称进行过滤,您可以将Python作为参数化值传递给参数化值,即使在迭代中也是如此循环:

SELECT d.id, d.model_id, d.date_created
FROM design d
INNER JOIN input i ON d.id = i.design_id
INNER JOIN parameters p ON p.id = i.parameter_id
WHERE p.name IN ('param1', 'param2', 'param3', 'param4', 'param5', ...)

内部加入临时表

如果长列表中的值超过100,请考虑将参数表过滤为特定参数值的临时表:

# CREATE EMPTY TABLE (SAME STRUCTURE AS parameters)
sql = "CREATE TABLE tempparams AS SELECT id, name, units FROM parameters WHERE 0;"
cur.execute(sql)
db.commit()

# ITERATIVELY APPEND TO TEMP
for i in paramslist:                                  # LIST OF 100+ ITEMS
    sql = "INSERT INTO tempparams (id, name, units) \
           SELECT p.id, p.name, p.units \
           FROM parameters p \
           WHERE p.name = ?;"
    cur.execute(sql, i)                               # CURSOR OBJECT COMMAND PASSING PARAM
    db.commit()                                       # DB OBJECT COMMIT ACTION 

然后,使用包含特定参数的新临时表连接主设计输入表:

SELECT d.id, d.model_id, d.date_created
FROM design d
INNER JOIN input i ON d.id = i.design_id
INNER JOIN tempparams t ON t.id = i.parameter_id 

同样的过程也适用于组件表。

*将图片移至问题部分