外键参考复合主键

Viv*_*ida 3 mysql sql database-design foreign-keys mariadb

该数据库将存储有关硬件设备及其收集的数据的信息。我创建了一个设备表来存储可用的硬件设备:

CREATE TABLE IF NOT EXISTS `devices` (
  `deviceID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `deviceType` int(10) unsigned NOT NULL,
  `updateFrequency` int(10) unsigned NOT NULL,
  PRIMARY KEY (`deviceID`,`deviceType`)
)
Run Code Online (Sandbox Code Playgroud)

deviceID 将对应于真实的硬件 ID(从 1 到 12)。由于有两种类型的硬件设备,我认为创建一个 deviceType 是合适的,该 deviceType 为 0 或 1,具体取决于哪个硬件设备并创建一个复合主键。

为了存储该数据,我创建了另一个表。

CREATE TABLE IF NOT EXISTS `data` (
  `dataID` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `deviceID` int(11) unsigned NOT NULL,
  `payload` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  PRIMARY KEY (`dataID`),
  KEY `fk_data_devices` (`deviceID`),
  CONSTRAINT `fk_data_devices` 
    FOREIGN KEY (`deviceID`) 
    REFERENCES `devices` (`deviceID`) 
    ON DELETE CASCADE
)
Run Code Online (Sandbox Code Playgroud)

问题显然是我无法引用数据内一列中的复合键。在数据内部为 deviceType 和外键引用创建一个附加列是否有意义,或者将设备内部的 deviceID 和 deviceType 分配给另一个 id 并引用该内部数据是否更有意义?

提前致谢!

GMB*_*GMB 6

您有一个在列 ( deviceID, deviceType) 上具有复合主键的父表。如果你想创建一个子表,你需要:

  • 在子表中为父表中主键的每一列创建一列 ( deviceID, deviceType)
  • 创建一个复合外键,将该列元组引用到父表中相应的列元组

考虑:

CREATE TABLE IF NOT EXISTS `data` (
    `dataID` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `deviceID` int(11) unsigned NOT NULL,
    `deviceType` int(10) unsigned NOT NULL,
    `payload` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
    PRIMARY KEY (`dataID`),
    CONSTRAINT `fk_data_pk` 
        FOREIGN KEY (`deviceID`, `deviceType`) 
        REFERENCES `devices` (`deviceID`, `deviceType`) 
        ON DELETE CASCADE
);
Run Code Online (Sandbox Code Playgroud)

注意:创建复合外键在功能上与创建两个外键不同,每个外键都指向父表中的一列。

鉴于父表中的数据:

deviceID  deviceType
1         0
2         1
Run Code Online (Sandbox Code Playgroud)

如果您在每列上创建一个单独的外键,它们将允许您在子表中插入一条记录,其值例如(1, 1), 或(2, 0)。复合外键不允许这样做,因为源表中不存在这些特定的元组。