SQL Lookup的替代方案?

时间:2016-06-06 08:49:16

标签: sql sql-server tsql sql-server-2014

我有多个这样的ProductTable

ProductTable1
ProductTable2
ProductTable3

请注意,ProductTable的设计不同。

我需要引用客户产品,他们可能有多种不同的产品 - 我该怎么做?

我可以像这样制作一个Order表(映射):

[Order]
Id
AccountId
ProductId
ProductType

然后我可以在ProductType中插入ProductTable的名称。所以在查询中我会得到一个ProductId和产品的表名(类型),所以我可以根据它创建一个新的查询。我猜这就是所谓的LookUp

但缺点是SQL数据库不知道AccountProduct之间的关系。

有没有更好的方法来实现这一目标?

我正在尝试为我们公司构建CMDB。 客户可以拥有物理服务器,虚拟服务器,VPN隧道,防火墙,其他硬件等。这就是为什么我需要拥有多个产品,因为它们之间的关系很少。

3 个答案:

答案 0 :(得分:2)

  

客户可以拥有物理服务器,虚拟服务器,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的不同表,并且您不一定需要知道其余详细信息所在的表。一种产品 - 所有产品共享相同的产品ID。

像entityframework这样的ORM工具也会为你构建正确的继承heirachy,例如允许PhsicalServer继承Product

答案 1 :(得分:0)

我猜你已经碰到了关系数据库的一个局限 - 很难对继承关系进行建模。这是Stack Overflow上的常见主题 - 最佳答案是here

您可能希望在阅读本文时重构您的数据库设计 - 但如果您不这样做,您的"会发现订单"查询需要在所有产品表上联合。

您可能想要介绍" orderHeader"的概念。使用orderID和customerID,以及" orderLine",将orderHeader链接到客户订购的商品 - 您当前的设计意味着订单只有一个产品,或者您为每个订单行重复accountID和OrderID。 / p>

答案 2 :(得分:0)

您的产品并不像您想象的那样彼此不同。有卖电脑,衣服,玩具等的商店,他们还有一个单项表,因为这些商品有很多属性。

  • 产品编号
  • 一个名字
  • 描述
  • 品牌名称
  • 一个价格
  • 也许还有很多

有些可能是可选的。在上面的数据库中,颜色可能仅适用于90%的项目。那么,对其他人来说,它是空的。所以这是处理特定属性的一种方法。另一种方法是为这些属性添加键值表。第三个是拥有其他产品组特定表。 E.g:

  • 产品(productno,名称,描述,价格,id_physicalserver,id_virtualserver,...)
  • physicalserver(id_physicalserver,...)
  • virtualserver(id_virtualserver,...)
  • ...

然后在产品表上添加约束,以便始终只填充其中一个产品组ID。

使用

  • order(orderno,orderdate,clientid,productno)

您这样查询数据:

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);

(我的情况可能只包含一个包含几个可选字段的产品表。这通常是最简单的方法。)