我根据此处的函数使用PHP生成UUID
现在我想将它存储在MySQL数据库中.存储UUID v4的最佳/最有效的MySQL字段格式是什么?
我目前有varchar(256),但我很确定它比必要的要大得多.我发现了许多差不多的答案,但他们对于他们指的是什么形式的UUID一般都很模糊,所以我要求具体的格式.
tad*_*man 37
存储它就VARCHAR(36)好像你想要一个完全合适,或者VARCHAR(255)无论如何都要以相同的存储成本来解决.这里没有理由对字节大惊小怪.
记住VARCHAR字段是可变长度的,因此存储成本与它们实际存在的数据量成正比,而不是它们中的数据量.
存储它BINARY非常烦人,值是不可打印的,并且在运行查询时可能显示为垃圾.很少有理由使用文字二进制表示.人类可读的值可以复制粘贴,并且可以轻松处理.
其他一些平台,如Postgres,有一个适当的UUID列,它以更紧凑的格式在内部存储它,但将其显示为人类可读的,因此您可以获得两种方法中的最佳方法.
Mat*_*Rey 11
如果每行总是有一个UUID,则可以将其存储为CHAR(36)每行1个字节VARCHAR(36).
uuid CHAR(36) CHARACTER SET ascii
Run Code Online (Sandbox Code Playgroud)
与CHAR相比,VARCHAR值存储为1字节或2字节长度前缀加数据.长度前缀表示值中的字节数.如果值不超过255个字节,则列使用一个长度字节;如果值可能需要超过255个字节,则列使用两个长度字节. https://dev.mysql.com/doc/refman/5.7/en/char.html
虽然要小心CHAR,但即使字段留空,它也总是会消耗定义的全长.此外,请确保使用ASCII作为字符集,CHAR否则计划最坏情况(即每个字符3个字节utf8,4个utf8mb4)
[...] MySQL必须为CHAR CHARACTER SET utf8mb4列中的每个字符保留四个字节,因为这是可能的最大长度.例如,MySQL必须为CHAR(10)CHARACTER SET utf8mb4列保留40个字节. https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
Kar*_* R. 10
问题是关于在MySQL中存储UUID.
从mySQL 8.0版开始,您可以binary(16)通过UUID_TO_BIN/BIN_TO_UUID函数自动转换:https:
//mysqlserverteam.com/mysql-8-0-uuid-support/
请注意,mySQL还有一种快速生成UUID作为主键的方法:
INSERT IN TO VALUES(UUID_TO_BIN(UUID(),true))
最有效的肯定是BINARY(16),存储人类可读的字符使用两倍以上的存储空间,这意味着更大的索引和更慢的查找。如果您的数据足够小以至于将它们存储为文本不会影响性能,那么您可能不需要在无聊的整数键上使用 UUID。存储原始数据确实没有其他人建议的那么痛苦,因为任何体面的数据库管理工具都会将八位字节显示/转储为十六进制,而不是“文本”的字面字节。您不需要在数据库中手动查找 UUID;如果你有,HEX()和x'deadbeef01'文字是你的朋友。在你的应用程序中编写一个函数——就像你引用的那个——来为你处理这个问题是微不足道的。
我会将 UUID 生成逻辑与显示逻辑分开,以确保现有数据永远不会更改并且错误是可检测的:
function guidv4($prettify = false)
{
static $native = function_exists('random_bytes');
$data = $native ? random_bytes(16) : openssl_random_pseudo_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100
$data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
if ($prettify) {
return guidv4_pretty($data);
}
return $data;
}
function guidv4_pretty($data)
{
return strlen($data) == 16 ?
vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)) :
false;
}
function guidv4_ugly($data)
{
$data = preg_replace('/[^[:xdigit:]]+/', '', $data);
return strlen($data) == 32 ? hex2bin($data) : false;
}
Run Code Online (Sandbox Code Playgroud)
编辑:如果您在读取数据库时只需要漂亮的列,那么像下面这样的语句就足够了:
ALTER TABLE test ADD uuid_pretty CHAR(36) GENERATED ALWAYS AS (CONCAT_WS('-', LEFT(HEX(uuid_ugly), 8), SUBSTR(HEX(uuid_ugly), 9, 4), SUBSTR(HEX(uuid_ugly), 13, 4), SUBSTR(HEX(uuid_ugly), 17, 4), RIGHT(HEX(uuid_ugly), 12))) VIRTUAL;
Run Code Online (Sandbox Code Playgroud)
这在 MySQL 8.0.26 中对我来说就像一个魅力
create table t (
uuid BINARY(16) default (UUID_TO_BIN(UUID())),
)
Run Code Online (Sandbox Code Playgroud)
查询时您可以使用
select BIN_TO_UUID(uuid) uuid from t;
Run Code Online (Sandbox Code Playgroud)
结果是:
# uuid
'8c45583a-0e1f-11ec-804d-005056219395'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25007 次 |
| 最近记录: |