外键 - 数据库设计

时间:2017-03-06 09:38:41

标签: sql database-design foreign-keys

在数据库设计期间,我发现了以下情况,我不确定我是否以正确的方式处理了这个问题。所以有我的数据库架构:

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中,你可以看到标有**的行,我必须在一个查询中连接一个表两次,我不完全确定,但我觉得这可能是坏主意/糟糕的db设计。

我有一个想法将ProductServer和Instance拆分为一个表,但由于ProductServer表可能有100k行,我觉得最好将这个表拆分为两个较小的表。

请告诉我这是否设计得很糟糕并转发到某些来源,我可以弄清楚如何以更好的方式实现这个问题?

修改 我需要为给定的服务器获取所有客户,因为我需要将所有数据提取到Java对象。这就是为什么我需要表Customer加入ServerCustomer并在一个数据库查询中加入Customer with Instance表。

1 个答案:

答案 0 :(得分: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},我们可以引用任何列中的任何列这些表格是我们加入条件的一部分。