繁体   English   中英

最佳实践数据库设计,用于通过相关表(多个左联接)跟踪进度

[英]best practice database design for tracking progress through related tables (multiple left joins)

我有一个不断发展的django数据库应用程序。

我们想跟踪样本的进展情况

sample ->  library -> machine -> statistics, etc. 

通常,从每个阶段到从左到右都是一对多的关系。

这是我的数据库架构的简化版本

table sample
id    
name  

table library 
id     
name 
sample_id  (foreign key to sample table) 

table machine 
id
name
status
library_id  (foreign key to library table)

table sample_to_projects 
sample_id
project_id

table library_to_subprojects
library_id 
subproject_id

到目前为止,一切正常,除了现在,项目都需要查看所有内容。 每个阶段都可以属于一个或多个项目。 我在项目和现有表之间添加了many_to_many关系。

我正在尝试创建一些视图以执行多个左连接并显示项目的示例进度。

sample A
sample B   library_1    machine_1   
sample B   library_2    machine_2
sample C   library_3

第一次尝试查询是这样的:

SELECT fields FROM
sample_to_projects , 
sample 
LEFT JOIN library ON sample.id = library.sample_id , 
library_to_project 
LEFT JOIN machine ON machine.library_id = library.id
WHERE 
    sample_to_project.project_id = 30 
    AND sample_to_project.sample_id = sample.id
    AND library_to_project.project_id = 30
    AND library_to_project.library_id = library_id

这里的问题是LEFT JOIN在WHERE子句之前完成。

因此,如果我们有一个属于project_A和project_B的样本。 如果样本中有一个针对project_B的库,但是我们想对project_A进行过滤,则LEFT JOIN不会为库列添加一行带有NULL的行(因为存在库)。 但是,这些行将被WHERE子句过滤掉,并且该示例不会显示。

reults filtering on project_A

sample_1(project_A, project_B)   library_A (project_A)
sample_1(project_A, project_B)   library_B (project_A, project_B)
sample_2(project_A, project_B)   library_C (project_B)  *this row gets filtered out, it should show only the sample details*

因此,我的解决方案是在完成LEFT JOIN之前创建一个子查询以连接其他(右侧)表。

SELECT fields FROM
     sample_to_projects , 
     sample 
     LEFT JOIN (
          SELECT library.id as lib_id , library.sample_id as smaple_id ,  library.name as lib_name , machine_name 
          FROM library , 
          lib_to_projects ,  
          machine         
     ) 
     AS join_table ON sample.id = join_table.sample_id 
     WHERE 
         sample_to_project.project_id = 30 
         AND sample_to_project.sample_id = sample.id

问题在于数据库的实际版本中还有更多的阶段,因此我将需要为每个LEFT JOIN做一个嵌套的子查询。 SQL将变得难以阅读的大型广告,我想知道在设计级别是否有更好的解决方案? 同样,它在Django模型中不能很好地工作(尽管如果我可以使用SQL,我会很高兴的)。

还是有人可以针对此类问题提出某种最佳实践的建议? 我敢肯定,将用户分组显示或类似显示肯定是相对常见的。 如果有人知道一种适合Django模型的方法,那就更好了。

为每个Project_Id创建单独的视图怎么办?

如果您按原样保留数据库结构,并在应用程序运行时将其添加到数据库中。 您可以为每个阶段或Project_Id创建一个单独的视图。 如果有30个阶段(Project_Id 1..30),则创建30个单独的视图。

添加新舞台时...创建一个新视图。

我不清楚您将其用于什么用途,但是您的用例似乎可以从数据透视表中受益。 Microsoft Excel和Microsoft Access都有这些,可能也是最容易设置的。

基本上,您设置了一个查询,将所有相关数据连接在一起,并可能带有用户可以填充的某些参数(如果您有大量数据,则可以使处理更快),然后将结果输入到数据透视表中,然后可以按您希望的方式对事物进行分组。 您可以随时查看按库分类的子项目,按机器分类的样本,按样本分类的库,以及在任何这些字段上进行过滤。 因此,您可以快速按机器报告样本,并对其进行过滤,以便仅显示机器1的样本。

好处是您可以进行一个查询,其中包含您可能需要的所有数据,然后您可以专注于安排组和过滤。 对于这类东西,有更多的重型系统(OLAP服务器),但是如果您没有大量数据,则可能不需要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM