我有一个 PHP 函数来创建那些著名的 AlphaID 整数表示,如下所示:
function alphaID( $input ) {
$index = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$base = strlen( $index );
$input += pow( $base, 4 );
$output = '';
for( $i = floor( log( $input, $base ) ); $i >= 0; $i-- ) {
$bcp = bcpow( $base, $i );
$start = floor( $input / $bcp ) % $base;
$output .= substr( $index, $start, 1 );
$input = $input - ( $start * $bcp );
}
return $output;
}
编码,例如,PHP_MAX_INT常量 (2147483647) 提供的最大整数将返回cwuCBb
但是我认为在整个应用程序图片中它有点太慢了,所以我尝试创建一个 MYSQL 函数,所以理论上,一旦数据在查询时为我准备好,我就不会浪费性能使用 PHP 进行这种转换。
MySQL手册并不完全友好,但在这里和那里搜索我想出了这个:
DROP FUNCTION IF EXISTS ENCODE_ALPHAID;
DELIMITER $$
CREATE FUNCTION ENCODE_ALPHAID( input integer ) RETURNS CHAR( 6 ) DETERMINISTIC
BEGIN
DECLARE output CHAR( 6 );
DECLARE letters CHAR( 62 );
DECLARE base TINYINT( 2 );
DECLARE iterator TINYINT( 2 );
DECLARE bcp CHAR( 9 );
DECLARE start TINYINT( 2 );
SET output = '';
SET letters = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
SET base = CHAR_LENGTH( letters );
SET input = input + POW( base, 4 );
SET iterator = FLOOR( LOG( base, input ) );
ENCODING: LOOP
SET bcp = POW( base, iterator );
SET start = FLOOR( input / bcp ) % base + 1;
SET output = CONCAT( output, SUBSTR( letters, start, 1 ) );
SET input = input - ( start * bcp );
SET iterator = iterator-1;
IF iterator < 0 THEN LEAVE ENCODING; END IF;
END LOOP ENCODING;
RETURN output;
END $$
DELIMITER ;
但是当我通过我使用的 MySQL 管理器(DBNinja)运行它时,显然没有任何反应。运行查询后,它显示0 行受影响,我不确定这是否是预期的输出。
无论对与否,该函数都不起作用,因为当我尝试在查询中使用它时:
SELECT ENCODE_ALPHAID( `c`.`cid` ) from `table` c WHERE `c.user` = 1
我第一次收到一个错误,说table.ENCODE_ALPHAID不存在。然后我注意到,事实上,我在尝试使用的数据库的不同数据库中创建了该函数。
但是我在正确的数据库中再次创建了它,但出现了同样的错误。
所以这里有问题:
- 我做错了什么?这是我第一次尝试做这样的事情,我不确定
- 我的 PHP 代码实现是有效的 MySQL 对应物吗?我错过了什么吗?
- 我可以将此功能设为“全局”吗?我的意思是,可用于我需要的任何数据库?因为对于我正在处理的应用程序,为了使所涉及的两个子系统保持分离,我创建了两个数据库。
更新
显然,没有创建函数的问题出在 DBNinja 的末尾,因为我直接在 MySQL 控制台中运行了该语句,虽然输出状态相同,0 行受影响,但我能够在语句中有效地使用该函数,所以函数毕竟是创建的。
但是,例程本身有问题,因为当我测试它时,结果字符串是......“一个领先”。
例如,如果我运行以下 PHP 代码:
echo alphaID( 2 );
它会产生baaac,但 MySQL 函数返回baaad,这将是整数3的 AlphaID 表示
这不仅是错误的,而且我认为它还可能溢出达到最大值时使用的 INT 类型 2147483647