我猜你已经碰到了关系数据库的一个局限 - 很难对继承关系进行建模。这是Stack Overflow的常见主题 - 最好的答案是 这里 。
您可能希望在阅读本文时重构您的数据库设计 - 但如果您不这样做,您的“查找订单”查询将需要在所有产品表上合并。
您可能希望使用orderID和customerID以及“orderLine”引入“orderHeader”的概念,将orderHeader链接到客户订购的项目 - 您当前的设计意味着订单只有一个产品,或者您正在重复accountID和OrderID对于每个订单行。
客户可以拥有物理服务器,虚拟服务器,VPN隧道,防火墙,其他硬件等。这就是为什么我需要拥有多个产品,因为它们之间的共享很少。
但它们应该共享(至少)一件事 - 产品Id,用于将产品(任何类型)链接到数据库中的其他实体的主键。可能,他们也可以分享一个描述。
Table: Product Id: int (PK) Description (NVARCHAR) Table: PhysicalServer ProductId: int (FK to Product) ... other fields relevant only to PhsicalServers Table: VirtualServer ProductId: int (FK to Product) ... other fields relevant only to VirtualServer
使用这种方法,你的其他表总是链接到产品的PK - 这样你没有多个不同的表和自己的ProductId,你不一定需要知道那些产品的其余细节是什么表 - 所有产品共享相同的productId。
像entityframework这样的ORM工具也可以构建正确的继承heirachy,例如 PhsicalServer 继承自 Product
PhsicalServer
Product
您的产品并不像您想象的那样彼此不同。有商店出售电脑,衣服,玩具等,他们仍然有一个单项表,因为这些项共享许多属性。
有些可能是可选的。在上面的数据库中,颜色可能仅适用于90%的项目。那么,其他人则无效。所以这是处理特定属性的一种方法。另一种方法是为这些属性添加键值表。第三个是拥有其他产品组特定表。例如。:
然后在产品表上添加约束,以便始终只填充其中一个产品组ID。
同
你这样查询数据:
select p.productno, p.name, coalesce(ps.size, vs.size) as size from order o join product p on p.productno = o.productno left join physicalserver ps on ps.id_physicalserver = p.id_physicalserver left join virtualserver vs on vs.id_virtualserver = p.id_virtualserver where p.clientid = 1234 and (p.id_physicalserver is not null or p.id_virtualserver is not null);
(在你的情况下,我可能只有一个产品表包含几个可选字段。这通常是最简单的方法。)