在数据库设计期间,我发现了以下情况,我不确定我是否以正确的方式处理了这个问题。所以有我的数据库架构:
此架构包含有关在给定服务器上运行的产品的数据。服务器可以在多个客户之间共享。 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中,你可以看到标有**的行,我必须在一个查询中连接一个表两次,我不完全确定,但我觉得这可能是坏主意/糟糕的db设计。
我有一个想法将ProductServer和Instance拆分为一个表,但由于ProductServer表可能有100k行,我觉得最好将这个表拆分为两个较小的表。
请告诉我这是否设计得很糟糕并转发到某些来源,我可以弄清楚如何以更好的方式实现这个问题?
修改 我需要为给定的服务器获取所有客户,因为我需要将所有数据提取到Java对象。这就是为什么我需要表Customer加入ServerCustomer并在一个数据库查询中加入Customer with Instance表。
答案 0 :(得分:0)
您可能想要做的是重新安排联接,只加入Customer
一次。不完全清楚您当前的条件是否应该由AND
或OR
组合。我在这里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}
,我们可以引用任何列中的任何列这些表格是我们加入条件的一部分。