我有一个SQL Server 2012 Express数据库,其中包含以下情况。
我有一个Sales
,一个Purchase
和一个Movement
表。
Sales
和Purchase
都汇总在Movement
表中。
但我想控制数据的来源。 基本上是:
MOVEMENT_ID TABLE_ID RECORD_ID PROD QTY
1 PURCHASE 1 PENCIL 10
2 PURCHASE 2 ERASER 5
3 SALES 1 PENCIL 1
4 PURCHASE 3 MARKER 10
不要担心规范化部分,我只是想知道我是否可以在Record_ID
列上有一个外键,该列链接到Table_ID
列中指定的表的记录。
所以......
MovementID=1
上,我想要Purchase
table MovementID=3
上,我想要Sales
table 这一切都可能吗?如果是,怎么样?
答案 0 :(得分:1)
这一切都可能吗?
不是直接的,我会热烈推荐单独的字段与单独的FK(正如其他人已经建议的那样)。
然而,因为你使用的是MS SQL Server,你可以像这样间接地做到这一点:
例如:
ALTER TABLE Movement
ADD SALE_ID AS IIF(TABLE_ID = 'SALES', RECORD_ID, NULL) PERSISTED
REFERENCES Sales (SALE_ID);
ALTER TABLE Movement
ADD PURCHASE_ID AS IIF(TABLE_ID = 'PURCHASE', RECORD_ID, NULL) PERSISTED
REFERENCES Purchase (PURCHASE_ID);
1 SQL Server禁止在非持久计算列上创建FOREIGN KEY。
答案 1 :(得分:0)
根据你为此做了什么,这样的非规范化表可能不会太糟糕(即它只是用于查询/分析)。但是,它可能变得难以维护(例如,当这些表中的ID具有不同的数据类型等时会发生什么)。您可能会做的一些查询示例
;WITH SalesMovement AS
(
SELECT * FROM Movement
WHERE TableName = 'Sales'
)
SELECT PROD, SUM(QTY) FROM SalesMovement
GROUP BY PROD
;WITH PurchaseMovement AS
(
SELECT * FROM Movement
WHERE TableName = 'Purchase'
)
SELECT * FROM Purchase p
INNER JOIN PurchaseMovement pm ON pm.Record_Id = p.Id
;WITH PurchaseMovement AS
(
SELECT * FROM Movement
WHERE TableName = 'Purchase'
)
, SalesMovement AS
(
SELECT * FROM Movement
WHERE TableName = 'Sales'
)
SELECT * FROM Purchase p,
INNER JOIN Sales s ON s.SaleDate = p.PurchaseDate
INNER JOIN PurchaseMovement pm ON pm.Record_Id = p.Id
INNER JOIN SalesMovement sm ON sm.Record_Id = s.Id
每当你想加入原始数据时,你都需要过滤,投射以及你可能会成为真正的皮塔的东西
要考虑的另一件事是SUM(Qty) = SUM(ProductsSold) + SUM(ProductsSales)
这样的东西是否有意义,你必须小心这种“误用”表格中的数据。
答案 2 :(得分:0)
听起来运动真的是购买或销售的概括。如果是,请考虑使用shared-primary-key。
这将消除在一列中混合不同类型的FK的问题。移动表中的PK将根据具体情况在购买或销售表中引用PK。更少的列,也更少混乱。