【发布时间】:2019-05-18 05:52:35
【问题描述】:
我在一个 MySQL 表中有 70,000 行。我正在尝试通过导入 JSON 将它们上传到 Firebase。我已将表格导出为 JSON 格式。输出是一个数组。例如,JSON 如下 -
[
{"question_id":"99","question":"What is your name?"},
{"question_id":"200","question":"What do you do?"}
]
为了在移动应用程序中正确使用 Firebase,我需要将此 JSON 数据作为对象导入,以及如下所示的 GUID -
{
"-Lf64AvZinbjvEQLMzGc" : {
"question_id" : 99,
"question" : "What is your name?"
},
"-Lf64AvZinbjvEQLMzGd" : {
"question_id" : 200,
"question" : "What do you do?"
}
}
由于行数为 70,000(此数据的 JSON 文件为 110 MB);无法单独插入 Firebase。 所以我尝试了一种生成 70,000 GUID 并编辑 JSON 文件以在每个对象之前添加每个 GUID 的方法。但是,我在这两个地方都卡住了。我正在使用以下类 (PushId.php) 来生成 GUID -
<?php
/**
* Fancy ID generator that creates 20-character string identifiers with the following properties:
*
* 1. They're based on timestamp so that they sort *after* any existing ids.
* 2. They contain 72-bits of random data after the timestamp so that IDs won't collide with other clients' IDs.
* 3. They sort *lexicographically* (so the timestamp is converted to characters that will sort properly).
* 4. They're monotonically increasing. Even if you generate more than one in the same timestamp, the
* latter ones will sort after the former ones. We do this by using the previous random bits
* but "incrementing" them by 1 (only in the case of a timestamp collision).
*/
class PushId
{
/**
* Modeled after base64 web-safe chars, but ordered by ASCII.
*
* @var string
*/
const PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
/**
* Timestamp of last push, used to prevent local collisions if you push twice in one ms.
*
* @var int
*/
private static $lastPushTime = 0;
/**
* We generate 72-bits of randomness which get turned into 12 characters and appended to the
* timestamp to prevent collisions with other clients. We store the last characters we
* generated because in the event of a collision, we'll use those same characters except
* "incremented" by one.
*
* @var array
*/
private static $lastRandChars = [];
/**
* @return string
*/
public static function generate()
{
$now = (int) microtime(true) * 1000;
$isDuplicateTime = ($now === static::$lastPushTime);
static::$lastPushTime = $now;
$timeStampChars = new SplFixedArray(8);
for ($i = 7; $i >= 0; $i--) {
$timeStampChars[$i] = substr(self::PUSH_CHARS, $now % 64, 1);
// NOTE: Can't use << here because javascript will convert to int and lose the upper bits.
$now = (int) floor($now / 64);
}
static::assert($now === 0, 'We should have converted the entire timestamp.');
$id = implode('', $timeStampChars->toArray());
if (!$isDuplicateTime) {
for ($i = 0; $i < 12; $i++) {
$lastRandChars[$i] = floor(rand(0, 64));
}
} else {
// If the timestamp hasn't changed since last push, use the same random number, except incremented by 1.
for ($i = 11; $i >= 0 && static::$lastRandChars[$i] === 63; $i--) {
static::$lastRandChars[$i] = 0;
}
static::$lastRandChars[$i]++;
}
for ($i = 0; $i < 12; $i++) {
$id .= substr(self::PUSH_CHARS, $lastRandChars[$i], 1);
}
static::assert(strlen($id) === 20, 'Length should be 20.');
return $id;
}
/**
* @param bool $condition
* @param string $message
*/
private static function assert($condition, $message = '')
{
if ($condition !== true) {
throw new RuntimeException($message);
}
}
}
以下是我为生成 70,000 个 GUID 而编写的 PHP 代码,但它显示错误(如果我只使用它生成 1 个 GUID,则相同的代码正在工作)
require_once('PushId.php');
$vars = new PushId();
$my_file = 'TheGUIDs.txt';
$handle = fopen($my_file, 'w') or die('Cannot open file: '.$my_file);
$i=1;
while($i <= 70000){
$data = $vars->generate();
fwrite($handle, $data);
echo $data;
$i++;
}
fclose($handle);
编辑 -1
我在生成 GUID 时遇到的错误是 -
Notice: Undefined offset: 11 in C:\wamp64\www\firebase-json\PushId.php on line 65
Notice: Undefined variable: lastRandChars in C:\wamp64\www\firebase-json\PushId.php on line 71
第一个 GUID 是完整的,例如在上次运行中我得到了-Lf8WPlkkNTUjYkIP4WT,但后来我得到了不完整的 GUID -Lf8WPlk------------
【问题讨论】: