如何在子类型中实现参照完整性

时间:2011-02-04 10:17:18

标签: sql database relational-database foreign-key-relationship

我在关系数据库中有以下表格:

[Sensor]
LocationId [PK / FK -> Location]
SensorNo [PK]

[AnalogSensor]
LocationId [PK/FK -> Sensor]
SensorNo [PK/FK -> Sensor]
UpperLimit
LowerLimit

[SwitchSensor]
LocationId [PK/FK -> Sensor]
SensorNo [PK/FK -> Sensor]
OnTimeLimit

[Reading]
LocationId [PK/FK -> Sensor]
SensorNo [PK/FK -> Sensor]
ReadingDtm [PK]

[ReadingSwitch]
LocationId [PK/FK -> Reading]
SensorNo [PK/FK -> Reading]
ReadingDtm [PK/FK -> Reading]
Switch

[ReadingValue]
LocationId [PK/FK -> Reading]
SensorNo [PK/FK -> Reading]
ReadingDtm [PK/FK -> Reading]
Value

[Alert]
LocationId [PK/FK -> Reading]
SensorNo [PK/FK -> Reading]
ReadingDtm [PK/FK -> Reading]

基本上,ReadingSwitch和ReadingValue是Reading和SwitchSensor的子类型,AnalogSensor是Sensor的子类型。读数可以是SwitchReading或ValueReading值 - 它不能同时为两者,而Sensor可以是AnalogSensor或SwitchSensor。

到目前为止,我遇到的唯一方法是here

肯定必须有更好的方法来做这类事情。

我能想到的唯一另一种方法是不使用子类型但完全扩展所有内容:

[SwitchSensor]
LocationId [PK/FK -> Location]
SensorNo [PK]

[AnalogSensor]
LocationId [PK/FK -> Location]
SensorNo [PK]

[SwitchReading]
LocationId [PK/FK -> SwitchSensor]
SensorNo [PK/FK -> SwitchSensor]
ReadingDtm
Switch

[AnalogReading]
LocationId [PK/FK -> AnalogSensor]
SensorNo [PK/FK -> AnalogSensor]
ReadingDtm
Value

[AnalogReadingAlert]
LocationId [PK/FK -> AnalogReading]
SensorNo [PK/FK -> AnalogReading]
ReadingDtm [PK/FK -> AnalogReading]

[SwitchReadingAlert]
LocationId [PK/FK -> SwitchReading]
SensorNo [PK/FK -> SwitchReading]
ReadingDtm [PK/FK -> SwitchReading]

哪个可能不是那么糟糕,但我也有引用Alert表的表,因此它们也必须重复:

[AnalogReadingAlertAcknowledgement]
...
[AnalogReadingAlertAction]
...
[SwitchReadingAlartAcknowledgement]
...
[SwitchReadingAlartAction]

这个问题对任何人都有意义吗?

2 个答案:

答案 0 :(得分:18)

答案 1 :(得分:1)

第二种选择也充满了问题 - 例如对于传感器(并假设SensorNo是代理键),因为您没有基表,所以SensorNo代理在子类表之间不是唯一的,除非您使用klugey机制在所有子代码之间发布密钥类表(或使用guid)。

如果您的用户界面“组合”了不同类型的传感器,例如显示模拟和开关传感器联合的列表。

我建议您继续使用第一个模式,然后使用经过良好测试的事务代码封装这些表的插入和维护。

e.g。为各种SubTable创建插入过程,在相应的工作单元下插入相应的基本和子类记录。您可以更进一步,然后在任何表上撤消INSERT权限,从而强制通过SPROC进行插入。

您还可以运行每日完整性报告,该报告检查没有违反您的继承结构。