替代太大的复合键
Substitution for too large composite key
我正在尝试为给定问题找到最佳解决方案:
我有一个由多个字段组成的实体(我们称之为 Collateral
)。这个实体的唯一性由 4 个字段的组合定义(我们称它们为:user_id (bigint)
、device_id(varcha(9))
、key_id(varchar(2732))
、application_id(varchar(255))
)
这个 table 是用休眠生成的。我已经尝试将这 4 个字段移动到一个单独的实体 (CollateralEmbeddedEntity
) 以将其用作嵌入式 ID,并在 Collateral
实体中的这 4 个字段上创建约束:
@Table(
name="COLLATERAL",
uniqueConstraints=
@UniqueConstraint(name = "comp_key", columnNames={"device_id", "application_id", "key_id", "user_id"}))
问题是在这两种情况下,字段都超过了 MariaDB 键的最大允许长度:
java.sql.SQLException: Specified key was too long; max key length is 3072 bytes
更改 dbCharset 编码(排序规则)或缩小字段 varchar 范围本身不是一个选项。
我想过的是生成并存储这 4 个字段的哈希值,并给它一个唯一的约束(搜索和更新将始终基于这 4 个字段)但是,我不确定如果这样的解决方案是合适的,因为我们使用冗余信息违反了数据库规范化。
哈希的解决方案实际上是一个好的解决方案吗?如果不是,对于给定的问题,更好的选择是什么?
规范化证书密钥:
CREATE TABLE CertKeys (
cert_id INT UNSIGNED AUTO_INCREMENT,
cert_key VARCHAR(2732) NOT NULL, -- base64 encoded
-- or: cert_key VARBINARY(2049) NOT NULL, -- binary
PRIMARY KEY (cert_id),
UNIQUEY (cert_key) ) ENGINE=InnoDB;
然后在另一个 table 和复合 INDEX
中使用 cert_id
。
在新的table中插入cert_key并得到cert_id需要一个额外的步骤。这是在插入主 table.
之前完成的
不太重要,但您也可以考虑标准化 application_id
。
(是的,可以使用散列设计一种不同的技术,但我认为这更干净。)
我正在尝试为给定问题找到最佳解决方案:
我有一个由多个字段组成的实体(我们称之为 Collateral
)。这个实体的唯一性由 4 个字段的组合定义(我们称它们为:user_id (bigint)
、device_id(varcha(9))
、key_id(varchar(2732))
、application_id(varchar(255))
)
这个 table 是用休眠生成的。我已经尝试将这 4 个字段移动到一个单独的实体 (CollateralEmbeddedEntity
) 以将其用作嵌入式 ID,并在 Collateral
实体中的这 4 个字段上创建约束:
@Table(
name="COLLATERAL",
uniqueConstraints=
@UniqueConstraint(name = "comp_key", columnNames={"device_id", "application_id", "key_id", "user_id"}))
问题是在这两种情况下,字段都超过了 MariaDB 键的最大允许长度:
java.sql.SQLException: Specified key was too long; max key length is 3072 bytes
更改 dbCharset 编码(排序规则)或缩小字段 varchar 范围本身不是一个选项。
我想过的是生成并存储这 4 个字段的哈希值,并给它一个唯一的约束(搜索和更新将始终基于这 4 个字段)但是,我不确定如果这样的解决方案是合适的,因为我们使用冗余信息违反了数据库规范化。
哈希的解决方案实际上是一个好的解决方案吗?如果不是,对于给定的问题,更好的选择是什么?
规范化证书密钥:
CREATE TABLE CertKeys (
cert_id INT UNSIGNED AUTO_INCREMENT,
cert_key VARCHAR(2732) NOT NULL, -- base64 encoded
-- or: cert_key VARBINARY(2049) NOT NULL, -- binary
PRIMARY KEY (cert_id),
UNIQUEY (cert_key) ) ENGINE=InnoDB;
然后在另一个 table 和复合 INDEX
中使用 cert_id
。
在新的table中插入cert_key并得到cert_id需要一个额外的步骤。这是在插入主 table.
之前完成的不太重要,但您也可以考虑标准化 application_id
。
(是的,可以使用散列设计一种不同的技术,但我认为这更干净。)