我有一个数据库。如您所见,主键是一个 auto_increment
并且也是唯一的。我读到向公众公开共享表的行的主键是不安全的。我想为 customers
中的每一行分配一个可以公开共享的唯一 ID。如何在不必每次在 INSERT
语句中指定 public_id 的情况下执行此操作?数据库应该自动找到一个唯一的 ID 来分配给该行,就像它为 id
所做的那样,因为 auto_increment
。
CREATE TABLE customers (
id int primary key auto_increment,
name varchar(32) not null,
-- public_id (an ID I can give to the public to uniquely identify this row
);
INSERT INTO customers (name) VALUES ('Bob'), ('Sarah'), ('Bob');
答案 0 :(得分:2)
好吧,这是一种方法:
CREATE TABLE customers (
id int primary key auto_increment,
name varchar(32) not null,
public_id char(36) not null unique default uuid()
);
注意手册上说:
<块引用>尽管 UUID() 值旨在是唯一的,但它们不一定不可猜测或不可预测。如果需要不可预测性,则应以其他方式生成 UUID 值。
所以这很简单,也许会让你的山羊漂浮,但我们也可以尝试更好:
CREATE TABLE customers (
id int primary key auto_increment,
name varchar(32) not null,
public_id char(24) not null unique default to_base64(random_bytes(18))
);
这将是一个很好且密集的标识符,但它会包含字符 +
和 /
,这些字符与 URL 不兼容。当然,您可以对它们进行编码,但如果您想更懒惰,也可以这样做:
CREATE TABLE customers (
id int primary key auto_increment,
name varchar(32) not null,
public_id char(32) not null unique default hex(random_bytes(16))
);
请注意,这样标识符会变得更长。
为了两全其美,我们可以这样做,但代价是一个非常长的默认值:
CREATE TABLE customers (
id int primary key auto_increment,
name varchar(32) not null,
public_id char(24) not null unique default replace(replace(to_base64(random_bytes(18)), '+', '_'), '/', '-')
);
另请注意,处理 MD5()
/SHA()
/SHA1()
/SHA2()
并不比仅生成具有给定长度的随机十六进制字符串好。