外键参考复合主键

时间:2019-04-05 21:01:43

标签: mysql sql 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`)
)

deviceID将对应于实际的硬件ID(从1到12)。由于存在两种类型的硬件设备,因此我认为创建一个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
)

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

谢谢!

1 个答案:

答案 0 :(得分:2)

您有一个父表,在列(async users ({ request, response, domain }) { const { users } = request.only(['users']) for (const user of users) { try { let u = await User.findOrCreate({ email: user.email }, user) if (u.id) { u.merge(user) await u.save() } else { await u.test().associate(test) } } catch (e) { console.log(e) return response.status(500).send(`User Task Error: ${e}`) } } )上有一个复合主键。如果要创建子表,则需要:

  • 在子表中为作为父表({{1)}主键一部分的每一列创建一个列
  • 创建一个复合外键,将列的元组引用到父表中的相应列元组

考虑:

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 ); deviceID deviceType 1 0 2 1 之类的值的记录。复合外键将不允许它,因为这些特定的元组在源表中不存在。