替代太大的组合键

时间:2019-06-24 07:16:18

标签: java sql hibernate mariadb mariasql

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

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

该表是使用休眠生成的。我已经尝试将这4个字段移动到单独的实体(CollateralEmbeddedEntity)并将其用作嵌入式ID,并尝试对Collateral Entity中的这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个字段),但是我不确定解决方案是适当的,因为我们用冗余信息违反了数据库规范化。

使用散列的解决方案实际上是一个好方法吗?如果没有,对于给定的问题,有什么更好的选择?

1 个答案:

答案 0 :(得分: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标准化。

(是的,可以使用哈希设计另一种技术,但是我认为这更干净。)