GVKun编程网logo

在MySQL中存储UUID v4(在MySQL中存储过程对应的关键字是?)

9

本文将介绍在MySQL中存储UUIDv4的详细情况,特别是关于在MySQL中存储过程对应的关键字是?的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于

本文将介绍在MySQL中存储UUID v4的详细情况,特别是关于在MySQL中存储过程对应的关键字是?的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于java – 如何在MySQL中存储图片?、Mysql中存储UUID去除横线的方法、MYSQL教程Mysql中存储UUID去除横线的方法、MySQL表中存储UUID值作为主键,使用UNHEX()提升性能的知识。

本文目录一览:

在MySQL中存储UUID v4(在MySQL中存储过程对应的关键字是?)

在MySQL中存储UUID v4(在MySQL中存储过程对应的关键字是?)

根据此处找到的功能,我正在使用PHP生成UUID

现在,我想将其存储在MySQL数据库中。存储UUID v4的最佳/最有效的MySQL字段格式是什么?

我目前有varchar(256),但我可以肯定它比所需的要大得多。我已经找到了很多几乎可以回答的内容,但是对于它们所指的UUID形式,它们通常是模棱两可的,所以我要询问特定的格式。

答案1

小编典典

将其存储起来,VARCHAR(36)好像您希望完全适合它一样,或者VARCHAR(255)无论如何都要以相同的存储成本进行计算。这里没有理由大惊小怪。

请记住,VARCHAR字段是 可变长度的 ,因此存储成本与它们中实际有多少数据成正比,而不是与其中可能有多少数据成正比。

存储它BINARY非常烦人,这些值是不可打印的,并且在运行查询时可能显示为垃圾。很少有理由使用文字二进制表示形式。可以将人类可读的值粘贴粘贴并轻松使用。

其他一些平台,例如Postgres,都有一个适当的UUID列,该列以更紧凑的格式在内部存储它,但将其显示为便于人类阅读,因此您可以充分利用这两种方法。

java – 如何在MySQL中存储图片?

java – 如何在MySQL中存储图片?

我想将图像存储在 MySQL数据库中.我创建了一个具有BLOB数据类型的表,但现在如何将图像存储在此表中?

解决方法

您可能需要查看以下示例:

java2s.com: Insert picture to MySQL开始:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.sqlException;

public class InsertPicturetoMysqL {
  public static void main(String[] args) throws Exception,IOException,sqlException {
    Class.forName("org.gjt.mm.MysqL.Driver");
    Connection conn = DriverManager.getConnection("jdbc:MysqL://localhost/databaseName","root","root");
    String INSERT_PICTURE = "INSERT INTO MyPictures (photo) VALUES (?)";

    FileInputStream fis = null;
    PreparedStatement ps = null;
    try {
      conn.setAutoCommit(false);
      File file = new File("/tmp/photo.png");
      fis = new FileInputStream(file);
      ps = conn.prepareStatement(INSERT_PICTURE);
      ps.setBinaryStream(1,fis,(int) file.length());
      ps.executeUpdate();
      conn.commit();
    } finally {
      ps.close();
      fis.close();
    }
  }
}

MysqL表:

CREATE TABLE MyPictures (
   photo  BLOB
);

如果映像位于MysqL服务器主机上,则可以使用MysqL客户端的LOAD_FILE()命令:

INSERT INTO MyPictures (photo) VALUES(LOAD_FILE('/tmp/photo.png'));

Mysql中存储UUID去除横线的方法

Mysql中存储UUID去除横线的方法

通常用uuid做唯一标识,需要在数据库中进行存储。

相关mysql视频教程推荐:《mysql教程》

UUID的格式

String string = UUID.randomUUID().toString();  
System.out.println(“uuid:” + string); 
uuid:05ba463f-1dab-471f-81c7-58e0b06f35f0
登录后复制

数据库中直接存储UUID的坏处:

完全‘随机''的字符串,例如由MD5()、SHA1()、UUID()产生的。它们产生的每一个新值都会被任意地保存在很大的空间范围内,这会减慢INSERT及一些SELECT查询。

1)它们会减慢INSERT查询,因为插入的值会被随机地放入索引中。这会导致分页、随机磁盘访问及聚集存储引擎上的聚集索引碎片。

2)它们会减慢SELECT查询,因为逻辑上相邻的行会分布在磁盘和内存中的各个地方。

3)随机值导致缓存对所有类型的查询性能都很差,因为它们会使缓存赖以工作的访问局部性失效。如果整个数据集都变得同样“热”的时候,那么把特定部分的数据缓存到内存中就没有任何的优势了。并且如果工作集不能被装入内存中,缓存就会进行很多刷写的工作,并且会导致很多缓存未命中。

如果保存UUID值,就应该移除其中的短横线,更好的办法是使用UHEX()把UUID值转化为16字节的数字,并把它保存在BINARY(16)列中。

DELIMITER $$  
CREATE FUNCTION `GuidToBinary`(  
    $Data VARCHAR(36)  
) RETURNS binary(16)  
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  
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
登录后复制
CREATE FUNCTION `UUIDTOBIN`() RETURNS binary(16)   
BEGIN
DECLARE my_uuid char(36);   
SET my_uuid = UUID();   
RETURN CONCAT(UNHEX(LEFT(my_uuid,8)),UNHEX(MID(my_uuid,10,4)),UNHEX(MID(my_uuid,15,4)),UNHEX(MID(my_uuid,20,4)),UNHEX(RIGHT(my_uuid,12)));   
END
CREATE FUNCTION `BINTOUUID`(UUID BINARY(16)) RETURNS char(36)   
BEGIN
RETURN CONCAT(HEX(LEFT(uuid,4)),'-', HEX(MID(uuid,5,2)),'-', HEX(MID(uuid,7,2)),'-',HEX(MID(uuid,9,2)),'-',HEX(RIGHT(uuid,6)));   
END
登录后复制

MYSQL教程Mysql中存储UUID去除横线的方法

MYSQL教程Mysql中存储UUID去除横线的方法

《MysqL教程MysqL中存储UUID去除横线的方法》要点:
本文介绍了MysqL教程MysqL中存储UUID去除横线的方法,希望对您有用。如果有疑问,可以联系我们。

参考:MysqL数据库

http://stackoverflow.com/questions/412341/how-should-i-store-guid-in-MysqL-tablesMysqL数据库

通常用UUID做唯一标识,必要在数据库中进行存储.MysqL数据库

UUID的格局
MysqL数据库

代码如下:

String string = UUID.randomUUID().toString(); 
System.out.println(“uuid:” + string);
uuid:05ba463f-1dab-471f-81c7-58e0b06f35f0

数据库中直接存储UUID的坏处:

完全‘随机'的字符串,例如由MD5()、SHA1()、UUID()产生的.它们产生的每一个新值都会被任意地保存在很大的空间范围内,这会减慢INSERT及一些SELECT查询.1)它们会减慢INSERT查询,因为插入的值会被随机地放入索引中.这会导致分页、随机磁盘拜访及聚集存储引擎上的聚集索引碎片.2)它们会减慢SELECT查询,因为逻辑上相邻的行会分布在磁盘和内存中的各个地方.3)随机值导致缓存对所有类型的查询性能都很差,因为它们会使缓存赖以工作的拜访局部性失效.如果整个数据集都变得同样“热”的时候,那么把特定部分的数据缓存到内存中就没有任何的优势了.并且如果工作集不能被装入内存中,缓存就会进行很多刷写的工作,并且会导致很多缓存未命中.MysqL数据库

如果保存UUID值,就应该移除其中的短横线,更好的方法是使用UHEX()把UUID值转化为16字节的数字,并把它保存在BINARY(16)列中.MysqL数据库

代码以下:

DELIMITER $$ 
CREATE FUNCTION `GuidToBinary`( 
    $Data VARCHAR(36) 
) RETURNS binary(16) 
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,3,1, 
                UNHEX(SUBSTRING($Data,11,9,15,13,17,16))); 
END IF; 
RETURN $Result; 
END
$$ 
CREATE FUNCTION `ToGuid`( 
    $Data BINARY(16) 
) RETURNS char(36) CHARSET utf8 
BEGIN
DECLARE $Result CHAR(36) DEFAULT NULL; 
    IF $Data IS NOT NULL THEN
SET $Result = CONCAT(HEX(SUBSTRING($Data,4,1)),HEX(SUBSTRING($Data,2,‘-',  
                HEX(SUBSTRING($Data,6, 
                HEX(SUBSTRING($Data,8,6))); 
END IF; 
RETURN $Result; 
END
代码以下:

CREATE FUNCTION `UUIDTOBIN`() RETURNS binary(16)  
BEGIN
DECLARE my_uuid char(36);  
SET my_uuid = UUID();  
RETURN CONCAT(UNHEX(LEFT(my_uuid,8)),UNHEX(MID(my_uuid,10,4)),20,UNHEX(RIGHT(my_uuid,12)));  
END
CREATE FUNCTION `BINTOUUID`(UUID BINARY(16)) RETURNS char(36)  
BEGIN
RETURN CONCAT(HEX(LEFT(uuid,HEX(MID(uuid,HEX(RIGHT(uuid,6)));  
END

欢迎参与《MysqL教程MysqL中存储UUID去除横线的方法》讨论,分享您的想法,小编PHP学院为您提供专业教程。

MySQL表中存储UUID值作为主键,使用UNHEX()提升性能

MySQL表中存储UUID值作为主键,使用UNHEX()提升性能

假设我们有一个用户表,每个用户都有一个UUID。MySQL有一个UUID()函数,它使MySQL生成一个UUID值,并以VARCHAR(36)类型的可读形式返回。让我们试试MySQL 5.7.8:


mysql> select uuid();
+--------------------------------------+
| uuid()                               |
+--------------------------------------+
| aab5d5fd-70c1-11e5-a4fb-b026b977eb28 |
+--------------------------------------+

mysql> select uuid();
+--------------------------------------+
| uuid()                               |
+--------------------------------------+
| aab5d5fd-70c1-11e5-a4fb-b026b977eb28 |
+--------------------------------------+
所以第一个想法是简单地做到这一点:




create table users(id varchar(36), name varchar(200));
insert into users values(uuid(), ''Andromeda'');

 

 

create table users(id varchar(36), name varchar(200));
insert into users values(uuid(), ''Andromeda'');
但是这种UUID的可读形式并不紧凑。让我们观察一下:


四个破折号是多余的
每对字符实际上是一个在00-FF范围内的十六进制数; 总共有16个数字(以上为:0xAA,0xB5等),每个数字可以存储在一个字节中。
所以我们可以使用REPLACE()去掉破折号,UNHEX()把每个
双字符对转换成一个字节:


create table users(id_bin binary(16), name varchar(200));
insert into users values(unhex(replace(uuid(),''-'','''')), ''Andromeda'');

 

 

create table users(id_bin binary(16), name varchar(200));
insert into users values(unhex(replace(uuid(),''-'','''')), ''Andromeda'');
这个二进制形式使用16个字节,比人类可读形式(我现在称之为“文本”形式)使用的VARCHAR(36)小得多。如果UUID必须是主键,则增益更大,如InnoDB中的主键值被复制到所有二级索引值中。


二进制(16)是...好吧...只是二进制!没有字符集,没有排序,只有十六个字节。适合我们的需求。


也许在某些应用程序中,文本形式仍然是必需的,所以让我们把它作为表格中的一个附加列; 但为了尽量减少磁盘占用,让我们将文本形成一个虚拟的生成 列(这是MySQL 5.7的一个新特性,在CREATE TABLE的文档中有描述)。该列将通过二进制格式列的公式计算:我们将二进制格式转换回十六进制数字并插入破折号。




create table users(
id_bin binary(16),
id_text varchar(36) generated always as
 (insert(
    insert(
      insert(
        insert(hex(id_bin),9,0,''-''),
        14,0,''-''),
      19,0,''-''),
    24,0,''-'')
 ) virtual,
name varchar(200));


insert into users (id_bin,name)
  values(unhex(replace(uuid(),''-'','''')), ''Andromeda'');


select id_text, name from users;
+--------------------------------------+-----------+
| id_text                              | name      |
+--------------------------------------+-----------+
| C2770D2E-70E6-11E5-A4FB-B026B977EB28 | Andromeda |
+--------------------------------------+-----------+

 

 

create table users(
id_bin binary(16),
id_text varchar(36) generated always as
 (insert(
    insert(
      insert(
        insert(hex(id_bin),9,0,''-''),
        14,0,''-''),
      19,0,''-''),
    24,0,''-'')
 ) virtual,
name varchar(200));
 
insert into users (id_bin,name)
  values(unhex(replace(uuid(),''-'','''')), ''Andromeda'');
 
select id_text, name from users;
+--------------------------------------+-----------+
| id_text                              | name      |
+--------------------------------------+-----------+
| C2770D2E-70E6-11E5-A4FB-B026B977EB28 | Andromeda |
+--------------------------------------+-----------+
我没有在SELECT中包含id_bin,因为它会以隐藏字符(ASCII码0xC2,0x77等:通常不在人可读的字符范围内)出现。我们没有理由需要看id_bin的内容; 但是,如果这样做,则可以使用HEX(id_bin)来显示其十六进制代码。


请注意,id_text被声明为VIRTUAL,因此在磁盘上的表中不占用空间。


使id_text成为生成列的另一个好处是消除了两列之间的任何不一致的风险。事实上,如果id_text是一个简单的列,可以做




update users set id_bin = <something>;

而无意更新id_text。但是作为一个生成的列,id_text不能直接更新,而是在更新id_bin时自动更新。换句话说,信息只在一个地方(id_bin),数据库保证了一致性。


那么,那么查询呢?例如,我们可能想通过UUID找到一个用户:



select * from users where <it has UUID XYZ>;

 

WHERE子句应该指定二进制还是文本形式?这取决于:


如果我们创建一个二进制形式的索引:


alter table users add unique(id_bin);


那么,为了使用这个索引,WHERE应该指定二进制形式:


WHERE id_bin = binary_form_of_XYZ


相反,如果我们在文本表单上创建一个索引:


alter table users add unique(id_text);



那么,WHERE应该指定文本形式:


WHERE id_text = text_form_of_XYZ

即使id_text是一个虚拟列,也可以像上面那样在其上添加索引(在这种情况下,索引占用磁盘空间)。这是MySQL 5.7.8中引入的一个新功能。


但是,如果我们有一个选择,由于二进制形式更短,它索引它看起来更合乎逻辑,而不是文本形式 - 索引将更小,从而更快地遍历,更快的备份...


最后,还有如何巧妙地重新排列二进制形式的字节的问题。


要了解这一点,我们需要了解更多关于UUID的信息。它们存在几个版本,不同的来源可以生成不同的版本。MySQL的UUID()使用版本1,这意味着,正如在RFC 4.1.2中所解释的那样,三个最左边的以破折号分隔的组是8字节的时间戳:最左边的组是时间戳的低四个字节; 第二组是中间两个字节,第三个组是高(最重要)两个字节的时间戳。因此,最左边的组变化最快(每微秒10次)。我们可以验证:




mysql> select uuid(); do sleep(2); select uuid();
+--------------------------------------+
| uuid()                               |
+--------------------------------------+
| 3b96402f-70c5-11e5-a4fb-b026b977eb28 |
+--------------------------------------+
+--------------------------------------+
| uuid()                               |
+--------------------------------------+
| 3cc7f7dc-70c5-11e5-a4fb-b026b977eb28 |
+--------------------------------------+

mysql> select uuid(); do sleep(2); select uuid();
+--------------------------------------+
| uuid()                               |
+--------------------------------------+
| 3b96402f-70c5-11e5-a4fb-b026b977eb28 |
+--------------------------------------+
+--------------------------------------+
| uuid()                               |
+--------------------------------------+
| 3cc7f7dc-70c5-11e5-a4fb-b026b977eb28 |
+--------------------------------------+
你可以看到最左边的8个字符是如何变化的,而其他的则没有。


因此,在由单个机器连续产生的UUID序列中,所有UUID具有不同的第一字节。将该序列插入索引列(二进制或文本形式)将因此每次修改不同的索引页面,从而防止内存中的缓存。因此,在我们存储到id_bin之前,重新安排UUID,使得快速变化的部分走到最后,是有意义的。再一次请注意,这个想法只适用于版本1的UUID。


这个想法不是我的 ; 我在第一次看到它这个博客(http://mysql.rjweb.org/doc.php/uuid)和那一个(https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/)。


以下,通过改变时间低/时间中/时间高到时间高/时间中/时间低来重新排列二进制形式。




create table users(id_bin binary(16), name varchar(200));


set @u = unhex(replace(uuid(),''-'',''''));


insert into users (id_bin,name)
values
(
 concat(substr(@u, 7, 2), substr(@u, 5, 2),
        substr(@u, 1, 4), substr(@u, 9, 8)),
 ''Andromeda''
);

create table users(id_bin binary(16), name varchar(200));
 
set @u = unhex(replace(uuid(),''-'',''''));
 
insert into users (id_bin,name)
values
(
 concat(substr(@u, 7, 2), substr(@u, 5, 2),
        substr(@u, 1, 4), substr(@u, 9, 8)),
 ''Andromeda''
);
我在(@u)之上使用了一个用户变量,因为每个SUBSTR()调用需要引用UUID值,但是我不能写UUID()四次:每次都会生成一个新的UUID!所以我调用一次UUID(),删除破折号,将其转换为二进制文件,将其存储在一个变量,并做它的四个SUBSTR。


但是,我仍然希望文本格式处于“未重新排列”的顺序,因为...或许这个文本格式将用于一些错误日志记录,调试?如果人类要阅读它,我不想通过重新排列的顺序来混淆它们。
添加id_text可以在CREATE TABLE中完成,或者作为后续的ALTER TABLE:




alter table users add
id_text varchar(36) generated always as
(
 insert(
   insert(
     insert(
       insert(
         hex(
           concat(substr(id_bin,5,4),substr(id_bin,3,2),
                  substr(id_bin,1,2),substr(id_bin,9,8))
         ),
         9,0,''-''),
     14,0,''-''),
   19,0,''-''),
 24,0,''-'')
) virtual;

 

 

alter table users add
id_text varchar(36) generated always as
(
 insert(
   insert(
     insert(
       insert(
         hex(
           concat(substr(id_bin,5,4),substr(id_bin,3,2),
                  substr(id_bin,1,2),substr(id_bin,9,8))
         ),
         9,0,''-''),
     14,0,''-''),
   19,0,''-''),
 24,0,''-'')
) virtual;
它将二进制形式的部分(带有SUBSTR)放在“正常”位置(CONCAT),将字节转换为十六进制数字(HEX)并插入破折号。对,这是一个复杂的表达式,但是在创建生成的列时只能输入一次。


现在看看数据:



select id_bin, hex(id_bin), name, id_text from users;
+------------------+----------------------------------+-----------+--------------------------------------+
| id_bin           | hex(id_bin)                      | name      | id_text                              |
+------------------+----------------------------------+-----------+--------------------------------------+
| �p�:�ˤ� &�w�        | 11E570EA3A059CCBA4FBB026B977EB28 | Andromeda | 3A059CCB-70EA-11E5-A4FB-B026B977EB28 |
+------------------+----------------------------------+-----------+--------------------------------------+

select id_bin, hex(id_bin), name, id_text from users;
+------------------+----------------------------------+-----------+--------------------------------------+
| id_bin           | hex(id_bin)                      | name      | id_text                              |
+------------------+----------------------------------+-----------+--------------------------------------+
| �p�:�ˤ� &�w�        | 11E570EA3A059CCBA4FBB026B977EB28 | Andromeda | 3A059CCB-70EA-11E5-A4FB-B026B977EB28 |

+------------------+----------------------------------+-----------+--------------------------------------+

 

专栏是:
1.隐含字符(重新排列的二进制UUID)
2.第一列的相应的十六进制代码
3.名字
4.未重新排列的文本UUID。看看这个文本形式最左边的3A059CCB是如何快速变化的部分,处于二进制形式(第2列)的中间,所以二进制形式将会提供更有效的索引。

 

java中使用UUID.randomUUID().toString().replace("-", "").toLowerCase()来生成UUID。

关于在MySQL中存储UUID v4在MySQL中存储过程对应的关键字是?的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于java – 如何在MySQL中存储图片?、Mysql中存储UUID去除横线的方法、MYSQL教程Mysql中存储UUID去除横线的方法、MySQL表中存储UUID值作为主键,使用UNHEX()提升性能的相关知识,请在本站寻找。

本文标签:

上一篇NVIDIA NVML 驱动程序/库版本不匹配(nvidia驱动程序与windows版本不兼容怎么办)

下一篇Android SQLiteDatabase SELECT查询需要很长时间(sql查询时间太长的原因)