请使用 varchar(36) 或是否有任何更好的方法呢?

2009-01-05 05:37:12
问题评论:

"thaBadDawg"提供了一个很好的答案。堆栈溢出的讨论主题位于并行线程。添加一些注释链接到资源的详细信息与该线程应答。这里是提问链接︰ stackoverflow.com/questions/547118/storing-mysql-guid-uuids -期望这个主题来变得越来越普遍,当人们开始考虑 AWS 和极光。

回答:

我打电话问我,当我问有关存储为我为什么我所需的对象时使用的整数都做到同样的事情,以 4 个字节存储 16 字节的 Guid 的最好办法。由于他将这一难题有到我现在认为我是说它的好时机。谈话...

如果想要最大程度优化利用的存储空间,您可以为 CHAR(16) 二进制存储 guid。

因为通过 16 个字节,可以生成在不同数据库中,在不同的计算机上的内容在不同的时间,并且仍然合并数据无缝地:)

:) 在资金上向右

需要回复,什么确实是一个 char 16 二进制吗?没有字符?不是二进制的吗?我看不到任何 mysql gui 工具,也不在 mysql 网站中的任何文档中的该类型。@BillyONeal

@nawfal: char 是数据类型。二进制文件是对该类型的类型说明符。它具有的唯一效果是修改 MySQL 如何进行归类。Dev.mysql.com/doc/refman/5.0/en/charset-binary-op.html有关更多详细信息,请参阅。当然您可以只使用二进制类型直接如果数据库编辑工具使您可以做到这一点。(旧工具二进制数据类型还不知道,但二进制列标志知道吗)

有几个理由为什么 GUID 是远远好于自动增量。Jeff Atwood 列出这些之一对我来说,使用 GUID 的最佳优点为我的应用程序不需要知道的实体键的数据库往返行程︰ 我无法进行填充以编程的方式,我不可以这样做如果我使用一个自动递增字段。这为我节省从几个方面的麻烦问题︰ 我可以管理的 guid 中相同的方式,而不考虑该实体的实体已经保持或其全新。

我会将其存储为 char(36)。

将添加到 ThaBadDawg 的答案,使用这些便利功能 (这要归功于我的比我们更聪明 collegue) 回到 36 长度字符串从 16 字节数组。

DELIMITER $$

CREATE FUNCTION `GuidToBinary`(
    $Data VARCHAR(36)
) RETURNS binary(16)
DETERMINISTIC
NO SQL
BEGIN
    DECLARE $Result BINARY(16) DEFAULT NULL;
    IF $Data IS NOT NULL THEN
        SET $Data = REPLACE($Data,'-','');
        SET $Result =
            CONCAT( UNHEX(SUBSTRING($Data,7,2)), UNHEX(SUBSTRING($Data,5,2)),
                    UNHEX(SUBSTRING($Data,3,2)), UNHEX(SUBSTRING($Data,1,2)),
                    UNHEX(SUBSTRING($Data,11,2)),UNHEX(SUBSTRING($Data,9,2)),
                    UNHEX(SUBSTRING($Data,15,2)),UNHEX(SUBSTRING($Data,13,2)),
                    UNHEX(SUBSTRING($Data,17,16)));
    END IF;
    RETURN $Result;
END

$$

CREATE FUNCTION `ToGuid`(
    $Data BINARY(16)
) RETURNS char(36) CHARSET utf8
DETERMINISTIC
NO SQL
BEGIN
    DECLARE $Result CHAR(36) DEFAULT NULL;
    IF $Data IS NOT NULL THEN
        SET $Result =
            CONCAT(
                HEX(SUBSTRING($Data,4,1)), HEX(SUBSTRING($Data,3,1)),
                HEX(SUBSTRING($Data,2,1)), HEX(SUBSTRING($Data,1,1)), '-', 
                HEX(SUBSTRING($Data,6,1)), HEX(SUBSTRING($Data,5,1)), '-',
                HEX(SUBSTRING($Data,8,1)), HEX(SUBSTRING($Data,7,1)), '-',
                HEX(SUBSTRING($Data,9,2)), '-', HEX(SUBSTRING($Data,11,6)));
    END IF;
    RETURN $Result;
END

CHAR(16)是实际BINARY(16),选择您首选然后再将其

要更好地跟踪代码,需要给出下面的数字排序 GUID 的示例。(非法字符用于说明目的的每个位置的唯一字符。)这些函数将转换字节排序以实现优异的索引群集的位顺序。下面示例显示了重新排序后的 guid。

12345678-9ABC-DEFG-HIJK-LMNOPQRSTUVW
78563412-BC9A-FGDE-HIJK-LMNOPQRSTUVW

短划线删除︰

123456789ABCDEFGHIJKLMNOPQRSTUVW
78563412BC9AFGDEHIJKLMNOPQRSTUVW

下面是上述 GuidToBinary 而不从字符串中删除连字符︰ 创建函数GuidToBinary($guid char(36)) 返回 binary(16) 返回 CONCAT (UNHEX (子字符串 ($guid,7,2)),UNHEX (子字符串 ($guid,5,2))、 UNHEX (子字符串 ($guid,3,2))、 UNHEX (子字符串 ($guid,1、 2))、 UNHEX (子字符串 ($guid,12,2))、 UNHEX (子字符串 ($guid,10,2))、 UNHEX (子字符串 ($guid,17,2))、 UNHEX (子字符串 ($guid,152))、 UNHEX (子字符串 ($guid,20,4))、 UNHEX (子字符串 ($guid,25、 12)));

对于一些好奇的人,这些函数是优于只是 UNHEX(REPLACE(UUID(),'-','')),因为其排列将更好地执行在聚集索引中的顺序的位。

这是很有帮助,但是我认为它可以改进与用于CHARBINARY等效源 (文档似乎暗示存在着重大差异,并解释为什么聚集的索引性能会更好地与重新排序字节。

当我使用这被更改我的 guid。我试了插入使用 unhex (替换 (字符串,'-',')),以上函数,当转换它们重新使用相同的方法选择 guid 不是插入的。什么变换 guid?我所做的就是复制上面的代码。

char(36) 是个不错的选择。此外 MySQL 的 UUID() 可以使用函数返回可用于此类 Id 从数据库检索的 36 个字符的文本格式 (用连字符的十六进制)。

"更好地"取决于您正在优化的。

多少关心存储的大小性能,可与易用性的开发呢?更重要的是-您正在生成足够的 Guid,或频繁地提取它们不够重要吗?

如果答案为"否", char(36)多不够好,因此它将存储/读取 Guid 死简单。否则为binary(16)是合理的但您必须了解在 MySQL 和/或您的编程语言选择来回转换的常用字符串表示形式。

如果主机软件 (例如 ie web 页) 并不销售/安装在客户端,可以总是开头容易开发的早期阶段中的软件,用于 char(36) 和随着系统使用量的增加,开始需要优化为更紧凑的格式改变。

最大的方量较大是 char(36) 的索引将占据多少空间。如果您在数据库中有大量的记录,在索引的大小增加一倍。

内容来源于Stack Overflow How should I store GUID in MySQL tables?
请输入您的翻译

How should I store GUID in MySQL tables?

确认取消