• ベストアンサー

mySQLのカラムの並び順によるデータ領域確保について

MeijiKの回答

  • ベストアンサー
  • MeijiK
  • ベストアンサー率100% (3/3)
回答No.1

ここらへんは、適切なデータ型や適切なキャラクタセットを選択すること以外は、 気にするほどの効果は得られないと思います。 どうしても気になるような場合や、効果を確認したい場合には、 実際にデータを入れてみて確認することをおすすめします。実際にデータを入れるには ご自分の得意なプログラミング言語で挿入してもいいですが、MySQL 5.0以降では ストアドプロシジャが利用できるので、これを使うとプラットフォームに依存せず MySQL本体だけで、どのくらいデータ領域が利用できるか確認できます。例えば 以下のようなテーブルとストアドプロシジャを作成して、 create table tbl1( t1 tinyint(1), t2 tinyint(1), t3 tinyint(1), c4 char(1), i5 int, i6 int, i7 int) engine = myisam; delimiter $ create procedure tbl1_insert(v_max int) begin declare v_id int default 0; repeat set v_id = v_id + 1; insert into tbl1 values(mod(v_id, 128),mod(v_id, 128),mod(v_id, 128),'a', v_id, v_id, v_id); until v_id > v_max end repeat; end; $ delimiter ; create table tbl2( t1 tinyint(1), i2 int, t3 tinyint(1), i4 int, c5 char(1), i6 int, t7 tinyint(1)) engine = myisam; delimiter $ create procedure tbl2_insert(v_max int) begin declare v_id int default 0; repeat set v_id = v_id + 1; insert into tbl2 values(mod(v_id, 128),v_id, mod(v_id, 128),v_id, 'b', v_id, mod(v_id, 128)); until v_id > v_max end repeat; end; $ delimiter ; 以下のように実行すると、それぞれ10万行が挿入できます。 mysql> call tbl2_insert(100000); mysql> call tbl1_insert(100000); その後実際にできたデータファイル(MyISAMの場合、*.MYD)を確認すると 今回の場合は、差異がないことが確認できます。 2010/07/22 09:54 8,712 tbl1.frm 2010/07/22 09:56 1,700,017 tbl1.MYD 2010/07/22 10:05 1,024 tbl1.MYI 2010/07/22 09:54 8,712 tbl2.frm 2010/07/22 09:55 1,700,017 tbl2.MYD 2010/07/22 10:05 1,024 tbl2.MYI

関連するQ&A

  • C++で領域の確保の方法

    今C++の勉強中なのですが、 領域の確保の方法でいい方法が知りたいのです。 ポインターのポインターを使って二次元配列の領域を確保したいのですがいい方法が思いつきません。 int **pBox; pBox = new int *[ 10 ]; for( int i=0; i<10; i++ ) { pBox[ i ] = new int[10]; } //ちなみに今はこんな感じのものしか考え付きませんint型[10][10] を確保したつもりです。 間違っていたら教えていただきたいです。 本題はこちらで、もっと効率のいい確保の方法を知りたいのでご協力を よろしくお願いします。

  • 種別カラムのデータ型について

    MySQLバージョン4.1.16を使用しています。 数種類の種別(青が1、赤が2、緑が3として)を保持するカラムの場合、 そのデータ型はTINYINTなのか、VARCHAR(1)なのか、どちらが良い方法なのでしょうか? それとも(青をblue、赤がred、緑がgreenとして) VARCHAR(10←(少し多めに確保))として英字(blue、red、green)を 保存するやり方もあるのでしょうか? テーブル「好きな色」(TINYINTの場合) +----------+---------+ |  人_id   | 色の種別 | +----------+---------+ |  田中   |   3   | +----------+---------+ |  鈴木   |   1   | +----------+---------+ テーブル「好きな色」(VARCHAR(1)の場合)←この場合は 文字として数字を保存することになるのでしょうか? +----------+---------+ |  人_id   | 色の種別 | +----------+---------+ |  田中   |   3   | +----------+---------+ |  鈴木   |   1   | +----------+---------+ テーブル「好きな色」(VARCHAR(10)の場合) +----------+---------+ |  人_id   | 色の種別 | +----------+---------+ |  田中   |  green | +----------+---------+ |  鈴木   |   blue | +----------+---------+

    • ベストアンサー
    • MySQL
  • メモリ領域確保に関して

    C言語を始めて3ヶ月の初心者です。 下記のような定義で、領域確保をしたいのですが、 うまい方法がわかりません。 ご存知の方いらっしゃいましたら、 御知恵をお貸し下さいませんでしょうか? <test.h> ================================== #define SIZE_A (5) /* 親構造体 */ typedef struct { int testInt; testSmallStructT *testSmall; // 7バイト構造体の配列 char *testChar; // SIZE_A分の領域*配列数 } testBigStructT; /* 7バイト構造体 */ typedef struct { char str1[3]; char str2[4]; } testSmallStructT; /* メンバ変数 */ testBigStructT gTest[10]; ================================== ここで、あらかじめ全体の領域サイズを算出して、 mallocにてエリア確保を行う方法を求めてます。 また、多数にmallocを使用するとメモリ確保失敗時に、 それまで確保したエリアの開放を行わなくてはいけなくなる懸念から、 できるだけ使用しないようにしたいのです。 メンバ変数gTestを10の配列で持ち、構造体testBigStructTの、 要素testSmallとtestCharを可変の配列として扱いたくポインタ定義をしており、 更に、testCharにSIZE_A(5byte)の領域を確保しようとしております。 最終的には、下記のような使い方をしたいのですが、 メモリ確保の方法がわかりません。 =================================== (EX:) strcpy(gTest[0].testSmall[0].str1,"aaa"); strcpy(gTest[3].testSmall[2].str2,"bbb"); strcpy(gTest[6].testChar[3],"cccc"); =================================== 開放は下記の記述で問題ないと思っております。 free(gTest); 大変申し訳御座いませんが、 ご指摘・ご指導願いませんでしょうか? どうか宜しくお願い致します。

  • 動的なメモリ領域の確保

    double型変数5個分のメモリをmalloc関数により確保し,その確保した要素のアドレスを表示するように,プログラムを作る問題で、 (注)に「 %pで表示するためには,double型へのポインタ(double *)をvoid型へのポインタ(void *)にキャストする必要がある.」と書かれていたのですが、どういうことでしょうか? 以下のようでいいのでしょうか? #include<stdio.h> #include<stdlib.h> #define COUNT 5           // 動的に確保するメモリ領域数を示すマクロ定数の定義 int main(void) {  // 動的に確保するメモリ領域のアドレスを保持するポインタ変数の宣言  double * pointer;  int i;                  // for文で使用する変数の宣言  // int型変数5個分のメモリ領域を確保  pointer = (double *)malloc(sizeof(double) * COUNT);  if(pointer == NULL) {        // メモリ領域の確保が失敗した場合   printf("メモリ領域を確保できませんでした.\n");   exit(1);                // プログラムの終了  }  for(i = 0; i < COUNT; i++)   printf("%d番目のアドレスは%pです.\n", i + 1, pointer + i);  free(pointer);            // 確保したメモリ領域の解放  return 0; }

  • void型へのポインタ

    というのがC言語にありますよね? このvoid型へのポインタというのは、 どのようにイメージすればいいのでしょうか? 例えばchar型へのポインタなら、 指している領域は 1バイトの領域ですよね? ではvoid型は? また malloc関数を 使って char *p; p=(char *)malloc(1000); とするとでchar型にキャストしているから、 1個1バイト分の領域が1000個用意して、 先頭アドレスをpに格納するのですよね? では、 int *q; q=(int *)malloc(1000); としたら、用意されるのは、int型にキャストしているから 1個2バイト分の領域が500個用意されるのでしょうか? お願いします。

  • 構造体の領域確保について

    以下のソースでコンパイルは出来るのですが、実行時にセグメンテーション違反のエラーが出ます。 ------------------------------------------------ struct magicpacket { char mgc_syn[6]; char mgc_mac[6][12]; } mgcpkt; /* (1) */ int main(int argc, char **argv) { struct magicpacket *mgc; /* (2) */ char mac[6] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0xff }; make_magic_packet(mgc, mac); /* (3) */ } void make_magic_packet(struct magicpacket *mgc, const char *macaddr) { char *cur; int i, j; /* 初期シーケンス */ for(i = 0; i < 6; i++) { mgc->mgc_syn[i] = 0xff; } /* MAC ADDRESS部 */ cur = &mgc->mgc_mac[0][0]; for(j = 0; j < 16; j++) { memcpy(cur, macaddr, 6); cur += 6; } } ------------------------------------------------ (3)の第一引数を&mgcpkt(1)とするか、(3)の前にmgc = malloc(sizeof(struct magicpacket)); を入れると正常に動作します。(2)では正常にメモリ領域が確保されていないのでしょうか? それとも、他に原因があるのでしょうか。ご教授お願いします。

  • 変数内のデータをmysqlのデータベースへ書き込むサンプルなのですが、うまくinsertされません。

     回答者様たちのおかげで、mysqlをVC++から呼び出すことはできるようになりました。ありがとうございます。  ネットで拾ってきたサンプルを修正し、変数内のデータをtotalというテーブルに書き込んでいくプログラムを書いてみました。  しかし既存のテーブル内のデータは読み込み、表示はできるのですが、書き込みがうまくいきません。  以下、私が書いたソースです。 #include <cstdlib> #include <iostream> #include "windows.h" #include "mysql.h" MYSQL *mysql; MYSQL_RES *results; MYSQL_ROW record; static char *server_options[] = { "mysql_test", "--defaults-file=my.cnf" }; int num_elements = sizeof(server_options)/ sizeof(char *); static char *server_groups[] = { "libmysqld_server", "libmysqld_client" }; //メイン int main(int argc, char **argv) { //mysql_server_init(num_elements, server_options, server_groups); mysql = mysql_init(NULL); //mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "libmysqld_client"); //mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL); char query[256]; int year = 2007; int manth = 2; int day = 2; int hour = 12; int min = 33; int group = 1; int man = 1; char name[] = "紙コップ"; int num = 1; int tanka = 900; int cre = 1; int check; memset(query, '\0', 256); mysql_real_connect(mysql, NULL,"root","パスワード", "rest", 0,NULL,0); if(mysql_errno(mysql) != 0) { fprintf(stderr, "Error: %s\n", mysql_error(mysql)); system("PAUSE"); return 0; } mysql_query(mysql, "SELECT * FROM total"); if(mysql_errno(mysql) != 0) { fprintf(stderr, "Error: %s\n", mysql_error(mysql)); system("PAUSE"); return 0; } results = mysql_store_result(mysql); if(results == NULL || mysql_errno(mysql) != 0) { fprintf(stderr, "Error: %s\n", mysql_error(mysql)); system("PAUSE"); return 0; } /* MYSQL_FIELD *fd; for(int i = 0; fd = mysql_fetch_field(results); i++) { printf("%d %s \n", i, fd->name); } while((record = mysql_fetch_row(results))) { printf("%s %s\n", record[0], record[1]); printf("%s, %s, %s \n", record[2], record[3], record[4]); } */ sprintf(query, "insert into total values (%d, %d, %d, %d, %d, %d, %d, %s, %d, %d, %d)",year, manth, day, hour, min, group, man, name, num, tanka, cre); mysql_query(mysql, query); mysql_free_result(results); mysql_close(mysql); mysql_server_end(); system("PAUSE"); return 1; } データベース名はrest  テーブル名はtotal です。 /**/でかこってある部分は、拾ってきたサンプルで、コメントを外し、 すでにデータが入っているテーブルを指定してやれば、 指定したテーブルのデータを引っ張ってくるので、VC++とmysqlが繋がっていないということはないと思います。 totalのフィールドの数も、書き込みたい変数の数と一致しています。 totalの各フィールドのタイプは、変数nameの紙コップを書き込みたいやつだけVARCHAR型でそれ以外はINT型です。 検索並び替え等はまだ考えてないのでKEY指定はしておりません。 ご指導よろしくお願いいたします。

  • MYSQLからデータを取り出して表示したい

    度々お世話になります。解説書を見ながらMySQLのデータを取り出して表示させようとしているのですが、理解に苦労しています。その本のやり方は以下の通りです。 *サーバ接続済み *データベース選択済み *使用するテーブル名:joke *使用するコラム:joketext $result = @mysql_query('SELECT joketext FROM joke'); if (!$result) { exit('<p>Error performing query: ' . mysql_error() . '</p>'); } while ($row = mysql_fetch_array($result)) { echo '<p>' . $row['joketext'] . '</p>'; } 1.$resultの中にはTURE/FALSE以外に何か入っているのでしょうか?多分データベースのデータがストックされていくのだと思うのですが、この変数には二種類のデータ(true/falseと実際のデータ)が入っているという解釈でよろしいでしょうか? 2.mysql_fetch_arrayですが、これが6行目でやっていることは、$resultからデータを取り出して行に配列していくということでよろしいでしょうか? 3.完全に解らないのは、$row['joketext']の部分で、いったいぜんたいこれは何をやっているんでしょうか?変数の後に[ ]が出てくるパターンはこの本では初めてなのですが、解説されていません。 4.echo '<p>' . $row['joketext'] . '</p>'; の部分で、このピリオドはどういった役割をしているのでしょうか?これも本では初めて出てくるのですが、解説されていなくて困っています。 たくさんの質問になりますが、ひとつでも解る方おられましたら、どうぞよろしくお願いします。

    • ベストアンサー
    • PHP
  • 「動的確保した2次元配列のメモリ解放」を関数化したい

    質問タイトルの通りですが、 「動的確保した2次元配列のメモリ解放」をC言語で関数化したいと思っています。しかし、関数の引数には動的確保した配列の先頭アドレスのみ渡す形にしたいです。そのような場合の関数化は可能ですか? どうもうまくいかず、困っています。 以下、具体的に、サンプルソースを記述します。 わかる方、よろしくお願いします。 //====================================================// #include<stdio.h> unsigned char** AllocByteArray2d(int column, int row); void FreeByteArray2d(unsigned char** box); int main(voidls){ unsigned char array**; array = AllocByteArray2d(2, 3); FreeByteArray2d(array); return 0; } unsigned char** AllocByteArray2d(int column, int row){ unsigned char* box; box = (unsigned char**)malloc( sizeof(unsigned char*)*column ) int i; for(i=0; i<column; i++){ box[i] = (unsigned char*)calloc( row, sizeof(unsigned char)); if(box[i] == NULL) exit(EXIT_FAILURE); } return box; } //引数では配列の先頭アドレスだけ渡す形にしたい void FreeByteArray2d(unsigned char** box){ //ここをどう書いたらいいかわからない }

  • MySQL VIEW連結時の設定

    テーブル名 : table1 カラム1 : id(int) カラム2 : table2_id(int) テーブル名 : table2 カラム1 : id(int) カラム2 : time(int) ← phptaimestamp この二つをviewとして連結したいです。 table1.table2_id と table2.id をキーにするとして、問題はtable2.dateの中身がphpのtimestampで格納されている事です。 VIEW上で連結した際に、このtable2.dateのphpで吐いたtaimestampを通常の20131015の様な変換を加えたいのですが、MySQLの中で完結する方法はあるのでしょうか? 長文で申し訳ありませんが、アドバイス宜しくお願いします。

    • ベストアンサー
    • MySQL