MySQL 生成随机数字、字符串、日期、验证码及 UUID的方法

2022-05-21 0 327
目录
  • 生成随机数字
    • 生成 0 到 1 之间的随机数
    • 生成指定范围内的随机数
    • 生成 6 位数字手机验证码
    • 生成遵循正态分布的随机数
  • 生成随机字符串
    • 生成固定长度的随机字符串
    • 生成可变长度的随机字符串
  • 生成随机日期和时间
    • 获取表中的随机记录
      • 生成 UUID
        • 总结

          上一篇介绍了如何在 Oracle 生成随机数字、字符串、日期、验证码以及 UUID,今天我们继续讨论在 MySQL 中生成各种随机数据的方法。

          计算机生成的都是伪随机数,并不是真正的物理随机数。

          生成随机数字

          生成 0 到 1 之间的随机数

          MySQL 中的 RAND 函数可以用于生成一个大于等于 0 小于 1 的随机数字。例如:

          SELECT rand();
          rand()   |
          ------------------|
          0.7245639057127423|
          
          SELECT rand();
          rand()    |
          -------------------|
          0.01697599982561171|

          该函数返回的数据类型为 double,包含 16 位小数;每次调用都会返回不同的数据。

          如果想要重现某些场景,需要确保每次运行时生成相同的随机数。这种情况下可以为 RAND 函数传递一个输入参数,设置一个随机数种子。例如:

          SELECT rand(1);
          rand(1)   |
          -------------------|
          0.40540353712197724|
          
          SELECT rand(1);
          rand(1)   |
          -------------------|
          0.40540353712197724|

          从结果可以看出,相同的种子返回了相同的随机数。

          生成指定范围内的随机数

          基于 RAND 函数和数学运算,可以返回任意两个数字之间的随机数:

          low + RAND() * (high − low)

          以上表达式将会返回一个大于等于 low,小于 high 的随机数。例如:

          SELECT 10 + rand(1) * 10;
          10 + rand(1) * 10 |
          ------------------|
          14.054035371219772|

          以上示例返回了一个大于等于 10 且小于 20 的随机数字。

          如果想要生成某个范围内的随机整数,可以加上 FLOOR 函数。例如:

          SELECT floor(10 + rand(1) * (10)) AS rd;
          rd |
          ----|
          14.0|

          该语句返回了一个大于等于 10,小于等于 19(不是 20)的随机整数。

          生成 6 位数字手机验证码

          我们已经获得了指定范围内的随机整数,加上 LPAD 函数就可以生成由 6 位数字字符组成的手机验证码。例如:

          SELECT lpad(floor(rand(999) * 1000000), 6, '0') AS captcha;
          captcha|
          -------|
          088146 |

          其中,lpad 函数可以确保数据不够 6 位时在前面补足 0。

          生成遵循正态分布的随机数

          RAND 函数生成的是一个遵循均匀分布的随机数,MySQL 没有提供生成遵循正态分布(normal distribution)的随机数。我们可以创建一个存储函数来模拟正态分布的随机数:

          delimiter //
          create function normal_distrib(mean double, stdev double) 
          returns double no sql
          begin
          set @x = rand(), @y = rand();
          set @nd = (sqrt(-2 * log(@x)) * cos(2 * pi() * @y)) * stdev + mean;
          return @nd;
          end
          //
          delimiter ;

          以上函数利用 Box-Muller 变换算法通过两个平均分布的随机数生成正态分布的随机数。

          以下语句通过 normal_distrib 函数生成了一个期望值为 0,标准差为 1 的正态分布随机数:

          SELECT normal_distrib(0,1);
          normal_distrib(0,1)|
          -------------------|
           1.4930564399841173|

          以下语句可以用于验证 normal_distrib 函数是否遵循正态分布:

          with recursive temp(val) as (
           select normal_distrib(0,1)
           union all
           select normal_distrib(0,1)
           from temp
           limit 1000000
          )
          select /*+ set_var(cte_max_recursion_depth = 1m) */avg(val),std(val)
          from temp;
          avg(val)    |std(val)   |
          ---------------------|------------------|
          -0.002340136192616743|0.9994844557755181|

          通过运行 1000000 次,计算这些数据的平均值和标准差,返回结果非常接近 0 和 1。

          生成随机字符串

          生成固定长度的随机字符串

          除了随机数字之外,有时候我们也需要生成一些随机的字符串。MySQL 没有提供专门生成随机字符串的函数,但是可以通过其他函数进行模拟。例如:

          SELECT char(floor(rand() * 26)+65) as rand_char;
          rand_char|
          ---------|
          T  |

          以上查询返回了一个随机的大写字母,char 函数用于将 ASCII 码转换为对应的字符。我们可以基于该查询进一步创建一个存储函数:

          delimiter //
          create function rand_string(len integer) 
          returns text no sql
          begin
           declare counter int default 1;
           declare str text default '';
           
           if len < 1 then
           return null;
           end if;
           
           while counter <= len do
           set str = concat(str, char(floor(rand() * 94) + 33));
           set counter = counter + 1;
           end while;
           
           return str;
          end
          //
          delimiter ;

          rand_string 函数可以返回由任意可打印字符(ASCII 码从 33 到 126)组成的随机字符串。例如:

          rand_string(8)|
          --------------|
          7j5dz[58  |

          以上示例返回了一个长度为 8,由可打印字符组成的随机字符串。

          另外,MySQL 中的 elt 函数也可以用于返回指定位置中的元素。例如:

          SELECT elt(1 + floor(rand() * 36),
             0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
             'A','B','C','D','E','F','G',
             'H','I','J','K','L','M','N',
             'O','P','Q','R','S','T',
             'U','V','W','X','Y','Z') as val;
          val|
          ---|
          B |

          以上语句返回了一个随机的数字或者大写字母,将其替换到 rand_string 函数可以返回一个由数字和大写字母组成的随机字符串。

          生成可变长度的随机字符串

          那么,怎么返回一个长度可变的随机字符串呢?很简单,为 rand_string 函数指定一个随机的长度参数即可。例如:

          SELECT rand_string(floor(10 + rand() * 11));
          rand_string(floor(10 + rand() * 11))|
          ------------------------------------|
          4U13MjO+($}k"cO@5%[     |

          以上示例返回了一个长度大于等于 10 且小于等于 20,由可打印字符组成的随机字符串。

          生成随机日期和时间

          将指定日期增加一个随机的数字,就可以得到随机的日期。例如:

          SELECT date_add('2020-01-01', interval rand() * 31 day) rand_date;
          rand_date |
          ----------|
          2020-01-19|

          以上示例返回了 2020 年 1 月中的某个随机日期。以下语句则返回了一天中的某个随机时间:

          SELECT sec_to_time(rand() * 3600) rand_time;
          rand_time   |
          ------------------|
          00:05:29.546878000|

          其中,sec_to_time 函数用于将秒数转换为时间数据。

          获取表中的随机记录

          对于返回多行数据的查询语句,RAND 函数每次都会返回不同的随机数据。例如:

          SELECT rand(1) FROM employee;
          rand(1)    |
          --------------------|
           0.40540353712197724|
           0.8716141803857071|
           0.1418603212962489|
          ...

          利用这个特性,我们可以从表中返回随机的数据行。例如:

          SELECT emp_id,emp_name
          FROM employee
          ORDER BY rand(1)
          LIMIT 5;
          emp_id|emp_name |
          ------|----------|
            6|魏延  |
           14|张苞  |
           16|周仓  |
           15|赵统  |
            1|刘备  |

          以上示例从 employee 表中返回了 5 行随机记录。该方法需要为表中的每行数据都生成一个随机数,然后进行排序;所以会随着表中的数据量增加而逐渐变慢。

          如果表中存在自增主键,也可以基于主键生成一个随机数据。例如:

          SELECT round(rand() * (SELECT max(emp_id) FROM employee)) AS id;
          id |
          ----|
          10.0|

          然后基于这个随机数返回一条随机的记录:

          SELECT e.emp_id, e.emp_name
          FROM employee e
          INNER JOIN (SELECT round(rand() * (SELECT max(emp_id) FROM employee)) AS id
            ) AS t
          WHERE e.emp_id >= t.id
          LIMIT 1;
          emp_id|emp_name|
          ------|--------|
            9|赵云  |

          这种方法一次只能返回一条随机记录,而且只有当自增字段的值没有间隙时才会返回均匀分布的随机记录。

          生成 UUID

          UUID(Universal Unique Identifier)或者 GUID(Globally Unique Identifier)是一个 128 比特的数字,可以用于唯一标识每个网络对象或资源。由于它的生成机制,一个 UUID 可以保证几乎不会与其他 UUID 重复,因此常常用于生成数据库中的主键值。

          MySQL 提供了一个系统函数 UUID,可以用于生成 UUID。例如:

          SELECT uuid();
          uuid()        |
          ------------------------------------|
          35f67fde-e0e9-11ea-9d25-0800272142b1|

          如果想要生成没有中划线(-)的 UUID,可以使用 REPLACE 函数:

          SELECT replace(uuid(),'-','');
          replace(uuid(),'-','')   |
          --------------------------------|
          8505290be0ea11ea9d250800272142b1|

          除此之外,MySQL 还提供了一个UUID_SHORT 函数,它可以返回一个 64 比特的无符号整数。例如:

          SELECT uuid_short();
          uuid_short()  |
          -----------------|
          98862025337208832|

          该函数返回的是一个“短的”唯一标识符,只有满足以下条件时才具有唯一性:

          • 当前服务器的 server_id 位于 0 到 255 之间,并且在复制结构中具有唯一性;
          • 重启 mysqld 前后没有将服务器主机的系统时间往回调整;
          • 每秒钟的平均调用次数少于 1600 万次。

          总结

          本文介绍了在 MySQL 数据库中生成随机数据的方法,包括随机数字、验证码、随机字符串以及随机日期和时间等,同时还介绍了如何从表中返回随机记录,以及如何生成 UUID。

          到此这篇关于MySQL 生成随机数字、字符串、日期、验证码及 UUID的方法的文章就介绍到这了,更多相关MySQL 生成随机数字 UUID内容请搜索NICE源码以前的文章或继续浏览下面的相关文章希望大家以后多多支持NICE源码!

          免责声明:
          1、本网站所有发布的源码、软件和资料均为收集各大资源网站整理而来;仅限用于学习和研究目的,您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 不得使用于非法商业用途,不得违反国家法律。否则后果自负!

          2、本站信息来自网络,版权争议与本站无关。一切关于该资源商业行为与www.niceym.com无关。
          如果您喜欢该程序,请支持正版源码、软件,购买注册,得到更好的正版服务。
          如有侵犯你版权的,请邮件与我们联系处理(邮箱:skknet@qq.com),本站将立即改正。

          NICE源码网 MySql MySQL 生成随机数字、字符串、日期、验证码及 UUID的方法 https://www.niceym.com/42032.html