2

我正在尝试为给定问题找到最佳解决方案:

Collateral我有一个由多个字段组成的实体(让我们称之为)。该实体的唯一性由 4 个字段的组合定义(我们称它们为:user_id (bigint)device_id(varcha(9))key_id(varchar(2732))application_id(varchar(255))

这个表是用hibernate生成的。我已经尝试将这 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 个字段)但是,我不确定这样的解决方案是否合适因为我们使用冗余信息违反了数据库规范化。

哈希的解决方案实际上是一个好的解决方案吗?如果不是,对于给定问题,有什么更好的选择?

4

1 回答 1

2

规范化证书密钥:

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;

然后cert_id在另一个表和INDEX您正在谈论的复合材料中使用。

在新表中插入 cert_key 并获取 cert_id 需要额外的步骤。这是在插入主表之前完成的。

它不太重要,但您也可以考虑规范化application_id.

(是的,可以使用散列设计一种不同的技术,但我认为这更干净。)

于 2019-06-24T16:40:56.923 回答