หลายครั้งที่อัพเดตเวอร์ชั่น มักจะลืมแก้ไขบางฟิลด์
หรือหากเวอร์ชั่นใหม่ ต้องแก้ฟิลด์จำนวนมาก จะเสียเวลามานั่งไล่แก้โครงสร้างตามที่บันทึกไว้
ครั้นจะใช้โครงสร้างใหม่ แล้ว dump ข้อมูลเดิมใส่ ก็ทำได้ยาก เพราะทำผ่านเน็ตจะช้ามากๆ
กรณีข้อมูลเป็น GB จะนั่งรอกันเป็นวัน ^^"
ด้วยเหตุนี้เลยนั่งเขียนสคริปต์ PHP ที่ใช้อัพเดตโครงสร้างฐานข้อมูลขึ้นมาใช้งาน
ไหนๆ ก็ต้องนั่งรอ dump ข้อมูลใหม่ หรือนั่งไล่แก้ทีละฟิลด์อยู่แล้ว
ลองนำไปประยุกต์ใช้ดูนะครับ
Download
ตัวอย่างการใช้งาน
<?php /*------------------------------------------------------------------------------ ** File : check_database.php ** Description : ตรวจสอบฐานข้อมูล เพื่อเปรียบเทียบฟิลด์ที่ต่างกันของฐานข้อมูลที่ใช้จริง กับโครงสร้างฐานข้อมูลใหม่ (ฐานข้อมูลที่พัฒนาต่อเนื่อง) ** Author : Songchai Saetern ** Email: sunzandesign@gmail.com ** Homepage : www.sunzan-design.com ** Modify : 2013-04-27 ** ** Rev History **------------------------------------------------------------------------------ ** 2011-08-22 สร้างครั้งแรก ** 2013-04-27 อัพเดตหน้าล็อกอิน ** */ session_start(); header("Content-type: text/html; charset=utf-8"); require_once 'function/general.php'; $pageview = true;//แสดงผลแบบแบ่งหน้า $selfpage = $_SERVER['PHP_SELF']; //แหล่งข้อมูล $num_check = 3;//จำนวนฐานข้อมูลที่จะเช็ก $title = 'ตรวจสอบฐานข้อมูลเปรียบเทียบข้อแตกต่าง ก่อนการอัพเดตเวอร์ชั่นของโปรแกรม'; //COMMENT NOT DISPLAY ON INDEX PAGE $howto = <<<HOWTO 1. เลือกฐานข้อมูลที่ต้องการเปรียบเทียบโครงสร้าง ด้านซ้ายคือโครงสร้างฐานข้อมูลเวอร์ชั่นใหม่ ด้านขวาให้เลือกฐานข้อมูลจริงที่ใช้อยู่ปัจจุบัน 2. เมื่อคลิกปุ่ม "Start" จะทำการดึงข้อมูลตารางทั้งหมดจากฐานข้อมูลที่เลือกมาเปรียบเทียบกัน และแสดงให้เห็นว่ามีตารางที่ไม่ตรงกันกี่ตัว 3. ใต้ชื่อตารางจะมีชื่อฟิลด์ที่ไม่ตรงกันปรากฏให้เห็น ซึ่งจะแสดงเฉพาะฟิลด์ที่มียังไม่มีในเทเบิลเดิม หรือฟิลด์ที่ Type หรือ Comment ไม่ตรงกันเท่านั้น 4. เมื่อคลิก "UPDATE STRUCTURE" สคริปต์จะปรับโครงสร้างฐานข้อมูลที่ใช้จริง ให้เหมือนโครงสร้างฐานข้อมูลตัวใหม่ (สร้างตาราง และเพิ่มฟิลด์ที่ไม่ครบเท่านั้น ที่เหลือย้อนกลับไปเช็กอีกรอบจะเหลือคอมเมนต์ หรือชนิดข้อมูลที่ต้องปรับเพิ่มเอง) 5. คลิก "ย้อนกลับ" ไปตรวจสอบอีกที เพื่อดูรายการที่ยังไม่ได้อัพเดต ให้อัพเดตเอง HOWTO; $howto = nl2br(str_replace("\t"," ",$howto)); //MAIN TAG echo <<<HTML <html> <head> <title>$title</title> <script src="js/jquery-1.4.2.min.js" type="text/javascript"></script> <link rel="stylesheet" href="css/style.css" type="text/css" /> <script type="text/javascript"> function add_option(){ var option = $('#select_option').val(); var no = $('select[name="db_source[]"]').length + 1; var row = "<tr bgcolor='white'><td>"+no+"</td>"; row += "<td><select name='db_source[]'><option value=''>- เลือกฐานข้อมูล -</option>"+ option +"</select></td>"; row += "<td><select name='db_target[]'><option value=''>- เลือกฐานข้อมูล -</option>"+ option +"</select></td></tr>"; $("#tb_option").append(row); } </script> </head> <body> <div style="width: 1024px;margin: auto;"> <h3 align="center" style="text-decoration:underline">$title</h3> <div style="color:blue"><b>:: การทำงานของสคริปต์ ::</b> <div style="color:#000066;border:1px dashed #0033CC;padding: 5px;background:#eeeeee">$howto</div></div><br> <div align="center"> <a href="$selfpage" style="color:green;border:1px solid brown;background:orange;text-decoration:none;padding:5px"><<< หน้าหลัก >>></a> <a href="$selfpage?logout" style="color:green;border:1px solid brown;background:orange;text-decoration:none;padding:5px">Log out</a> </div><br> <div id="content"> HTML; //--end MAIN $warning = '<h4 style="color:red" align="center">* กรุณาแบ็กอัพข้อมูล และทดสอบกับฐานข้อมูลทดสอบก่อนนำไปใช้จริง เพื่อป้องกันข้อผิดพลาด <br/>(คุณสามารถ แก้ไขโครงสร้างด้วยตนเอง ตามข้อมูลในหน้าเปรียบเทียบโครงสร้าง</h4>'; if(isset($_GET['logout'])){ $_SESSION['user']=''; } if($_SESSION['user']=='' && $_POST['user']==''){ $user = $_SESSION['user'];if($user==''){$user='root';} $pass = $_SESSION['pass'];if($pass==''){$pass='123456';} echo '<div align="center"> <form action="'.$_SERVER['PHP_SELF'].'" method="post"> <font color="green"><u>ตั้งค่าฐานข้อมูลที่ต้องการใช้งาน</u></font><br> host : <input type="text" name="host" value="localhost"><br> User : <input type="text" name="user" value="'.$user.'"><br> Pass : <input type="password" name="pass" value="'.$pass.'"><br> <input type="submit" name="submit" value="เริ่มใช้งาน"><br> </form> </div>'; echo $warning; exit(); }else if($_POST['user']){ $_SESSION['host'] =$_POST['host']; $_SESSION['user'] = $_POST['user']; $_SESSION['pass'] = $_POST['pass']; } define("DBHOST", $_SESSION['host']); define("DBUSER", $_SESSION['user']); define("DBPASS", $_SESSION['pass']); $connect = @mysql_connect(DBHOST, DBUSER, DBPASS) or show_error( __FILE__,__LINE__, 'Connection error.' ); mysql_query("SET NAMES UTF8"); $operator = $_GET['operator']; if($operator=='')//default { //ลิสต์ฐานข้อมูล $dbSQL = "SHOW DATABASES"; $dbResult = mysql_query($dbSQL) or show_error(__FILE__, __LINE__, $dbSQL); while($dbRec = mysql_fetch_assoc($dbResult)){ if(++$n % 2){$bg = '#fff';}else{$bg='#f7f7f7';} $dbOption .= "<option value='$dbRec[Database]' style='background:$bg;'>$dbRec[Database]</option>"; } $database = '<option value="">- เลือกฐานข้อมูล -</option>'.$dbOption; mysql_free_result($dbResult); unset($dbRec); echo '<div style="width:50%; margin: auto"><b>New_structure</b> = โครงสร้างฐานข้อมูลใหม่ <br/><b>Old_structure</b> = ฐานข้อมูลที่ใช้จริง (ฐานข้อมูลที่ต้องการอัพเดต)</div>'; echo '<form action="'.$selfpage.'?operator=start_check" method="POST"> <table align="center" width="50%"> <tr> <td> <table id="tb_option" width="100%" align="center" class="" border="0" cellpadding="5" cellspacing="1" bgcolor="#cccccc">'; $th_option = array('fieldname'=>'yes','tag'=>'th','custom'=>array('bgcolor'=>'saddlebrown','style'=>'color:white')); $tr_option = array('attr'=>array('bgcolor'=>'#ffffff')); $td_option = array( 'New_structure'=>array('style'=>''), 'Old_structure'=>array('style'=>'') ); $dropdown = array(); for($i=0;$i<$num_check;$i++)//สร้างตัวเลือกเปรียบเทียบตามจำนวนที่ระบุ { ++$a['No']; $dropdown['New_structure'] = '<select name="db_source[]"><option value="">- เลือกฐานข้อมูล -</option>'.$dbOption.'</select>'; $dropdown['Old_structure'] = '<select name="db_target[]"><option value="">- เลือกฐานข้อมูล -</option>'.$dbOption.'</select>'; $arr = array_merge($a, $dropdown);//ใส่คอลัมน์ NO ไว้ด้านหน้า if($a['No']==1){ echo gen_tr($arr,$th_option,$td_option); } echo gen_tr($arr,$tr_option); } echo '</table> </td> </tr> <tr> <td align="center"> <textarea id="select_option" style="display:none">'.$dbOption.'</textarea> <input type="button" value=" + เพิ่มตัวเลือก " style="color:orangered;font-weight:bold;height:40px;font-size:15px" onclick="add_option();"> <input type="submit" value=" Start Check " style="color:green;font-weight:bold;height:40px;font-size:15px"/> </td></tr> </table> </form> '; } else if($operator=='start_check') //เริ่มการตรวจสอบ { $source = $_POST['db_source']; $target = $_POST['db_target']; if(empty($source[0]) || empty($target[0])){echo '<h1 align="center">ฐานข้อมูลที่เลือกไม่ครบ</h1>';exit();} //ไม่มีผลกับอัพดับของ dropdown $all_db = array_merge($source,$target);//มีปัญหาเรื่อง array ทับกัน $all_db = array_unique($all_db);//ถ้าเป็นฐานข้อมูลเดียวกันก็ได้เทเบิลตรงกัน sort($all_db);//เรียง key ใหม่ //TEST /* echo '<br>SOURCE :: '; print_r($source); echo '<br><br>TARGET :: '; print_r($target); echo '<br><br>MERGE :: '; print_r($all_db); echo '<br><br>'; */ //โครงสร้างใหม่ $arr = array(); $count = count($all_db); for($i=0;$i<$count;$i++){ $db = $all_db[$i]; if($db){ $sql = "SHOW TABLES FROM $db"; $result = mysql_query($sql) or show_error(__FILE__, __LINE__, $sql); while($rs = mysql_fetch_array($result)){ $table = $rs[0]; $arr[$db]['table'][$table] = $table; $sql = "SHOW FULL COLUMNS FROM $db.$table"; $res = mysql_query($sql) or show_error(__FILE__, __LINE__, $sql); while($field = mysql_fetch_assoc($res)){ $arr[$db.$table]['field'][$field['Field']] = $field; } } } }//for $no=0; $data = array(); echo '<br><form action="'.$selfpage.'?operator=start_update_structure" onsubmit="if(confirm(\' ยืนยันการปรับปรุงโครงสร้างฐานข้อมูล?\n\n หากทดสอบกับฐานข้อมูลทดสอบจนแน่ใจ คลิกตกลงเพื่อ ยืนยัน \n หากยังไม่ได้ทดสอบการทำงาน และไม่แน่ใจ คลิก ยกเลิก \n\n (คุณสามารถ แก้ไขโครงสร้างด้วยตนเอง ตามข้อมูลที่ปรากฏด้านบน )\')==true){return true;}else{return false;}" method="POST">'; echo '<font color="red" style="font-size:15px;"><b>* การอัพเดต จะใช้ข้อมูลจาก <b style="color:blue">ด้านซ้าย</b> >> <b style="color:magenta">ด้านขวา</b> ตรวจสอบให้แน่ใจว่าตารางด้านซ้ายและขวา เป็นตารางที่เชื่อมโยงกัน</b></font>'; echo '<table id="" class="" border="0" cellpadding="5" cellspacing="1" bgcolor="#cccccc">'; echo '<tr bgcolor="saddlebrown"> <th align="right">DB</th> <th align="right">TB</th> <th><span>โครงสร้างฐานข้อมูลใหม่</span></th> <th><span>ฐานข้อมูลเดิม(ที่ใช้อยู่ปัจจุบัน)</span></th> <th></th> </tr>'; foreach ($source as $key=>$db1){ $no++; $db2 = $target[$key]; if($db1){ $tb_db1 = $arr[$db1]['table']; $tb_db2 = $arr[$db2]['table']; //echo '<br>1=>';print_r($arr[$db1]['table']);echo '<br>'; //echo '<br>2=>';print_r($arr[$db2]['table']);echo '<br>'; $arrr = array_merge($tb_db1,$tb_db2); $s_no = 0; echo '<tr bgcolor="#cccccc"> <th align="">'.$no.'</th> <th align=""></th> <th><span style="color:blue;font-size:16px">'.$db1.'</span></th> <th><span style="color:blue;font-size:16px">'.$db2.'</span></th> <th>หมายเหตุ</th> </tr>'; $db_update = ''; $field_data = ''; $tb1_field = ''; foreach($arrr as $tb=>$tb1_name){ $s_no++; $sub_no = $no.'.'.$s_no; $tb1_name = $arr[$db1]['table'][$tb]; $tb2_name = $arr[$db2]['table'][$tb]; $style1 =$style2 = 'color:green;font-weight:bold;'; $check_field1 = $check_field2 = ''; $sign = ''; $remark = '<br>'; $tb_remark = '<br>'; $db_update = ''; $field_data = ''; if($tb2_name != $tb1_name){ if($tb1_name==''){ $style1 = "color:#556B2F;"; $style2 = 'color:blue;'; $tb1_name = $tb2_name; $tb_remark = '<div style="color:blue" style="line-height:20px;"> * แสดงให้เห็นเท่านั้น ไม่จำเป็นต้องอัพให้เหมือนเวอร์ชั่นที่ใช้อยู่ </div>'; } if($tb2_name==''){ $style1 = 'color:#333333;'; $style2 = "color:red;"; $tb2_name = $tb1_name; //จะสร้างตารางเฉพาะโครงสร้างปัจจุบันเท่านั้น $db_update = '<input type="text" name="new_table['.$db1.'.'.$tb1_name.']" value="'.$db2.'.'.$tb2_name.'" style="display:none">'; $tb_remark = '<div style="color:red" style="line-height:20px;">* สร้างตารางเพิ่ม</div>'; } }else{//ถ้าตรงกัน ให้ตรวจสอบฟิลด์ $remark = ''; $tb1_field = ''; $tb1_field = $arr[$db1.$tb1_name]['field']; $tb2_field = $arr[$db2.$tb2_name]['field']; $count_field = ''; $field_c1 = count($tb1_field); $field_c2 = count($tb2_field); if($field_c1 != $field_c2){ $style1 = 'color:orangered;font-weight:bold;'; $style2 = 'color:orangered;font-weight:bold;'; $count_field = '<div style="color:blue" style="line-height:20px;">!!จำนวนฟิลด์ไม่เท่ากัน อาจทำให้เทเบิล LOG ที่เชื่อมโยงกัน เกิดปัญหาได้</div>'; $check_field1 .= '<div style="line-height:20px;"> จำนวนฟิลด์ <font color="magenta">'.$field_c1.'</font></div>'; $check_field2 .= '<div style="line-height:20px;"> จำนวนฟิลด์ <font color="magenta">'.$field_c2.'</font></div>'; } foreach ($tb1_field as $name=>$dArr){ $no_math=false; $field1 = $dArr['Field']; $field2 = $arr[$db2.$tb2_name]['field'][$name]['Field']; $f2 = $arr[$db2.$tb2_name]['field'][$name]; $remark1 = $remark2 = ''; if($field1!=$field2){ $no_math = true; $color = "red"; if($field1==''){ $field1 = $field2; }else if($field2==''){ $field2 = $field1; $field_data .= '<input type="text" name="new_field['.$db1.'.'.$tb1_name.'@'.$field1.']" value="'.$db2.'.'.$tb2_name.'" style="display:none">'; } $ch1=$ch2= '->NEW!! '; $remark .= '<div style="color:blue;line-height:20px;">** เพิ่มฟิลด์</div>'; }else{ $ch1=$ch2=''; $color = "blue"; if($dArr['Type'] != $f2['Type']){ $ch1 = $dArr['Type']; $ch2 = $f2['Type']; $remark1 = '*** ชนิดของฟิลด์ไม่ตรงกัน'; } if($dArr['Comment'] != $f2['Comment'] && $dArr['Comment']!=''){ $ch1 .= '[Comment='.$dArr['Comment'].']'; $ch2 .= '[Comment='.$f2['Comment'].']'; $remark2 = '**** Comment ฟิลด์ไม่ตรงกัน '; } if($ch1 || $ch2 ){ $no_math = true; $remark .= '<div style="color:blue" style="line-height:20px;">'.$remark1.$remark2.'</div>'; $field_data .= '<input type="text" name="change_field['.$db1.'.'.$tb1_name.'@'.$field1.']" value="'.$db2.'.'.$tb2_name.'" style="display:none">'; } } if($no_math){ $check_field1 .= $sign.'<div style="line-height:20px;">'.$field1.' <font color="magenta">'.$ch1.'</font></div>'; $check_field2 .= $sign.'<div style="line-height:20px;">'.$field2.' <font color="magenta">'.$ch2.'</font></div>'; //$sign = ', '; } //$field_data = json_encode($dArr); //echo "<br>$tb1_name :::> FIELD :: $field1==$field2"; //echo '<br>';print_r($dArr); } if($check_field1){ $check_field1 = '<span style="color:'.$color.'"><b>* '.$check_field1.'</b></span>'; } if($check_field2){ $check_field2 = '<span style="color:'.$color.'"><b>* '.$check_field2.'</b></span>'; } }//else if $data['New_structure'] = $db1.'.'.$tb1_name; $data['Old_structure'] = $db2.'.'.$tb2_name; echo '<tr bgcolor="white"> <td valign="top">'.$db_update.$field_data.'</td> <td valign="top">'.$sub_no.'</td> <td valign="top"><span style="'.$style1.'">'.$db1.'.'.$tb1_name.'</span>'.$check_field1.'</td> <td valign="top"><span style="'.$style2.'">'.$db2.'.'.$tb2_name.'</span>'.$check_field2.'</td> <td>'.$tb_remark.$remark.$count_field.'</td> </tr>'; }//foreach echo '<tr><td colspan="5"></td></tr>'; }//if not null }//foreach echo '<tr bgcolor="white"><td colspan="5" align="center"> <input type="submit" value=" UPDATE STRUCTURE (สร้างตาราง เพิ่มฟิลด์ที่ไม่ครบ และอัพเดตฟิลด์ให้ตรงกัน ) " style="color:orangered;font-weight:bold;height:40px;font-size:15px"/> <br> <br> <font color="#996C05" style="font-size:15px;"><b>* การอัพเดต จะใช้ข้อมูลจาก <b style="color:blue">ด้านซ้าย</b> >> <b style="color:magenta">ด้านขวา</b> ตรวจสอบให้แน่ใจว่าตารางด้านซ้ายและขวา เป็นตารางที่เชื่อมโยงกัน</b></font> </td></tr>'; echo '</table></form>'; } elseif ($operator=='start_update_structure') { echo '<a href="javascript:void(0);" onclick="javascript:history.back();"> << ย้อนกลับ </a>'; mysql_query('SET NAMES UTF8'); $create = 0; echo '<br><b> สร้างตารางใหม่ :: </b>'; if($_POST['new_table']){ foreach ($_POST['new_table'] as $tb1=>$tb2) { $create++; $sql = "CREATE TABLE $tb2 LIKE $tb1 "; mysql_query($sql) or show_error(__FILE__, __LINE__, $sql); echo "<div style='color:green'>$create. $sql</div>"; } } echo "<div style='color:green'>รวมทั้งสิ้น <font color='blue'>$create</font> รายการ</div>"; $add=0; echo '<br><b> เพิ่มฟิลด์ใหม่ :: </b>'; if($_POST['new_field']){ foreach ($_POST['new_field'] as $db_field=>$tb2) { $add++; $ex = explode('@', $db_field); $source_table = $ex[0];//ตารางต้นทาง $field_name = $ex[1]; //ฟิลด์ต้นทาง $sql = "SHOW FULL COLUMNS FROM $source_table"; $res = mysql_query($sql) or show_error(__FILE__, __LINE__, $sql); $n=0; $arr=array(); while($field = mysql_fetch_assoc($res)){ $n++; $new[$n] = $field['Field']; if($field['Field']==$field_name){ $arr = $field; break; } } $after = $new[$n-1]; $table = $tb2;//เทเบิลปลายทาง //ถ้าเป็น NO แสดงว่าไม่เซ็ต if($arr['Null']=='NO'){$null = 'NOT NULL';}else{$null = 'NULL';} //ถ้ามีฟิลด์ก่อนหน้าเป็น AFTER แต่ถ้าไม่มี แสดงว่าเพิ่มใหม่ที่ฟิลด์แรกเลย if($after){$after = " AFTER $after ";}else{$after = "FIRST";} $sql = "ALTER TABLE $table ADD `$arr[Field]` $arr[Type] $null COMMENT '$arr[Comment]' $after "; mysql_query($sql) or show_error(__FILE__, __LINE__, $sql); echo "<div style='color:green'>$add. $sql</div>"; }//foreach }//if echo "<div style='color:green'>รวมเพิ่มฟิลด์ใหม่ทั้งสิ้น <font color='blue'>$add</font> รายการ</div>"; $change = 0; echo '<br><b> ฟิลด์ที่มีการเปลี่ยนแปลง :: </b>'; if($_POST['change_field']){ foreach ($_POST['change_field'] as $db_field=>$tb2) { $change++; $ex = explode('@', $db_field); $source_table = $ex[0];//ตารางต้นทาง $field_name = $ex[1]; //ฟิลด์ต้นทาง $sql = "SHOW FULL COLUMNS FROM $source_table LIKE '$field_name'"; mysql_query('SET NAMES UTF8'); $res = mysql_query($sql) or show_error(__FILE__, __LINE__, $sql); $field = mysql_fetch_assoc($res); if($field['Null']=='NO'){$null = 'NOT NULL';}else{$null = 'NULL';} $table = $tb2;//เทเบิลปลายทาง $sql = "ALTER TABLE $table CHANGE `$field[Field]` `$field[Field]` $field[Type] $null COMMENT '$field[Comment]'"; mysql_query('SET NAMES UTF8'); mysql_query($sql) or show_error(__FILE__, __LINE__, $sql); echo "<div style='color:green'>$change. $sql</div>"; }//forech }//if echo "<div style='color:green'>รวมทั้งสิ้น <font color='blue'>$change</font> รายการ</div>"; }//operator CloseDB(); echo '</div>'; echo $warning; //END ?>
ความคิดเห็น
แสดงความคิดเห็น