MySQL テーブル内にバイナリデータを格納する場合、blob 型の列を定義することになります。具体的には blob 型にも複数あり、想定される最大サイズに応じて使うことになります:
格納するデータの内容によって型を決める必要がありますが、例えば画像、音声、動画といったメディア系のファイルを格納しようとすると tinyblob や blob 型では足りないと思われるので、ほぼ mediumblob か largeblob を使うことになると思われます。1データの最大サイズが 16MB を超える想定があるかどうかで使い分けることになります。ただし largeblob でも 4GB が最大となります。
MySQL で mediumblob 型を使う場合のテーブル定義の例としてはこのようになります:
上記例では images テーブル内に mediumblob 型の img 列を定義しました。このテーブルにデータを読み書きする Java のサンプルは後述のようになります。なお後述のサンプル共通で getConnection() という関数を使っていますが、これは java.sql.Connection クラスのインスタンスを返す関数で、具体的には以下のような内容となります:
まずはデータの書き込み(insert)です。格納したいバイナリデータが byte[] 型の変数 data に格納されている場合、以下のようなコードで上述の images テーブルに insert することができます:
一方、読み出し(select)は以下のようになります。ResultSet からバイナリストリームを取得して ByteArrayOutputStream に書き出し、最後に byte[] 型の変数に変換して取り出しています:
バイナリデータをサービスシステム内のどこに格納するべきか、という設計の問題を考慮した上で使うべきだと思いますが、この方法で MySQL に格納しておけば、MySQL のバックアップを取ればバイナリデータもまとめてバックアップすることができ、同様に MySQL をリストアすればバイナリデータごとリストアできる、というメリットがあります。
| 型 | 最大サイズ(バイト) | 格納するデータの例 |
|---|---|---|
| tinyblob | 255 | (あまり使われない?) |
| blob | 65,535 | (あまり使われない?) |
| mediumblob | 16,777,215 | 画像など |
| largeblob | 4,294,967,295 | 動画、音声など |
格納するデータの内容によって型を決める必要がありますが、例えば画像、音声、動画といったメディア系のファイルを格納しようとすると tinyblob や blob 型では足りないと思われるので、ほぼ mediumblob か largeblob を使うことになると思われます。1データの最大サイズが 16MB を超える想定があるかどうかで使い分けることになります。ただし largeblob でも 4GB が最大となります。
MySQL で mediumblob 型を使う場合のテーブル定義の例としてはこのようになります:
create table images( id int primary key, img mediumblob );
上記例では images テーブル内に mediumblob 型の img 列を定義しました。このテーブルにデータを読み書きする Java のサンプルは後述のようになります。なお後述のサンプル共通で getConnection() という関数を使っていますが、これは java.sql.Connection クラスのインスタンスを返す関数で、具体的には以下のような内容となります:
public Connection getConnection(){
Connection conn = null;
try{
Class.forName( "com.mysql.jdbc.Driver" );
conn = DriverManager.getConnection( "jdbc:mysql://servername/dbname", "user", "pass" );
}catch( Exception e ){
e.printStackTrace();
}
return conn;
}
まずはデータの書き込み(insert)です。格納したいバイナリデータが byte[] 型の変数 data に格納されている場合、以下のようなコードで上述の images テーブルに insert することができます:
import java.sql.*;
:
try{
Connection conn = getConnection();
String sql = "insert into images( id, img ) values ( ?, ? )";
PreparedStatement stmt = conn.prepareStatement( sql );
stmt.setInt( 1, id );
stmt.setBytes( 2, data ); //. data は byte[] 型
int r = stmt.executeUpdate();
stmt.close();
conn.close();
}catch( Exception e ){
e.printStackTrace();
}
一方、読み出し(select)は以下のようになります。ResultSet からバイナリストリームを取得して ByteArrayOutputStream に書き出し、最後に byte[] 型の変数に変換して取り出しています:
import java.sql.*;
:
byte[] r = null;
try{
Connection conn = getConnection();
String sql = "select img from images where id = " + id;
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery( sql );
rs.first();
InputStream is = rs.getBinaryStream( 1 );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bs = new byte[1024];
int size = 0;
while( ( size = is.read( bs ) ) != -1 ){
baos.write( bs, 0, size );
}
r = baos.toByteArray(); //. byte[] 型に変換してデータを取得
stmt.close();
conn.close();
}catch( Exception e ){
e.printStackTrace();
r = null;
}
バイナリデータをサービスシステム内のどこに格納するべきか、という設計の問題を考慮した上で使うべきだと思いますが、この方法で MySQL に格納しておけば、MySQL のバックアップを取ればバイナリデータもまとめてバックアップすることができ、同様に MySQL をリストアすればバイナリデータごとリストアできる、というメリットがあります。












