我们正在构建一个新的restapi,并且有一些关于主键和幂等键的决定要做。我们的api有很多用户,用户只能查找属于他们的对象。请求经过身份验证,因此我们知道 userId
与给定请求关联。
关注属性: userId
用户的id。 idempotenyKey
在对api的幂等请求中使用的幂等键。每个用户都是唯一的。
假设有一个假设表 Cars
带端点 GET .../cars/{id}
我们将以此为基础进行讨论。
选项
选项1-使用userid和幂等键的组合作为主键
CREATE TABLE Cars (
userId VARCHAR(255) NOT NULL,
idempotencyKey VARCHAR(255) NOT NULL,
description VARCHAR(255),
PRIMARY KEY (userId, idempotencyKey),
INDEX user_index (userId)
);
项目查找: GET .../cars/{idempotencyKey}
思想:
查找中使用的id是可以猜测的。
由于对象是经过身份验证的,这似乎不会立即引起安全问题,但这确实意味着,如果api中有一个端点允许用户的用户查找某些内容,那么我们需要假设查找是可以猜测的。
选项2-使用userid+幂等键的哈希作为主键
CREATE TABLE Cars (
id VARCHAR(255) NOT NULL,
userId VARCHAR(255) NOT NULL,
idempotencyKey VARCHAR(255) NOT NULL,
description VARCHAR(255),
PRIMARY KEY (id),
INDEX user_index (userId)
);
当我们计算 id = hash(userId + idempotencyKey)
.
项目查找: GET .../cars/{id}
思想:
主键不可用。
这进一步防止了针对 ids
.
不再是复合主键。
与选项3不同,不需要对(userid,幂等键)进行唯一约束。
选项3-生成uuid主键
CREATE TABLE Cars (
id VARCHAR(255) NOT NULL,
userId VARCHAR(255) NOT NULL,
idempotencyKey VARCHAR(255) NOT NULL,
description VARCHAR(255),
PRIMARY KEY (id),
INDEX user_index (userId),
CONSTRAINT unique_by_user UNIQUE (userId, idempotencyKey)
);
当我们设置 id = UUID.randomUUID()
.
项目查找: GET .../cars/{id}
思想:
id是完全不可用的,并且不与任何业务数据绑定。
需要一个额外的索引。
选项4-从不向用户公开的自动递增主键
CREATE TABLE Cars (
id INT NOT NULL AUTO_INCREMENT,
userId VARCHAR(255) NOT NULL,
idempotencyKey VARCHAR(255) NOT NULL,
description VARCHAR(255),
PRIMARY KEY (id),
INDEX user_index (userId),
CONSTRAINT unique_by_user UNIQUE (userId, idempotencyKey)
);
有几种方法可以进行查找。查找可以仅基于幂等键,即: GET .../cars/{idempotencyKey}
或者,我们可以自动生成一个referenceid uuid,它将被索引并用于查找。
思想:
主键从不向用户公开,这是一种非常常见的做法。
如果业务逻辑发生变化,则允许更大的灵活性(尽管对于userid和幂等键这样的基本概念,我看不出它们会发生什么变化)。
主键是int,因此更小。这允许更小的索引和更高的性能。
同样需要一个额外的索引。
寻找关于采取什么方法的建议。围绕性能和规模的考虑非常重要。
谢谢!
暂无答案!
目前还没有任何答案,快来回答吧!