2017-03-06 169 views
0

我发现下面的情况,我不知道我是否以正确的方式处理。所以我的DB模式:数据库设计中的外键 - 数据库设计

enter image description here

该模式包含有关给定服务器上运行的产品数据。服务器可以在多个客户之间共享。 Table ProductServer告诉我们给定的产品已经安装在给定的服务器上。

由于产品/服务器的组合可以被多个客户使用(服务器可以有多个客户),所以我创建了另一个表Instance,它包含ProductServer行的其他信息。它包含有关哪个客户使用该产品及其优先级的信息。

我没有使用任何持久性框架,所以我手动编写了所有抓取函数。

我的问题是:目前我有查询时,连接所有表:

SELECT * FROM ProductServer ps 
LEFT OUTER JOIN Product p ON ps.product_id = p.product_id 
LEFT OUTER JOIN Server s ON ps.server_id = s.server_id 
LEFT OUTER JOIN ServerCustomer sc ON s.server_id = sc.server_id 
**LEFT OUTER JOIN Customer c ON sc.customer_id = c.customer_id** 
LEFT OUTER JOIN Instance i ON ps.ps_id = i.ps_id 
**LEFT OUTER JOIN Customer c2 ON i.customer_id = c2.customer_id** 

在我的SQL,你可以看到标有**行,我不得不参加一个表两次在一个查询,我不完全确定,但我觉得这可能是糟糕的想法/糟糕的数据库设计。

我有一个想法将产品服务器和实例拆分为一个表,但由于ProductServer表可能有100k行,所以我认为将表更好地拆分为两个较小的表。

请你能告诉我,这是否设计得不好,并转发给一些来源,我可以找出如何更好地实施这个问题?

编辑: 我需要获取所有客户给服务器,因为我需要获取所有数据到Java object`s。这就是为什么我需要表Customer与ServerCustomer加入,并且在一个数据库查询中也加入了Customer与Instance表。

回答

0

你可能想要做的是重新安排你的连接,只加入Customer一次。不完全清楚您的当前条件是否应合并ANDOR。我和AND怎么回事:

SELECT * FROM ProductServer ps 
LEFT OUTER JOIN Product p ON ps.product_id = p.product_id 
LEFT OUTER JOIN Server s ON ps.server_id = s.server_id 
LEFT OUTER JOIN ServerCustomer sc ON s.server_id = sc.server_id 
LEFT OUTER JOIN Instance i ON ps.ps_id = i.ps_id 
LEFT OUTER JOIN Customer c ON sc.customer_id = c.customer_id 
          AND i.customer_id = c.customer_id 

你可以做到这一点,因为连接并不限于两个表之间的必然 - 他们可能本身已经是结果的其它连接的表源之间。因此,在上文中,当我们到达最后的ON子句时,我们将在左边加入{ProductServer, Server, ServerCustomer, Instance}到右边的{Customer},我们可以引用任何这些表中的任何列作为加入条件的一部分。

+0

我之所以做这两个连接的原因是因为我使用此查询将所有这些数据提取到Java对象中。 所以我需要所有的客户对象在服务器对象中,并且我还需要在实例对象中有客户对象。 – n0hepe