MySQL에서 CUBRID의 변환을 생각하는 많은 개발자들이 궁금해 하는 MySQL의 BLOB타입 데이터를 CUBRID로 이전하는 방법에 대해 기술한다. 본FAQ는 http://blog.naver.com/windyhan/110052262344 블로그를 참조하여 기술하였음을 밝힌다.

이미 문서를 통하여 MySQL to CUBRID의 Data Type변경에 대해 소개하고 있다. 대부분의 경우 대응되는 Type으로의 스키마 변경으로 해결되나 Blob의 경우 약간의 작업이 필요하게 된다. 이 약간의 작업에 대해서 설명하도록 한다.

MySQL에서 사용하는 Blob타입 4종류와 각각의 허용 범위는 아래와 같다.


TinyBlob - maximum length of 255 characters.
Blob - maximum length of 65535 characters.
MediumBlob - maximum length of 16777215 characters.
LongBlob - maximum length of 4294967295 characters.

 


CUBRID에서 대응하는 Type인 Bit Varying의 범위는 아래와 같다.


Bit Varying(n) - n에 대한 값이 생략되면, 디폴트 길이 1,073,741,823이 가정된다. 이는 MySQL의 LongBlob을 제외한 Blob타입에 대응될 수 있다.
* MySQL의 LongBlob에 대해서는 CUBRID는 GLO라는 타입으로 대응이 가능하나 이는 다른 Tip으로 정리한다.
 
MySQL의 Blob을 CUBRID로 변환하는 과정을 아래의 예를 통하여 확인하고자 한다. 아래의 예시는 test_tbl이라는 테이블로 간단한 이미지를 저장한 저장해 놓은 테이블이다. 이미지의 사이즈는 30~60만 byte정도로 MySQL의 MediumBlob에 해당한다.


mysql> describe test_tbl;

+-----------+--------------+------+-----+---------+----------------+

| Field     | Type         | Null | Key | Default | Extra          |

+-----------+--------------+------+-----+---------+----------------+

| id        | int(11)      | NO   | PRI | NULL    | auto_increment |

| file_name | varchar(255) | YES  |     | NULL    |                |

| file_data | mediumblob   | YES  |     | NULL    |                |

+-----------+--------------+------+-----+---------+----------------+

3 rows in set (0.00 sec)

 

데이터는 아래와 같이 들어있다.

 


데이터를 추출하기 위해 JDBC를 이용한다. file_data칼럼에 있는 이미지를 추출하는 java코드는 아래와 같다.

public void getBlobDataFromMySQL(){

          Connection conn=null;

          Statement stmt=null;

          ResultSet rs=null;

          String file_path = "pic";

 

          try{

               File curr = new File("./" + file_path);

               if( !curr.exists() ){

                  curr.mkdir();

               }

               Class.forName("com.mysql.jdbc.Driver");  //드라이버 로드

               conn = DriverManager.getConnection   // Connection객체 가져오기

                   ("jdbc:mysql://localhost/testdb?user=root&password=root");

 

               String sql = "select id, file_name, file_data from test_tbl";

               stmt = conn.createStatement();

               rs = stmt.executeQuery(sql);

               while(rs.next()){

                 int id = rs.getInt("id");

                 String file_name = rs.getString("file_name");

                 InputStream is = rs.getBinaryStream("file_data");

                 FileOutputStream fos = new FileOutputStream("./pic/" + file_name);

                 byte[] buff = new byte[2048000];

                 int len;

                 while ( (len = is.read(buff)) > 0 )

                      fos.write( buff, 0, len);

                 fos.close();

                 is.close();

               }

               rs.close();

               stmt.close();

               conn.close();

          }catch(Exception e){

              e.printStackTrace();

          }

    }

 

위의 코드를 간략히 설명하면 test_tbl 테이블의 이미지를 select 하여 pic이라는 디렉토리에 file_name 을 이름으로 하는 파일들을 생성한다. 이 파일들을 읽어서 CUBRID에 삽입할 것이다.

 

이제 추출한 데이터를 넣을 CUBRID테이블을 생성한다. CUBRID의 테이블 생성 예는 아래와 같다.


csql> create table test_tbl ( id integer auto_increment primary key not null, file_name varchar(255), file_data bit varying);

csql> ;x

 

Current transaction has been committed.

 

1 command(s) successfully processed.

csql> ;sc test_tbl

 

=== <Help: Schema of a Class> ===

 

 <Class Name>

 

     test_tbl

 

 <Attributes>

 

     id                   INTEGER AUTO_INCREMENT  NOT NULL

     file_name            CHARACTER VARYING(255)

     file_data            BIT VARYING(1073741823)

 

 <Constraints>

 

     PRIMARY KEY pk_test_tbl_id ON test_tbl (id)

 

Current transaction has been committed.

 


MySQL의 BLOB 타입에서 빼낸 이미지 파일들을 CUBRID의 test_tbl의 bit varying 타입인 file_data 컬럼에 넣는다.

public void setBlobDataToCUBRID_bit(){

           File curr = new File("./pic");                        

           String[] filelist = curr.list(new BlobFileNameFilter());              -------------------------  1

           cubrid.jdbc.driver.CUBRIDConnection conn=null;

           cubrid.jdbc.driver.CUBRIDPreparedStatement stmt=null;

 

           try{

               Class.forName("cubrid.jdbc.driver.CUBRIDDriver");

               conn = (cubrid.jdbc.driver.CUBRIDConnection)DriverManager.getConnection                   

("jdbc:cubrid:127.0.0.1:33004:testdb1:dba::");          ------------------------- 2

 

               for( int i = 0; i < filelist.length ; i++){

                  String filename  = filelist[i];

                  File file = new File("./pic/" + filename);

                  FileInputStream in = new FileInputStream(file);           ------------------------- 3

 

                  String sql = "insert into test_tbl(file_name, file_data) values ( ?,?)";

                  stmt=(cubrid.jdbc.driver.CUBRIDPreparedStatement)conn.prepareStatement(sql);

                  stmt.setString(1,filename);

                  stmt.setBinaryStream(2,in,(int)file.length());               ------------------------- 4

                  stmt.executeUpdate();                                 ------------------------- 5

                  stmt.close();       

                  in.close();

               }

               conn.commit();

               conn.close();

 

         }catch(Exception e){

            e.printStackTrace();

         }

}

 각각의 설명은 아래와 같다.
1. Bit varying 컬럼에 저장할 파일들의 리스트를 생성한다.

2. CUBRID DB의 Connection 을 가져온다.

3. 입력할 FILE의 InputStream 을 생성한다.

4. Bit Varying 타입인 file_data 컬럼에 setBinaryStream() 함수를 이용해 파라미터 바인딩을 한다.

5. insert 문을 실행한다.

 

위의 java파일을 컴파일 후 실행하면 test_tbl 테이블에 데이터가 삽입된다. 데이터가 제대로 들어갔는지 확인한다.


csql> select file_name, bit_length(file_data)/8 from test_tbl

csql> ;x

 

=== <Result of SELECT Command in Line 1> ===

 

  file_name              bit_length(file_data)/8

================================================

  'DSC_0193_007.JPG'                      329216

  'DSC_0199_010.JPG'                      266272

  'DSC_0202_011.JPG'                      329382

  'DSC_0190_004.JPG'                      419584

  'DSC_0206_013.JPG'                      319426

  'DSC_0187_002.JPG'                      321152

  'DSC_0197_008.JPG'                      273747

  'DSC_0191_005.JPG'                      391503

  'DSC_0192_006.JPG'                      291880

  'DSC_0198_009.JPG'                      169344

  'DSC_0183_001.JPG'                      216492

  'DSC_0208_014.JPG'                      345924

  'DSC_0203_012.JPG'                      333349

  'DSC_0189_003.JPG'                      262936

 

14 rows selected.

데이터가 잘 들어가 있는지 확인해 보았다. 질의에서 Bit_length(file_data)/8 을 한 이유는 저장된 데이터의 byte 수를 알기 위해 한 것이다. 특별히 다른 점은 없고, JDBC 표준 인터페이스를 사용하여 저장을 한 것이다.

 

CUBRID에 저장된 데이터를 추출하는 방법은 위의 MySQL에서 추출한 방법과 거의 같다 아래의 두가지 부분만 변경해 주면 된다.

 1. 함수 이름을 변경한다.

 2. MySQL Connection 연결하는 방법을 CUBRID용으로 변경한다.
[출처] MySQL의 Blob타입을 CUBRID로 변환하기 (큐브리드 공부하기) |작성자 Neo

'PHP > Mysql_이미지저장및 뷰' 카테고리의 다른 글

MySQL 쿼리에 이미지 저장  (0) 2013.07.04

원본 사이트 : http://webdev.berber.co.il/articles/MySqlandImages.php3
이글은 위의 페이지에 있는 글을 번역해 본 것으로 약간의 오역이 있을수도 있습니다.
또한 의미를 파악하는데는 문제가 없겠지만, 원본을 참조해 보시기를 권해드리고 싶습니다.

때때로 이미지를 데이터베이스에 저장하는 것이 파일로 저장하는 것보다 더 편리할때가 있습니다.
MySQL과 PHP는 이런 일을 매우 쉽게 만들어줍니다.
이 글에서 저는 MySQL 데이터베이스에 이미지를 저장하는 방법과 나중에 그것을 드러내 보이는 방법을 설명하고자 합니다.

데이터베이스 설정하기.
~~~~~~~~~~~~~~~~~~~~~~
어떤 보통의 텍스트나 정수영역과 이미지가 저장되어지기 위해 필요한 영역 사이의 차이점은 그 영역속에 지니게 되는데 필요한 데이터의 양입니다.
MySQL은 커다란 양의 데이터를 지니기위해 특별한 영역을 사용합니다.
이런 영역들은 BLOBs(BLOB)라고 알려져 있습니다.

MySQL 사이트에서는 BLOB를 아래와 같이 정의하고 있습니다.

BLOB는 데이터의 가변적인 양을 지니고 있을 수 있는 거대한 바이너리 객체이다.

TINYBLOB, BLOB, MEDIUMBLOB와 LONGBLOB의 네가지 BLOB의 형태는 단지 그들이 지니고 있을 수 있는 값의 최대 길이에서만 다를뿐입니다.

MySQL BLOB에 대한 더 많은 정보는 아래에서 확인해 보십시오.

http://www.mysql.com/Manual_chapter/manual_Reference.html#BLOB

이미지를 지니게 될 기본적인 테이블을 생성하기 위해 다음의 구문을 사용하십시오.

CREATE TABLE Images( PicNum int NOT NULL AUTO_INCREMENT PRIMARY KEY, Image BLOB );

업로드 스크립트 설정하기.
~~~~~~~~~~~~~~~~~~~~~~~~~
파일을 업로드하기 위한 예는 Berber(29/06/99)의 File Uploading(http://webdev.berber.co.il/articles/FileUpload.php3)에서 볼 수 있을 것입니다.

지금 우리에게 필요한 것은 MySQL에 파일을 넣고 그것을 얻는 PHP 스크립트입니다.

다음의 스크립트는 단지 그것 뿐입니다. 스크립트에서 저는 파일필드의 이름을 Picture인 것으로 가정하고 있습니다.

If($Picture != “none”)
{
$PSize = filesize($Picture);
$mysqlPicture = addslashes(fread(fopen($Picture, “r”), $PSize));
mysql_connect($host, $username, $password) or die(“SQL 서버에 접속할 수 없습니다.”);
@mysql_select_db($db) or die(“데이터베이스를 선택할 수 없습니다.”)
mysql_query(“INSERT INTO Image (Image) VALUES ‘($mysqlPicture)’”) or die(“쿼리를 수행할 수 없습니다.”);
}
else
{
echo “어떤 그림도 업로드하지 않으셨습니다.”;
}

이것이 데이터베이스에 이미지를 넣기 위해 필요한 모든 것입니다.
어떤경우에는 여러분이 MySQL에 이미지를 넣으려고 할 때 에러가 발생할 지도모르는데, 그런 경우에는 여러분의 MySQL 버전이 허락하는 최대 패킷의 크기를 확인해 보는 것이 좋습니다.
그런 경우는 매우 적을 테지만, 여러분은 MySQL의 에러 로그내에서 이 에러에 대한 것을 볼 수 있습니다.

위의 파일에서 우리가 한 것은,
1. 만약, If($Picture != “none”)으로 파일이 업로드되었는지 확인하고,
2. MySQL내에서 에러들을 피하기 위해 그림의 스트림에 addslashes()를 주고,
3. MySQL에 접속하여 데이터베이스를 선택하고 이미지를 넣도록 한 것입니다.

이미지 나타내기.
~~~~~~~~~~~~~~~~
이제 우리는 이미지를 데이터베이스에 넣는 법을 알았습니다. 우리는 그것들을 얻고 보이는 방법을 만들어 낼 필요가 있습니다. 이것은 이미지를 넣는 것보다 더 복잡하지만, 만약 여러분이 이 단계를 따른다면 이것을 만들어내고 실행하는데 시간이 걸리지 않을 것입니다.

그림을 보이는 데에는 보내어질 헤더가 필요하기 때문에 우리는 단지 하나의 그림외에는 더 볼 수밖에 없는 그런 상태에 봉착하게 될 수도 있습니다.

한번 헤더를 보내게 되면 더 이상의 헤더를 보낼 수 없게 됩니다.

이것이 트릭이 필요한 부분입니다.
시스템을 약간 속이기 위해 우리는 두개의 파일을 사용합니다.
첫번째 파일은  우리가 보이고자 하는 그림이 어디에 있는지를 알고 있는 HTML 템플릿 파일입니다.
이것은 우리가 보이고자 하는 하는 < IMG > 태그를 포함하고 있는 HTML 파일로서, 일반적인 PHP 파일입니다.

두번째 파일은 < IMG > 태그의 SRC 속성에 직접 데이터베이스로 부터 실제 파일스트림을 제공하기 위해 불리워지는 파일입니다.

첫번째 형태는 보이는 것처럼 매우 간단한 스크립트입니다.

mysql_connect($host, $username, $password) or die(“SQL 서버에 접속할 수 없습니다.”);
@mysql_select_db($db) or die(“데이터베이스를 선택할 수 없습니다.”);
$result=mysql_query(“select * from Images”) or die(“쿼리를 실행할 수 없습니다.”);
while($row=mysql_fetch_object($result))
{
echo ” SRC=\”SecondType.php3?PicNum=$row->PicNum\”>”;
}

그 HTML이 보여지는 동안, 두번째의 SecondType.php3 파일은 우리가 보이고자 하는 각 이미지를 위해 불리워집니다. 이 스크립트는 우리가 이미지를 가져오고 보이는 것을 가능케 하는 Picture ID(PicNum)을 가지고서 불리워 집니다.

SecondType.php3 파일은 이와 같습니다.

$result=mysql_query(“select * from Images where PicNum=$PicNum”) or die(“쿼리를 실행할 수 없습니다.”);
$row=mysql_fetch_object($result);
Header(“Content-type:image/gif”);
echo $row->Image;

이것이 이미지와 MySQL 뒤의 모든 이론입니다. 이 예의 스크립트들은 기본적인 것입니다. 이제 여러분은 썸네일(손톱조각그림)을 포함시키고, 다양한 위치에 이미지를 설정할 수 있게 향상시킬 수 있습니다. ALT 영역을 지닐 수 있도록 데이터베이스를 향상시킬 수도 있습니다. 이미지를 데이터베이스에 넣기 전에 그것의 폭과 높이를 확인하고, 그것의 테이블 등등의 것 역시 갖고 계십시요.

'PHP > Mysql_이미지저장및 뷰' 카테고리의 다른 글

MySQL에서 CUBRID의 변환  (0) 2013.07.15

+ Recent posts