디비 테이블 key 존재여부 확인후 쿼리 실행
본문
sql_query(" ALTER TABLE `g5_point` ADD KEY `index2` (`po_expire_date`); ", true);
위 쿼리를 실행해서 디비 g5_point 테이블에 해당 key 값이 존재하면 false 하고
없으면 실행하려고 합니다.
구글링해서 찾아서 만든 문법이 아래와 같은데, 정상적으로 작동하지 않아서 냑 님들의 조언 부탁합니다
if(!sql_query(" SELECT po_expire_date FROM Information_schema.table_constraints WHERE table_schema=디비테이블 AND table_name=`{$g5['point_table']}` ", false)) {
sql_query(" ALTER TABLE `{$g5['point_table']}` ADD KEY `index2` (`po_expire_date`); ", true);
}
또는
if(!sql_query(" SELECT po_expire_date FROM Information_schema.table_constraints WHERE table_name=`{$g5['point_table']}` ", false)) {
sql_query(" ALTER TABLE `{$g5['point_table']}` ADD KEY `index2` (`po_expire_date`); ", true);
}
답변 3
SHOW INDEX FROM g5_write_faq;
문장으로 해당 테이블에 걸린 인덱스를 확인해 보셔야 할 것 같습니다.
참고로 인덱스 명은 컬럼명에 관계 있게 명명하겠지만
이미 다른 인덱스가 두개 이상의 컬럼을 걸어서 사용할 경우도 있다는 부분을 참고하여 명명하셔야 할 것 같습니다.
아래의 에러는 글자 그대로 해당 테이블에 이미 wr_seo_title 라는 이름의 인덱스"명" (인덱스 컬럼이 아닌) 이 있다는 의미 입니다.
이미 있는 인덱스 "명"을 사용해서 인덱스를 생성하려 한 상황인듯 보입니다.
-----------
요녀석은 아래와 같이 에러를 토해내는군요 ㅠㅠ
ALTER TABLE `g5_write_faq` ADD KEY `wr_seo_title` (`wr_seo_title`)
1061 : Duplicate key name 'wr_seo_title'
<?
$sql = "SELECT po_expire_date FROM Information_schema.table_constraints WHERE table_schema=디비테이블 AND table_name=`{$g5['point_table']}`";
$result = sql_query($sql);
$row = sql_fetch_array($result);
if($row['po_expire_date'] == ""){
sql_query(" ALTER TABLE `{$g5['point_table']}` ADD KEY `index2` (`po_expire_date`); ");
}
?>
이렇게 하면 될 것 같은데 우선
SELECT po_expire_date FROM Information_schema.table_constraints WHERE table_schema=디비테이블 AND table_name=`{$g5['point_table']}` 이 문장이 정상적으로 실행되는지 먼저 mysql에서 확인 하는 것이 좋을 것 같습니다.
!-->
답변을 정리하는 동안 어찌 해결 하셨나 봅니다. ^^
제가 사용하던 소스 일부를 정리해서 올립니다.
Library File-------------
/*
Table 의 특정 컬럼에 걸린 인덱스의 여부를 확인함
다중 컬럼에 인덱스가 걸린 경우에도 True
Index Drop 시에는 컬럼별로 검사하지 않고 특정 이름만을 삭제 함
- DBA가 개별로 인덱스를 만들어 둘 수 있기 때문에 그냥 둠.
- 적정히 사용하지 않으면 인덱스를 프로그램에서 계속 만드는 위험이 있으므로 삭제 상태를 꼭 확인해 봐야 함.
*/
function hDB_findColIndex ($agTable, $agIndex)
{
$rtFind = false;
$lSql = "SHOW INDEX FROM `{$agTable}` WHERE Column_name = '{$agIndex}'";
$lRow = sql_fetch($lSql);
if ($lRow)
{
$rtFind = true;
}
return $rtFind;
}
//function hDB_createIndexCol ($agTable, $agIndexName, $agIndexs, ...)
function hDB_createIndexCol ()
{
$args = func_get_args();
$argc = func_num_args();
// 최소한 테이블명, 인덱스명, 인덱스용 컬럼 1개 이상 : 총 3개 이상
if ($argc < 3) return False;
$agTable = $args[0];
$agIndexName = $args[1];
// 세번째 이후 인덱스를 모두 카피
$agIndexs = array();
for ($i = 2; $i < $argc; $i++) {
$agIndexs[$i-2] = $args[$i];
}
$lSql = "";
$lSql .= "CREATE INDEX `{$agIndexName}` ON `{$agTable}` ( ";
$lSql .= "`" . implode( "`, `", $agIndexs ) . "`" ;
$lSql .= " ) USING BTREE";
// 에러 처리용 : sql_query($lSql, True);
// $rtVal == False 이면 mysql_error, mysqli_error 등으로 에러메세지 확인
$rtVal = False;
$rtVal = sql_query($lSql, False);
return $rtVal;
}
// $Colume이 걸린 인덱스를 찾아서 삭제 하지 않음 (수동으로 만든 경우가 있으므로)
// 지정한 이름 (본 루틴에서 생성한) 의 인덱스만 삭제 함
function hDB_dropIndexName ($agTable, $agIndexName)
{
$lSql = "";
$lSql .= "DROP INDEX `{$agIndexName}` ON `{$agTable}`";
// 에러 처리용 : sql_query($lSql, True);
// $rtVal == False 이면 mysql_error, mysqli_error 등으로 에러메세지 확인
$rtVal = False;
$rtVal = sql_query($lSql, False);
return $rtVal;
}
/* Test SQL
SHOW INDEX FROM g5_write_f_plaza01
SHOW INDEX FROM g5_write_f_plaza01 WHERE Column_name == 'wr_last'
CREATE INDEX 인덱스이름 ON 테이블이름 (필드이름1, 필드이름2, ...)
CREATE INDEX `hI_g5_write_f_plaza01_wr_last` ON `g5_write_f_plaza01` (`wr_last`) USING BTREE;
DROP INDEX `hI_g5_write_f_plaza01_wr_last` ON `g5_write_f_plaza01`;
*/
=================================================
실제 사용 예
-------------
if ($lBoset['db_index_gen'] === 'T') {
//---------
// 최근일로 볼 때가 많은데 이 경우 인덱스가 없어서 DB 속도 저하를 초래 함.
// 자동으로 인덱스를 생성
$lIndexCol = 'wr_last';
// 최근 일로 볼때 인덱스 자동 생성 및 보지 않을때 인덱스 삭제
$lWriteTable = $g5['write_prefix'] . $bo_table; // 게시판 테이블 전체이름
$lWriteTable_IndexName = "hI_{$lWriteTable}_{$lIndexCol}";
$flagWrIndex = False;
$flagWrIndex = hDB_findColIndex ($lWriteTable, $lIndexCol);
if(stripos($bo_sort_field, $lIndexCol) !== false) {
// wr_last 로 세팅 , 인덱스가 없음 = 생성
if ($flagWrIndex != True) {
if ( hDB_createIndexCol ($lWriteTable, $lWriteTable_IndexName, $lIndexCol) != True) {
// Error
}
}
} else {
// wr_last 로 비세팅 , 인덱스가 있음 = 삭제
if ($flagWrIndex == True) {
if (hDB_dropIndexName ($lWriteTable, $lWriteTable_IndexName) != True) {
// Error
}
}
}
}
=================================================
요청 내용에 적용한 예 (테스트는 되어 있지 않습니다.)
-------------
$lWriteTable = "g5_point"; // 인덱스 테이블 : g5_point
$lIndexCol = "po_expire_date"; // 인덱스 필드 : po_expire_date
$lIndexName = "index2"; //인덱스 키 명 : index2
// Test
$flagWrIndex = False;
$flagWrIndex = hDB_findColIndex ($lWriteTable, $lIndexCol);
if (! $flagWrIndex) echo "{$lWriteTable} {$lIndexCol} 컬럼의 인덱스 값이 존재 하지 않습니다.";
// 생성은 인덱스 컬럼으로 생성
if ( hDB_createIndexCol ($lWriteTable, $lIndexName, $lIndexCol) != True) {
// Error
}
// 삭제는 인덱스 "명" 으로 삭제
if (hDB_dropIndexName ($lWriteTable, $lIndexName) != True) {
// Error
}