├── LICENSE ├── README.MD ├── README_EN.MD ├── conf ├── common.ini └── local.ini ├── favicon.png ├── gensql.php ├── index.php ├── index_en.php └── sqlparse.php /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 wintercoder 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # 在线MYSQL测试数据生成工具 2 | 3 | 根据SQL表结构生成Mysql测试数据,根据字段名猜测类型,生成默认值 4 | 5 | [English Readme](./README_EN.MD) 6 | 7 | ## 生成规则 8 | 9 | 普通规则见[官网](http://www.datamaker.online/),此处讲个规则的组合使用 10 | 11 | **自增日期(组自增) + 常量列表(组模式)** 12 | 13 | 使用场景: 一个肯德基总店下有一堆子店,希望生成[每个子店每天]的数据,一行记录包含一个店一天的汇总数据 14 | 15 | 使用方法: 在子店ID 字段上选择 `常量列表(组模式)` 用逗号分隔写上各店的ID,日期选择 `自增日期(组自增)` 即可 16 | 17 | **Unique Key** 18 | 19 | 有 `UNIQUE KEY (user_id,platform) ` 的情况 20 | 21 | 方案一: 22 | 这种platform只有1和2的可以考虑使用 给 `platform` 选 `常量列表(组模式)` 填 `1,2`,然后user_id选自增之类保证不重就OK。 23 | 24 | 方案二: 25 | 选择重复Key选项,测试数据一般跳过就好,注意选 `REPLACE INTO` 可能出现 `AUTO_INCREMENT` + 2 的情况 26 | 27 | ## 个性化 28 | 你可以通过部署到自己的服务器上,对一些字段进行默认值配置,非常**适合公司内网** 29 | 部署也方便,代码里无任何框架依赖,能跑PHP就行 30 | 31 | ### 配置 32 | `/conf/common.ini` 为通用配置 33 | `/conf/local.ini` 为个性化配置,适合不宜暴露的默认值,如测试账号ID等,该文件已加入 `.gitignore` 里,如果发现不生效则跑下命令 34 | `git update-index --assume-unchanged conf/local.ini` 35 | 36 | 配置样例: 37 | 38 | ``` 39 | [0] 40 | key = index_day 41 | method = INCR_DAY 42 | value = 20180301 43 | way = match 44 | [1] 45 | key = url 46 | method = RAND_PIC_URL 47 | value = 300,400 48 | way = search 49 | ``` 50 | `key` : 字段名 51 | `method` : 生成规则,如下表 52 | `value` : 给前端的输入框值 53 | `way` : 输入的key跟配置文件的key匹配规则,目前支持 `match` 完全相等、`search` 字符串包含,默认为`match` 54 | 55 | 56 | | 规则英文 | 中文 | 参数 | 57 | |----------|------|------| 58 | | INCR_INT | 自增int | from : 从from开始自增,步长1 59 | | RAND_INT | 随机int | from,to : 生成[from,to]闭区间整数 60 | | RAND_FLOAT | 随机浮点 | from,to,round : 生成[from,to]闭区间浮点,保留round位小数,这三个参数都是整数 61 | | INCR_DAY | 日期自增 | from : 从from开始自增,步长1天,格式20180304 62 | | INCR\_DAY\_GROUPLY | 日期自增(组模式) | 同上,但每组值里的这个日期不变,下条SQL才变 63 | | RAND_TIMESTAMP | 随机时间戳 | from,to : 生成[from,to]这些天里的秒级时间戳,如 20180304,20180305 64 | | RAND\_TIMESTAMP\_MYSQL | 随机时间(Mysql格式) | from,to : 生成[from,to]这些天里的秒级时间,格式:2018-04-07 18:08:34 65 | | IGNORE | 不生成该列 | 66 | | CONST_STR | 常量 | 常量值 67 | | CONST\_STR\_LIST | 常量列表(组模式) | 输入 a,b,每条SQL都输出 a,b,此时组数固定 68 | | RAND_STR | 随机串 | length : 英文串长度 69 | | RAND\_STR\_LIST | 随机串(指定列表) | a,b,c : 该字段只出现a,b,c之一,可重复出现 70 | | INCR\_STR\_SUFFIX | 前缀+自增数字 | 输入 小王,输出 小王1,小王2,用于人名等 71 | | RAND\_PIC\_URL | 图片地址 | width,height : 图片的宽高 72 | 73 | ## 添加新生成规则流程 74 | 75 | 假设叫 rand_what 76 | 77 | 1. 前端 `index.php` 78 | 79 | `getDefaultValueByMethod()` 增加该规则的默认值 80 | `getHoverContent()` 增加该规则的hover文案 81 | `fillTabelWithData()` 增加对应代码 82 | 83 | 2. 后端 `gensql.php` 84 | 85 | `ValueGenerator` 类里新增 `randWhat()` 函数就行, 即下划线转驼峰 86 | 87 | 88 | 89 | ## License 90 | 91 | **The MIT License** 92 | -------------------------------------------------------------------------------- /README_EN.MD: -------------------------------------------------------------------------------- 1 | # Online Sql Test Data Generator 2 | 3 | 4 | Generate sql test data by Mysql table structure 5 | 6 | 7 | 8 | Input: 9 | 10 | ``` 11 | CREATE TABLE `student` ( 12 | `id` int(11) NOT NULL AUTO_INCREMENT, 13 | `user_id` int(11) NOT NULL, 14 | `name` varchar(20) NOT NULL , 15 | PRIMARY KEY (`id`), 16 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ; 17 | ``` 18 | 19 | Output: 20 | 21 | ``` 22 | INSERT INTO `student (user_id,name) VALUES ('10001','John1'),('10002','John2'); 23 | 24 | INSERT INTO `student (user_id,name) VALUES ('10003','John3'),('10004','John4'); 25 | 26 | ``` 27 | 28 | 29 | 30 | **[Try It Now ](http://datamaker.online/index_en.php)** 31 | 32 | 33 | 34 | ## Individuation 35 | You can deploy this project on your server to set default value for frequently used fields, good for local area network like company 36 | 37 | Easy to deploy: It only require PHP (without any framework) and webserver 38 | 39 | ### Config 40 | `/conf/common.ini` is common config 41 | `/conf/local.ini` is personal config, good for same private value like test account. For safe, you should run 42 | `git update-index --assume-unchanged conf/local.ini` 43 | to avoid traced to git 44 | 45 | Sample: 46 | 47 | ``` 48 | [0] 49 | key = index_day 50 | method = INCR_DAY 51 | value = 20180301 52 | way = match 53 | [1] 54 | key = url 55 | method = RAND_PIC_LIST 56 | value = 300,400 57 | way = search 58 | ``` 59 | `key` : field name 60 | `method` : generate rule in the following table 61 | `value` : default value for front-end 62 | `way` : `match`:match this config if the input key is equals to key ; `search` match this config if the input key contains this key; the defalut value is `match` 63 | 64 | 65 | | Rule Method | Description | Parameter | 66 | |----------|------|------| 67 | | INCR_INT | auto increment integer | `from` : increase from `from` 68 | | RAND_INT | random int | `from,to` : random in interval `[from,to]` 69 | | RAND_FLOAT | random float | `from,to,round` : Random in interval `[from,to]` , retains `round` digits after the decimal point 70 | | INCR_DAY | increment day | `from` : increase from `from` with format 20180304 71 | | INCR\_DAY\_GROUPLY | increment day (grouply same) | same as above,but the value is same in the same group 72 | | RAND_TIMESTAMP | random timestamp | `from,to` : timestamp in day `[from,to]`, input format is 20180304,20180305 73 | | RAND\_TIMESTAMP\_MYSQL | random time (Mysql) | `from,to` : same as above,but the result format is 2018-04-07 18:08:34 74 | | IGNORE | ignore this column | 75 | | CONST_STR | const value | 76 | | CONST\_STR\_LIST | const (group list) | `a,b`: every group in sql will output `a,b` 77 | | RAND_STR | random string | `length` : the length of string with alphabet 78 | | RAND\_STR\_LIST | random string in list | `a,b,c` : random pick one in `a,b,c` 79 | | INCR\_STR\_SUFFIX | Prefix + Number (Incr) | `test` : it will ouput test1,test2,test3 ... 80 | | RAND\_PIC\_URL | picture url | `width,height` : the width and height of url 81 | 82 | ## How to add new generator 83 | 84 | When you add a method call `rand_what` 85 | 86 | 1. Frontend: `index.php` 87 | 88 | `getDefaultValueByMethod()` add the default value 89 | `getHoverContent()` add the hover content 90 | `fillTabelWithData()` modify it 91 | 92 | 2. Backend`gensql.php` 93 | 94 | Add the function call `randWhat()` In class `ValueGenerator` ( Camel-Case of `rand_what` ) 95 | 96 | 97 | 98 | ## License 99 | 100 | **The MIT License** 101 | -------------------------------------------------------------------------------- /conf/common.ini: -------------------------------------------------------------------------------- 1 | [0] 2 | key = avatar 3 | method = RAND_PIC_URL 4 | value = 300,400 5 | way = search 6 | [1] 7 | key = photo 8 | method = RAND_PIC_URL 9 | value = 300,400 10 | way = search 11 | [2] 12 | key = picture 13 | method = RAND_PIC_URL 14 | value = 300,400 15 | way = search 16 | [3] 17 | key = url 18 | method = RAND_PIC_URL 19 | value = 300,400 20 | way = search 21 | [4] 22 | key = time 23 | method = RAND_TIMESTAMP 24 | value = 20180407,20180408 25 | way = search 26 | [5] 27 | key = phone 28 | method = RAND_INT 29 | value = 15602000001,15602009999 30 | way = search 31 | [6] 32 | key = insert_day 33 | method = INCR_DAY_GROUPLY 34 | value = 20180301 35 | way = match 36 | [7] 37 | key = index_day 38 | method = INCR_DAY 39 | value = 20180301 40 | way = match 41 | [8] 42 | key = status 43 | method = RAND_STR_LIST 44 | value = 0,1 45 | way = search 46 | [9] 47 | key = data_day 48 | method = INCR_DAY_GROUPLY 49 | value = 20180301 50 | way = match 51 | [10] 52 | key = is_ 53 | method = RAND_INT 54 | value = 0,1 55 | way = search 56 | [11] 57 | key = flag 58 | method = RAND_INT 59 | value = 0,1 60 | way = search 61 | [12] 62 | key = score 63 | method = RAND_INT 64 | value = 0,100 65 | way = search 66 | -------------------------------------------------------------------------------- /conf/local.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wintercoder/datamaker/c42e12258dc17c75e55dc654b67e29712309e79b/conf/local.ini -------------------------------------------------------------------------------- /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wintercoder/datamaker/c42e12258dc17c75e55dc654b67e29712309e79b/favicon.png -------------------------------------------------------------------------------- /gensql.php: -------------------------------------------------------------------------------- 1 | randTimestamp($input,$groupSize); 148 | foreach ($ret as &$item){ 149 | $item = date("Y-m-d H:i:s",$item); 150 | } 151 | return $ret; 152 | } 153 | 154 | /** 155 | * 常量 156 | * @param $input 157 | * value 常量值 158 | * @param $groupSize int 每组多少条合并成一个数组,也是该次函数返回的数组大小 159 | * @return array 160 | */ 161 | public function constStr($input,$groupSize){ 162 | return explode('$#$',str_repeat($input.'$#$',$groupSize)); 163 | } 164 | 165 | 166 | /** 167 | * 常量列表 168 | * @param $input 169 | * value 常量值 170 | * @param $groupSize int 每组多少条合并成一个数组,也是该次函数返回的数组大小 171 | * @return array 172 | */ 173 | public function constStrList($input,$groupSize){ 174 | $input = !empty($input) ? $input : '百度$#$阿里$#$腾讯'; 175 | return explode('$#$',$input); 176 | } 177 | 178 | /** 179 | * 随机字符串(字符集:大小写字母) 180 | * @param $input array 181 | * length 长度 182 | * @param $groupSize int 每组多少条合并成一个数组,也是该次函数返回的数组大小 183 | * @return array 184 | */ 185 | public function randStr($length,$groupSize) 186 | { 187 | $ret = []; 188 | $count = 0; 189 | while ($count++ < $groupSize) { 190 | $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 191 | $ranStr = ''; 192 | for ($i = 0; $i < $length; $i++) { 193 | $ranStr .= $characters[rand(0, strlen($characters) - 1)]; 194 | } 195 | $ret []= $ranStr; 196 | } 197 | return $ret; 198 | } 199 | /** 200 | * 在字符串列表里 随机,全局可重复 201 | * @param $input array 202 | * length 长度 203 | * @param $groupSize int 每组多少条合并成一个数组,也是该次函数返回的数组大小 204 | * @return array 205 | */ 206 | public function randStrList($input,$groupSize) 207 | { 208 | $input = !empty($input) ? $input : 'ofo,mobike'; 209 | $value = explode(',',$input); 210 | $ret = []; 211 | $count = 0; 212 | while ($count++ < $groupSize) { 213 | $ranStr = $value[rand(0, count($value) - 1)]; 214 | $ret []= $ranStr; 215 | } 216 | return $ret; 217 | } 218 | 219 | 220 | /** 221 | * 自增中文,根据 前缀+1 这种,如程序员1,程序员2 222 | * @param $input array 223 | * pre_str 前缀 224 | * @param $groupSize int 每组多少条合并成一个数组,也是该次函数返回的数组大小 225 | * @return array 226 | */ 227 | public function incrStrPrefix($input,$groupSize,$sqlCounter) 228 | { 229 | $pre = !empty($input) ? $input : '测试店'; 230 | $inputArr['from'] = 1; 231 | $intArr = $this->incrInt($inputArr,$groupSize,$sqlCounter); 232 | $ret = []; 233 | foreach ($intArr as $intVal){ 234 | $str = $pre . $intVal; 235 | $ret []= $str; 236 | } 237 | return $ret; 238 | } 239 | 240 | /** 241 | * 随机图片,目前是 http://lorempixel.com/ 242 | * 也可以考虑用百度的 http://image.baidu.com/channel/listjson?pn=0&rn=30&tag1=%E7%BE%8E%E5%A5%B3&tag2=%E5%85%A8%E9%83%A8&ie=utf8 243 | * @param $input 244 | * @param $groupSize int 每组多少条合并成一个数组,也是该次函数返回的数组大小 245 | * @return array 246 | */ 247 | public function randPicUrl($input,$groupSize){ 248 | $exp = explode(',',$input); 249 | $width = !empty($exp[0]) ? intval($exp[0]) : 300; 250 | $height = !empty($exp[1]) ? intval($exp[1]) : 300; 251 | $url = "http://lorempixel.com/{$width}/{$height}/"; 252 | 253 | return explode(',',str_repeat($url.',',$groupSize)); 254 | } 255 | } 256 | 257 | class WorkHandler{ 258 | 259 | // /** 260 | // * 同步的数据导出,格式为.sql 261 | // */ 262 | // public function syncExportStr2File($fileName, $content){ 263 | // header_remove(); 264 | // ini_set('memory_limit', '128M'); 265 | // set_time_limit(1800); 266 | // header("Content-type:text/html;charset=utf-8"); 267 | // // header("Content-Transfer-Encoding: binary"); 268 | // // header("Content-Type: application/force-download;"); 269 | // header("Content-type: application/octet-stream"); 270 | // header("Cache-control: no-cache"); 271 | // header("Content-Transfer-Encoding: binary"); 272 | // header("Content-Disposition: attachment; filename=$fileName.sql"); 273 | // header("Expires: 0"); 274 | // header("Cache-control: private"); 275 | // header("Pragma: no-cache"); 276 | // header('Content-Length: ' . strlen($content)); 277 | 278 | // // $content = iconv('UTF-8', 'GBK//IGNORE', $content); 279 | // echo $content.PHP_EOL; 280 | // exit(); 281 | // } 282 | 283 | public function checkParams($input){ 284 | $input = json_decode($input,true); //json转数组 285 | if(empty($input) || empty($input['list'])){ 286 | echo "参数不是JSON格式";exit(); 287 | } 288 | $input['count'] = intval($input['count']); 289 | $input['group_size'] = intval($input['group_size']); 290 | if( $input['count'] <= 0 || $input['group_size'] <= 0 291 | || $input['count'] >= 5000 || $input['group_size'] >= 5000) { 292 | echo "条数、组数只能是 1 到 5000 以内";exit(); 293 | } 294 | } 295 | 296 | public function execute($input){ 297 | $this->checkParams($input); 298 | 299 | $input = json_decode($input,true); //json转数组 300 | $inputList = $input['list']; 301 | 302 | //对于自增ID等忽略的类型,删除它并重排下标,不能用 array_splice ,删除多个时会乱 303 | foreach ($inputList as $key => $item){ 304 | if($item['method'] == 'ignore'){ 305 | unset($inputList[$key]); 306 | } 307 | } 308 | $inputList = array_values($inputList); //从0开始 重建下标 309 | 310 | $genCount = !empty($input['count']) ? $input['count'] : 5 ; 311 | $tableName = !empty($input['table_name']) ? $input['table_name'] : 'test'; 312 | $groupSize = $input['group_size']; //每个SQL有多少value组 313 | $insertWay = !empty($input['insert_way']) ? $input['insert_way'] : 'INSERT INTO '; 314 | 315 | $keyArr = array_column($inputList,'key'); 316 | 317 | $generator = new ValueGenerator(); 318 | 319 | $sql = ''; 320 | //insert的SQL条数 321 | for($genI = 1; $genI <= $genCount; $genI++) { 322 | 323 | $genResult = []; //生成结果数组: key => 生成方法+下标 防止同样的方法覆盖数据,value => 按该方法生成的数据数组 324 | foreach ($inputList as $itemIndex => $item){ 325 | $genService = $this->camelize($item['method']); //方法名转驼峰 326 | $genResult [ $item['method'].$itemIndex ] = $generator->$genService($item['value'],$groupSize,$genI ); 327 | } 328 | $valueStr = ''; 329 | 330 | //每个SQ有多少value组 331 | for($cnt = 0; $cnt < $groupSize; $cnt++){ 332 | 333 | $valueStr .= '('; 334 | //取每个字段的值,单引号引起来 335 | foreach ($genResult as $result) { 336 | $valueStr .= "'{$result[$cnt]}',"; 337 | } 338 | $valueStr = rtrim($valueStr,','); 339 | $valueStr .= '),'; 340 | } 341 | $valueStr = rtrim($valueStr,','); 342 | $valueStr .= ';'; 343 | $sql .= $insertWay . "{$tableName} (" . implode(",",$keyArr) .") VALUES $valueStr"; 344 | $sql .= "\n"; 345 | $sql .= "\n"; 346 | } 347 | //一直没成功,还怀疑是jq的post方法不是超链导致,最终用前端去做了 348 | // $this->syncExportStr2File('datamake_'.date('YmdHis', time()).'sql' ,$sql); 349 | echo $sql; 350 | } 351 | 352 | /** 353 | * 下划线转驼峰 354 | * @param $str 355 | * @param string $separator 356 | * @return string 357 | */ 358 | private function camelize($str,$separator='_') 359 | { 360 | $str = $separator. str_replace($separator, " ", strtolower($str)); 361 | return ltrim(str_replace(" ", "", ucwords($str)), $separator ); 362 | } 363 | } 364 | 365 | 366 | date_default_timezone_set("Asia/Shanghai"); 367 | 368 | $postData = file_get_contents('php://input'); //提交的是JSON,不能直接$post获取 369 | if(empty($postData)){ 370 | echo "我是空白"; 371 | exit(); 372 | } 373 | //echo ($postData);exit(); 374 | 375 | 376 | $handler = new WorkHandler(); 377 | $handler->execute($postData); 378 | exit(); 379 | 380 | /* 381 | $parser = new CreateSqlParser(); 382 | $ret = $parser->execute($sql); 383 | if(0 == ($ret['error'])){ 384 | 385 | $input = json_encode($ret['data']); 386 | $handler = new WorkHandler(); 387 | $handler->execute($input); 388 | } else{ 389 | echo json_encode($ret);exit(); 390 | 391 | } 392 | 393 | */ -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 2 |
3 |列名 | 140 |生成规则 | 141 |参数 | 142 |
---|
Copyright © 小光 2017. 你的备案号
498 |Column | 137 |Rule | 138 |Parameter | 139 |
---|