这个问题有几个部分。我在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_id
和component_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:
答案 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
同样的过程也适用于组件表。
*将图片移至问题部分