PHP 导入导出excel、csv百万数据到数据库

待解决:

wamp下导入导出百万数据没有问题
lnmp下导入10W条数据没问题,导入50W及以上会出现nginx504报错

代码包地址

测试数据表地址

表中有大概110W+条数据,下载时可能会慢一些
下载完成后,导入到数据库中,然后用Navicat修改表为MYISAM类型,把触发器删除掉即可

环境

WAMP和LNMP
PHP版本: 7.3

目录结构

PHPExcel
	PHPExcel
	PHPExcel.php	Excel类
DB.php				PDO操作类
export.php			导出
import.php			导入
LICENSE			
phpinfo.php
price_copy.sql		数据表结构
README.md			readme
test.php			测试文件

踩过的坑总结:

看apache、nginx的错误日志
导出时,10000条数据以下导出xls格式,10000条数据以上导出csv格式
导入时,用到了array_chunk()批量插入的方法,为的是给数据库一个缓冲的时间
当数据量很大时,可以用这个函数设置每几百或几千次执行一次sql,需要开启事务

# 导入、导出都必须设置的:
ini_set('memory_limit','5600M'); //设置程序运行的内存
ini_set('max_execution_time',0); //设置程序的执行时间,0为无上限
ini_set('display_errors', 1); // 开启报错
error_reporting( E_ALL ); //设置报错等级
# 导入时必须要设置的
	php.ini:
		找到:post_max_size = 8M,表单提交最大数据为 8M,此项不是限制上传单个文件的大小,而是针对整个表单的提交数据进行限制的。限制范围包括表单提交的所有内容.例如:发表贴子时,贴子标题,内容,附件等…这里修改为:
		post_max_size = 1024M
		找到:upload_max_filesize = 2M ,上载文件的最大许可大小 ,修改为:
		upload_max_filesize = 1024M
	httpd.conf:
		LimitRequestBody 1024000000 #添加
	nginx.conf:
		# 放到http{}里
	    fastcgi_connect_timeout 300;
	    fastcgi_send_timeout 300;
	    fastcgi_read_timeout 300;
	    client_max_body_size 1000M;

下载PHPEXCEL:
git克隆

git clone git@github.com:PHPOffice/PHPExcel.git

composer安装

composer require phpoffice/phpexcel

直接下载
PHPEXCEL类库地址

下载到本地之后,只需要Classes文件夹,把Classes改成PHPExcel即可
在这里插入图片描述
目录结构如下:
在这里插入图片描述
使用方法:

导出:
	导出前的准备工作
	修改export.php 21行的代码 ,通过limit控制导出数据条数
	$sql = " select * from ht_price limit 10000";
	执行方法:
	http://localhost/excel/export.php 
	
导入:
	先使用导出方法导出到本地,再从本地选择excel文件上传到服务器中,
	如果返回true,到price_copy表中看数据即可
	执行方法:
	http://localhost/excel/import.php 

配置DB类
在这里插入图片描述
导出:

<?php
#!/bin/bash

/**
 * User: hzbskak
 * Date: 2019/12/31 - 9:16
 */

require_once "DB.php";
require_once "PHPExcel/PHPExcel.php";
$db = new DB();

// 文件名和文件类型
$fileName = "student";
$fileType = "xlsx";
ini_set('memory_limit','5600M'); //设置程序运行的内存
ini_set('max_execution_time',0); //设置程序的执行时间,0为无上限
ini_set('display_errors', 1); //
error_reporting( E_ALL );
// 百万数据
$sql = " select * from ht_price limit 500000";
$data = $db->getAll( $sql);
// 最大列数
$sql2 = "select count(1) from information_schema.COLUMNS where table_name = 'ht_price'";
$column_max = $db->getRow( $sql2)['count(1)'];
// 表的字段key value
$sql3 = "select column_name as k,column_comment as v from information_schema.columns where table_name='ht_price'";
$kv = $db->getAll( $sql3);
// 少量数据
if( count( $data) < 10000)
{
    $obj = new \PHPExcel();

// 以下内容是excel文件的信息描述信息
    $obj->getProperties()->setCreator('创建者11'); //设置创建者
    $obj->getProperties()->setLastModifiedBy('修改者11'); //设置修改者
    $obj->getProperties()->setTitle('标题11'); //设置标题
    $obj->getProperties()->setSubject('主题11'); //设置主题
    $obj->getProperties()->setDescription('描述11'); //设置描述
    $obj->getProperties()->setKeywords('关键词11');//设置关键词
    $obj->getProperties()->setCategory('类型11');//设置类型

// 设置当前sheet
    $obj->setActiveSheetIndex(0);

// 设置当前sheet的名称
    $obj->getActiveSheet()->setTitle('sheet11');


// 循环列 输出 a-z-zz
    $list = [];
    for ($i = 0; $i <= $column_max-1; $i++) {

        $y = ($i / 26);
//    echo $i,"=>";
        if ($y >= 1) {
            $y = intval($y);
            $a = chr($y+64);
            $b = chr($i-$y*26 + 65);
            $list [] = $a . $b;
        } else {
            $c = chr($i+65);
            $list [] = $c;
        }
//    echo "\r\n";
    }

// 填充第一行数据
    $sheet=  $obj->getActiveSheet();
    foreach ( $kv as $k => $v)
    {
        $sheet->setCellValue( $list[$k] . '1', $v['v']);
    }

// 填充第n(n>=2, n∈N*)行数据
    $length = count($data);
    foreach ( $data as $k => $v)
    {
        foreach ( $kv as $kk => $vv)
        {
            // 需要转换成文本的值手动加空格
            if( $vv['k'] == 'market_code')
            {
                $sheet->setCellValue( $list[$kk] . ($k + 2), $v[$vv['k']] . ' ',
                    \PHPExcel_Cell_DataType::TYPE_STRING);//将其设置为文本格式
            }
            elseif( $vv['k'] == 'date')
            {
                $v[$vv['k']] = date( 'Y-m-d H:i:s', $v[$vv['k']]);
                $sheet->setCellValue( $list[$kk] . ($k + 2), $v[$vv['k']],
                    \PHPExcel_Cell_DataType::TYPE_STRING);//将其设置为文本格式
            }
            else
            {
                $sheet->setCellValue( $list[$kk] . ($k + 2), $v[$vv['k']],
                    \PHPExcel_Cell_DataType::TYPE_STRING);//将其设置为文本格式
            }
        }
    }
// 设置加粗和左对齐
    foreach ($list as $col) {
        // 设置第一行加粗
        $obj->getActiveSheet()->getStyle($col . '1')->getFont()->setBold(true);
        // 设置第1-n行,左对齐
        for ($i = 1; $i <= $length + 1; $i++) {
            $obj->getActiveSheet()->getStyle($col . $i)->getAlignment()->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
        }
    }

// 设置列宽
    $obj->getActiveSheet()->getColumnDimension('D')->setWidth(20);

// 导出
    ob_clean();
    if ($fileType == 'xls') {
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="' . $fileName . '.xls');
        header('Cache-Control: max-age=1');
        $objWriter = new \PHPExcel_Writer_Excel5($obj);
        $objWriter->save('php://output');
        exit;
    } elseif ($fileType == 'xlsx') {
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="' . $fileName . '.xlsx');
        header('Cache-Control: max-age=1');
        $objWriter = \PHPExcel_IOFactory::createWriter($obj, 'Excel2007');
        $objWriter->save('php://output');
        exit;
    }
}
else
{
    // 大量数据
    ob_end_clean();  //清除内存
    ob_start();
    header("Content-Type: text/csv");
    header("Content-Disposition:filename=".$fileName.'.csv');
    // value列名
    $ks = array_column( $kv, 'v');

    $fp=fopen('php://output','w');
    fwrite( $fp,  chr(0xEF).chr(0xBB).chr(0xBF));
    fputcsv($fp, $ks);
    $index = 0;
    foreach ($data as &$item) {
        // 防止出现科学计数法
        $item['market_code'] = $item['market_code'] . "\t";
        // unix时间戳转日期
        $item['date'] = date( 'Y-m-d H:i:s', $item['date']);
        if($index==1000){ //每次写入1000条数据清除内存
            $index=0;
            ob_flush();//清除内存
            flush();
        }
        $index++;
        fputcsv($fp,$item);
    }

    ob_flush();
    flush();
    ob_end_clean();
    exit();
}


function echoJson($arr)
{
    echo json_encode($arr);
    exit;
}

导入

<?php
#!/bin/bash

/**
 * User: hzbskak
 * Date: 2019/12/31 - 11:11
 */

if( $_FILES)
{
    require_once "DB.php";
    require_once "PHPExcel/PHPExcel.php";
    $db = new DB();

    ini_set('memory_limit', '-1'); //设置程序运行的内存
    ini_set('max_execution_time',0); //设置程序的执行时间,0为无上限
    ini_set('display_errors', 1);
    error_reporting( E_ALL );

    if (!empty($_FILES['excel']['name'])) {
        $fileName = $_FILES['excel']['name'];    //得到文件全名
        $dotArray = explode('.', $fileName);    //把文件名安.区分,拆分成数组
        $type = end($dotArray);
//        if ($type != "xls" && $type != "xlsx") {
//            $ret['res'] = "0";
//            $ret['msg'] = "不是Excel文件,请重新上传!";
//            echoJson( $ret);
//        }

        //取数组最后一个元素,得到文件类型
        $uploaddir = date('Y-m-d') . '/';//设置文件保存目录 注意包含
        if (!file_exists($uploaddir)) {
            mkdir($uploaddir, 0777, true);
        }

        $path = $uploaddir . md5(uniqid(rand())) . '.' . $type; //产生随机文件名
        //$path = "images/".$fileName; //客户端上传的文件名;
        //下面必须是tmp_name 因为是从临时文件夹中移动
        move_uploaded_file($_FILES['excel']['tmp_name'], $path); //从服务器临时文件拷贝到相应的文件夹下

        $file_path = $path;
        if (!file_exists($path)) {
            $ret['res'] = "0";
            $ret['msg'] = "上传文件丢失!" . $_FILES['excel']['error'];
            echoJson( $ret);
        }

        //文件的扩展名
        $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
        // xls xlsx 上传
        if($ext != 'csv')
        {
            if ($ext == 'xlsx') {
                $objReader = \PHPExcel_IOFactory::createReader('Excel2007');
                $objPHPExcel = $objReader->load($file_path, 'utf-8');
            } elseif ($ext == 'xls') {
                $objReader = \PHPExcel_IOFactory::createReader('Excel5');
                $objPHPExcel = $objReader->load($file_path, 'utf-8');
            }
            $sheet = $objPHPExcel->getSheet(0);
            $highestRow = $sheet->getHighestRow(); // 取得总行数
            $highestColumn = $sheet->getHighestColumn(); // 取得总列数

            // 最大列数
            $sql2 = "select count(1) from information_schema.COLUMNS where table_name = 'ht_price'";
            $column_max = $db->getRow( $sql2)['count(1)'];
            // 表的字段key value
            $sql3 = "select column_name as k,column_comment as v from information_schema.columns where table_name='ht_price'";
            $kv = $db->getAll( $sql3);
            // 表的自增主键
            $sql4 = "SELECT column_name FROM INFORMATION_SCHEMA.`KEY_COLUMN_USAGE` WHERE table_name='ht_price' AND constraint_name='PRIMARY'";
            $primary = $db->getRow( $sql4)['column_name'];

            // 循环列 输出 a-z-zz
            $list = [];
            for ($i = 0; $i <= $column_max-1; $i++) {
                $y = ($i / 26);
//    echo $i,"=>";
                if ($y >= 1) {
                    $y = intval($y);
                    $a = chr($y+64);
                    $b = chr($i-$y*26 + 65);
                    $list [] = $a . $b;
                } else {
                    $c = chr($i+65);
                    $list [] = $c;
                }
//    echo "\r\n";
            }
            // 重组kv数组,追加a-z-zz
            // 并且把不需要写入的字段去掉,
            foreach ( $kv as $k => &$v)
            {
                // 删掉不需要添加的数
                if( $v['k'] == $primary || $v['k'] == 'add_time' || $v['k'] == 'edit_time')
                {
                    unset( $kv[$k]);
                }
                $v['col'] = $list[$k];
            }
            $keys = array_column( $kv, 'k');
            $keys_list = implode( ',', $keys);
            $ar = array();
            $i = 0;
            $importRows = 0;
            $data = [];
            // 插入语句
            $sql = "insert into price_copy (".$keys_list.") values ";
            for ($j = 2; $j <= $highestRow; $j++) {
                $importRows++;
                $sql .= "(";
                foreach ( $kv as $k => $v)
                {
                    // 去掉不需要上传的字段数据
                    if( $v['k'] != $primary && $v['k'] != 'add_time' && $v['k'] != 'edit_time')
                    {
                        // 日期转unix时间戳
                        if( $v['k'] == 'date')
                        {
                            $sql .= "'".strtotime( $objPHPExcel->getActiveSheet()->getCell($v['col'].$j)->getValue())."',";
                        }
                        else
                        {
                            $sql .= "'".$objPHPExcel->getActiveSheet()->getCell($v['col'].$j)->getValue()."',";
                        }
                    }
                }
                $sql = substr( $sql, 0, strlen($sql) - 1);
                $sql .= "),";
            }
            $sql = substr( $sql, 0, strlen($sql) - 1);
            $ret = $db->query( $sql);
            echoJson( $ret);
        }
        else
        {
            setlocale(LC_ALL,array('zh_CN.gbk','zh_CN.gb2312','zh_CN.gb18030'));
            $handle = fopen($file_path,'r');
            if(!$handle){
                echoJson('文件打开失败');
            }

            $i = 0;
            $j = 0;
            $result = [];
            // 第二行
            $offset = 1;
            // 读几行
            $line = 0;
            while($data = fgetcsv($handle)){
                //小于偏移量则不读取,但$i仍然需要自增
                // 从第二行开始读
                if($i < $offset && $offset){
                    $i++;
                    continue;
                }
                //大于读取行数则退出
                if($i > $line && $line){
                    break;
                }

                foreach ($data as $key => $value) {
                    $content = @iconv("gbk","utf-8//TRANSLIT//IGNORE",$value);//转化编码
                    $result[$j][] = $content;
                }
                $i++;
                $j++;
            }
            // 最大列数
            $sql2 = "select count(1) from information_schema.COLUMNS where table_name = 'ht_price'";
            $column_max = $db->getRow( $sql2)['count(1)'];
            // 表的字段key value
            $sql3 = "select column_name as k,column_comment as v from information_schema.columns where table_name='ht_price'";
            $kv = $db->getAll( $sql3);
            // 表的自增主键
            $sql4 = "SELECT column_name FROM INFORMATION_SCHEMA.`KEY_COLUMN_USAGE` WHERE table_name='ht_price' AND constraint_name='PRIMARY'";
            $primary = $db->getRow( $sql4)['column_name'];
            // 循环列 输出 a-z-zz
            $list = [];
            for ($i = 0; $i <= $column_max-1; $i++) {
                $y = ($i / 26);
            //    echo $i,"=>";
                if ($y >= 1) {
                    $y = intval($y);
                    $a = chr($y+64);
                    $b = chr($i-$y*26 + 65);
                    $list [] = $a . $b;
                } else {
                    $c = chr($i+65);
                    $list [] = $c;
                }
            //    echo "\r\n";
            }
            // 重组kv数组,追加a-z-zz
            // 并且把不需要写入的字段去掉,
            foreach ( $kv as $k => &$v)
            {
                // 删掉不需要添加的数
//                if( $v['k'] == $primary || $v['k'] == 'add_time' || $v['k'] == 'edit_time')
//                {
//                    unset( $kv[$k]);
//                }
                $v['col'] = $list[$k];
            }
            $keys = array_column( $kv, 'k');
            $keys_list = implode( ',', $keys);
            $size = 500; //批量插入500条数据
            $chunkData = array_chunk($result , $size);
            $count = count($chunkData);
//            echoJson( $kv); // 62
//            echoJson( $chunkData[0][0]);
            $len_result = count( $result);
            mysqli_query( $db->link, 'begin');
            try
            {
                for ($i=0; $i < $count; $i++) { // 100
                    $sql = "insert into price_copy (".$keys_list.") values ";
                    for( $j=0; $j < $size; $j++) // 500
                    {
                        $sql .= "(";
                        for ( $l=0;$l< $column_max;$l++) // 60
                        {
                            if( $kv[$l]['k'] == $primary)
                            {
                                $sql .= "null,";
                            }
                            elseif( $kv[$l]['k'] == 'date')
                            {
                                $sql .= "'".strtotime( $chunkData[$i][$j][$l])."',";
                            }
                            elseif( $kv[$l]['k'] == 'add_time')
                            {
                                $sql .= "'".date('Y-m-d H:i:s')."',";
                            }
                            elseif( $kv[$l]['k'] == 'edit_time')
                            {
                                $sql .= "'".date('Y-m-d H:i:s')."',";
                            }
                            else
                            {
                                $sql .= "'".@$chunkData[$i][$j][$l]."',";
                            }
                        }
                        $sql = substr( $sql, 0, strlen($sql) - 1);
                        $sql .= "),";
                    }
                    $sql = substr( $sql, 0, strlen($sql) - 1);
                    $ret = $db->query( $sql);
                }
                mysqli_query( $db->link, 'commit');
            }
            catch ( Exception $e)
            {
                echoJson( $e->getMessage());
                mysqli_query( $db->link, 'rollback');
            }
            mysqli_query( $db->link, 'end');

            fclose($handle);
            echoJson( $ret);
        }

    } else {
        $ret['res'] = "0";
        $ret['msg'] = "上传文件失败!";
        echoJson( $ret);
    }

}

function echoJson($arr)
{
    echo json_encode($arr);
    exit;
}
?>

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<form action="import.php" method="post" enctype="multipart/form-data">
    <input type="file" name="excel">
    <input type="submit">上传
</form>
</body>
</html>

数据表:
用到了两张数据表,只是表名不同
ht_price表和price_copy表
ht_price表中有110W+条数据,作用是用来生成excel文件的
price_copy表是空的,作用是用来通过excel导入数据库的

/*
 Navicat Premium Data Transfer

 Source Server         : 1
 Source Server Type    : MySQL
 Source Server Version : 50726
 Source Host           : localhost:3306
 Source Schema         : aaa

 Target Server Type    : MySQL
 Target Server Version : 50726
 File Encoding         : 65001

 Date: 02/01/2020 11:21:11
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for price_copy
-- ----------------------------
DROP TABLE IF EXISTS `price_copy`;
CREATE TABLE `price_copy`  (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `area_id` int(10) UNSIGNED NOT NULL COMMENT '地区id',
  `hotel_id` int(10) UNSIGNED NOT NULL COMMENT '酒店ID',
  `room_id` int(10) UNSIGNED NOT NULL COMMENT '房型ID',
  `market_code` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '11111111111111111' COMMENT '市场CODE(0不接受,1接受)1.中国,2.香港,3.澳门,4.台湾,5.日本,6.韩国,7.东南亚,8.俄罗斯,9.澳洲,10.非洲,11.中东,12.东欧,13.西欧,14.北欧,15.东美,16.南美,17.加拿大',
  `supp_id` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '供应商ID',
  `source` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '房价来源(0:自入房;1:EBK;2:api房;3:agt配额房;4:agt包房 5:自入EBK)',
  `is_priorty` enum('1','2') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '2' COMMENT '是否首选供应商(1:是;2:不是)',
  `state` tinyint(1) NOT NULL DEFAULT 1 COMMENT '状态(1:正常;2:关房)',
  `date` int(10) UNSIGNED NOT NULL COMMENT '日期',
  `price_type` tinyint(4) NOT NULL DEFAULT 1 COMMENT '价格类型(1:成本利润;2:售价回扣)',
  `price` double(10, 2) NOT NULL DEFAULT 0.00 COMMENT '售价',
  `prcurr_id` int(11) NOT NULL DEFAULT 1 COMMENT '售价币种',
  `prdexc` double(10, 5) NOT NULL DEFAULT 1.00000 COMMENT '售价当时的汇率',
  `cost` double(10, 2) NOT NULL DEFAULT 0.00 COMMENT '成本',
  `curr_id` int(11) NOT NULL COMMENT '成本币种id',
  `curr_sign` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '成本币种符号',
  `dexc` double(10, 5) NULL DEFAULT 1.00000 COMMENT '当时成本汇率',
  `profit` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0.00' COMMENT '利润',
  `pcurr_id` int(11) NOT NULL DEFAULT 1 COMMENT '利润币种',
  `pdexc` double(10, 5) NULL DEFAULT 1.00000 COMMENT '利润当时的汇率',
  `rebate` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0.00' COMMENT '回扣',
  `rcurr_id` int(11) NOT NULL DEFAULT 0 COMMENT '回扣币种',
  `rdexc` double(10, 5) NULL DEFAULT 1.00000 COMMENT '回扣当时的汇率',
  `b2c_price` double(10, 2) NOT NULL DEFAULT 0.00 COMMENT 'b2c 售价',
  `prb2c_curr_id` int(11) NOT NULL DEFAULT 0 COMMENT 'b2c售价币种ID',
  `prb2c_dexc` double(10, 5) NULL DEFAULT 1.00000 COMMENT 'b2c售价当时汇率',
  `b2c_profit` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0.00' COMMENT 'b2c 利润',
  `pb2c_curr_id` int(11) NOT NULL DEFAULT 0 COMMENT 'B2C利润币种ID',
  `pb2c_dexc` double(10, 5) NULL DEFAULT 1.00000 COMMENT 'b2c利润当时汇率',
  `told_cost_profit` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'no' COMMENT '定时处理房价前的成本或利润',
  `tack_type` tinyint(4) NOT NULL DEFAULT 1 COMMENT '定时处理房价的类型(1:利润 2:成本)',
  `addNum` tinyint(4) NOT NULL DEFAULT 0 COMMENT '总共加房数量(本字段只是用来统计总共加了多少房,实际房数量已经加到总房数里面)',
  `total` smallint(5) NOT NULL DEFAULT 0 COMMENT '总房数',
  `keep` smallint(5) NOT NULL DEFAULT 0 COMMENT '保留房数',
  `book` smallint(5) NOT NULL DEFAULT 0 COMMENT '已定数量',
  `no_quota_book` tinyint(4) NOT NULL DEFAULT 0 COMMENT '非配额房预定数量',
  `cancel` smallint(6) NOT NULL DEFAULT 0 COMMENT '取消数量',
  `remain` smallint(5) UNSIGNED NOT NULL DEFAULT 0 COMMENT '剩余数量',
  `minstay` tinyint(4) NOT NULL DEFAULT 0 COMMENT '连住多少天',
  `minstay_type` tinyint(1) NULL DEFAULT 3 COMMENT '连住类型(1:当天之前 2:当天之后 3:前后皆可)',
  `is_noprom` enum('1','2') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '1' COMMENT '是否优惠(1:是;2:否)',
  `cod` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT 'N天(固定日期)前不可定',
  `cot` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '17:00' COMMENT '多少点之前不可定',
  `cod_type` enum('1','2') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '1' COMMENT 'cod类型(1:多少天之前;2:固定日子)',
  `cancellation` int(11) NOT NULL DEFAULT 0 COMMENT '取消条款id',
  `is_cod_date` enum('1','2') CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '2' COMMENT '是否已经到了cod时间(1:是,2:否)',
  `no_show` int(11) NOT NULL DEFAULT 0 COMMENT 'noShow条款',
  `is_hold` enum('1','2') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '2' COMMENT '是否hold(1:是;2:否)',
  `is_robot` enum('1','2') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '2' COMMENT '自动房价(1:是;2:否)',
  `is_robotpt` enum('1','2') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '2' COMMENT '自动使用酒店利润(1:是;2:否)',
  `ro_show_type` enum('1','2','3') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单显示方式(1:成本;2:售价;3:售价加回扣)',
  `rpid_list` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0' COMMENT 'rateplan列表(多个rp用,隔开)',
  `in_note` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '对内备注',
  `out_note` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '对外备注',
  `ro_note` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'ro备注',
  `fax_note` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '列印备注',
  `ramarke` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '房型备注',
  `add_user_id` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '添加用户id',
  `add_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '添加时间',
  `edit_user_id` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '修改用户id',
  `edit_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '修改时间',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `room_id_2`(`room_id`, `market_code`, `supp_id`, `date`, `source`) USING BTREE,
  INDEX `hotel_id`(`hotel_id`) USING BTREE,
  INDEX `room_id`(`room_id`) USING BTREE,
  INDEX `date`(`date`) USING BTREE,
  INDEX `price`(`price`) USING BTREE,
  INDEX `b2c_price`(`b2c_price`) USING BTREE,
  INDEX `market_code`(`market_code`) USING BTREE,
  INDEX `is_priorty`(`is_priorty`, `price`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '酒店价格表' ROW_FORMAT = Dynamic;

更多推荐