MySQL本身提供一个叫rand的函数,返回的v范围为0 <= v < 1.0。
    介绍此函数的MySQL文档也介绍道,可以通过此计算公式FLOOR(i + RAND() * (j – i)),获取i <= v < j的随机数字v。

    1. CREATE FUNCTION rand_num ( start_num INTEGER,
    2. end_num INTEGER
    3. ) RETURNS INTEGER
    4. DETERMINISTIC
    5. BEGIN
    6. RETURN FLOOR(start_num + RAND() * (end_num - start_num + 1));
    7. END;

    比如,要获取1-9的随机数,如此调用即可:

    select rand_num(1, 9);
    

    因为CREATE PROCEDURE, CREATE FUNCTION, ALTER PROCEDURE,ALTER FUNCTION,CALL, DROP PROCEDURE, DROP FUNCTION等语句都会被写进二进制日志, 然后在从服务器上执行。
    但是,一个执行更新的不确定子程序(存储过程、函数、触发器)是不可重复的,

    在从服务器上执行(相对与主服务器是重复执行)可能会造成恢复的数据与原始数据不同,从服务器不同于主服务器的情况。

    为了解决这个问题,MySQL强制要求:
    在主服务器上,除非子程序被声明为确定性的或者不更改数据,否则创建或者替换子程序将被拒绝。
    这意味着当创建一个子程序的时候,必须要么声明它是确定性的,要么它不改变数据。
    声明方式有两种,

    第一种: 声明是否是确定性的
    DETERMINISTIC和NOT DETERMINISTIC指出一个子程序是否对给定的输入总是产生同样的结果。
    如果没有给定任一特征,默认是NOT DETERMINISTIC,所以必须明确指定DETERMINISTIC来声明一个子程序是确定性的。
    这里要说明的是:使用NOW() 函数(或它的同义)或者RAND() 函数不会使一个子程序变成非确定性的。
    对NOW()而言,二进制日志包括时间戳并会被正确的执行。RAND()只要在一个子程序内被调用一次也可以被正确的复制。
    所以,www.linuxidc.com可以认为时间戳和随机数种子是子程序的确定性输入,它们在主服务器和从服务器上是一样的。