我有以下业务规则:
一个帐户可以有零个或多个许可证。
每个许可证都有一个唯一的guid。
每个许可证都预先分配给一个给定的帐户。
所有安装都属于给定的帐户。
所有商业安装都需要许可证。
没有两个商业安装可以使用同一个许可证。
可以删除商业\u安装,然后可以在新的商业\u安装上使用许可证。
商业安装只能使用已分配给安装帐户的许可证。
如何执行最后一条规则?商业安装只能使用已分配给安装帐户的许可证。或者换句话说,对于要存储在 commercial_installations
, licenses.accounts_id
必须相等 installations.accounts_id
. 请参阅底部的示例数据。
CREATE TABLE IF NOT EXISTS accounts (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(45) NOT NULL,
otherData VARCHAR(45) NULL,
PRIMARY KEY (id))
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS licenses (
guid CHAR(36) NOT NULL,
accounts_id INT NOT NULL,
otherData VARCHAR(45) NULL,
PRIMARY KEY (guid),
INDEX fk_licenses_accounts1_idx (accounts_id ASC),
CONSTRAINT fk_licenses_accounts1
FOREIGN KEY (accounts_id)
REFERENCES accounts (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS installations (
id INT NOT NULL AUTO_INCREMENT,
accounts_id INT NOT NULL,
otherData VARCHAR(45) NULL,
PRIMARY KEY (id),
INDEX fk_installations_accounts1_idx (accounts_id ASC),
CONSTRAINT fk_installations_accounts1
FOREIGN KEY (accounts_id)
REFERENCES accounts (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS open_installations (
installations_id INT NOT NULL,
otherData VARCHAR(45) NULL,
PRIMARY KEY (installations_id),
CONSTRAINT fk_open_installations_installations1
FOREIGN KEY (installations_id)
REFERENCES installations (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS commercial_installations (
installations_id INT NOT NULL,
licenses_guid CHAR(36) NOT NULL,
otherData VARCHAR(45) NULL,
PRIMARY KEY (installations_id),
UNIQUE INDEX fk_commercial_installations_licenses1_idx (licenses_guid ASC),
CONSTRAINT fk_commercial_installations_installations1
FOREIGN KEY (installations_id)
REFERENCES installations (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT fk_commercial_installations_licenses1
FOREIGN KEY (licenses_guid)
REFERENCES licenses (guid)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
给出以下样本数据: b5060518-f87e-4acc-82c8-adb5750685a9
以及 d6f23460-0d77-400e-ae96-13f436e40245
只能存在于 commercial_installations
哪里 commercial_installations.id
是 1
或者 2
.
同样地, 8739ef62-7fff-4913-81de-3d00e8f50ecb
为了 3
.
同样地, 36cc0787-5cb9-4c3a-b79d-1dcfb83d2794
为了 4
.
账户
+----+-----------+
| id | name |
+----+-----------+
| 1 | Account 1 |
| 2 | Account 2 |
| 3 | Account 3 |
| 4 | Account 4 |
+----+-----------+
许可证
+--------------------------------------+-------------+
| guid | accounts_id |
+--------------------------------------+-------------+
| b5060518-f87e-4acc-82c8-adb5750685a9 | 1 |
| d6f23460-0d77-400e-ae96-13f436e40245 | 1 |
| 36cc0787-5cb9-4c3a-b79d-1dcfb83d2794 | 2 |
| 8739ef62-7fff-4913-81de-3d00e8f50ecb | 3 |
+--------------------------------------+-------------+
安装
+----+-------------+
| id | accounts_id |
+----+-------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 3 |
| 4 | 2 |
+----+-------------+
2条答案
按热度按时间kmpatx3s1#
简单传播
account_ID
至commercial_installations
. 它还需要一些更独特的约束,标记为sk(superkey,密钥的超集)作为模型中fks的目标。ergxz8rk2#
当然,您可以在应用程序的逻辑中强制执行它,但我猜您希望在数据库级别执行它。
我在这里看到的唯一选择是为
INSERT
,UPDATE
,和DELETE
操作。普通外键不适合您。我喜欢这个问题,因为我以前也遇到过这个问题,所以我没有花时间正式问这个问题。