« Mac De Oracle Heterogeneous! #33 | トップページ | Mac De Oracle Heterogeneous! #35 »

2006年2月11日 (土) / Author : Hiroshi Sekiguchi.

Mac De Oracle Heterogeneous! #34

数値型の検証のつづき(MySQL編の第2回目)。。。tinyint型、smallint型、mediumint型、int型、bigint型及び、各型の符号なし。

MySQL4.0.25での検証。(MySQL4.1.13aではワーニング返される点がことなるが大きな挙動の差はない。但し、不具合と思われる部分がいくつかある。)
MySQLの仕様なのだが数値型で定義した範囲を超える値を設定した場合はワーニング扱になっている、しかも、上限を超えれば最大値、下限を超えれば最小値に置き換えられる。ちなみに私の知っている商用RDBMSでこのような挙動をするものはないので私にとっては嫌な特徴の一つ。Oracleだけをやってきた方は、”ハマ”りそうな点なので注意しておいたほうがいいだろう。(複数行インサート文では精度超過でワーニングがでるが、MySQL4.0.xでは単一行をインサートする場合はワーニングもでないので要注意。)


1)tinyint型と符号なしtinyint型


Generic Connectivityで扱う場合にも問題は無さそうな気がするが、前述した通り、tinyint型及び、符号なしtinyint型で表現できる範囲を超えた値を設定すると最小値及び最大値に置き換えられてしまうので注意したほうがよい。

mysql> insert into
-> num_test(r_tinyint, r_tinyint_unsigned)
-> values(-128,0);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_tinyint, r_tinyint_unsigned)
-> values(127,255);
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select
-> r_tinyint,
-> r_tinyint_unsigned
-> from
-> num_test
-> limit
-> 3,-1;
+-----------+--------------------+
| r_tinyint | r_tinyint_unsigned |
+-----------+--------------------+
| -128 | 0 |
| 127 | 255 |
+-----------+--------------------+
2 rows in set (0.01 sec)

mysql>


MySQL4.0.25でも表現可能な範囲を超えた値を設定した場合には複数行インサート文ではワーニングが返される。
mysql> insert into
-> num_test(r_tinyint, r_tinyint_unsigned)
-> values(-129,-1), (128,256);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 4

mysql>
mysql> select
-> r_tinyint,
-> r_tinyint_unsigned
-> from
-> num_test
-> limit
-> 3,-1;
+-----------+--------------------+
| r_tinyint | r_tinyint_unsigned |
+-----------+--------------------+
| -128 | 0 |
| 127 | 255 |
| -128 | 0 |
| 127 | 255 |
+-----------+--------------------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.06 sec)

mysql> insert into
-> num_test(r_tinyint, r_tinyint_unsigned)
-> values(-129, -1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_tinyint, r_tinyint_unsigned)
-> values(128,256);
Query OK, 1 row affected (0.00 sec)

mysql> select
-> r_tinyint,
-> r_tinyint_unsigned
-> from
-> num_test
-> limit
-> 3,-1;
+-----------+--------------------+
| r_tinyint | r_tinyint_unsigned |
+-----------+--------------------+
| -128 | 0 |
| 127 | 255 |
| -128 | 0 |
| 127 | 255 |
+-----------+--------------------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.06 sec)

mysql>

2)smallint型と符号なしsmallint型

mysql> insert into
-> num_test(r_smallint, r_smallint_unsigned)
-> values(-32768,0), (32767,65535);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)


以下のインサート文では表現可能な値より大きい又は小さい値を設定している。
mysql> insert into
-> num_test(r_smallint, r_smallint_unsigned)
-> values(-32769,-1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_smallint, r_smallint_unsigned)
-> values(32768,65536);
Query OK, 1 row affected (0.00 sec)

mysql> select
-> r_smallint,
-> r_smallint_unsigned
-> from
-> num_test
-> limit
-> 5,-1;
+------------+---------------------+
| r_smallint | r_smallint_unsigned |
+------------+---------------------+
| -32768 | 0 |
| 32767 | 65535 |
| -32768 | 0 |
| 32767 | 65535 |
+------------+---------------------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.06 sec)

mysql>

3)mediumint型と符号nasimediumint型

mysql> insert into
-> num_test(r_mediumint, r_mediumint_unsigned)
-> values(-8388608,0), (8388607,16777215);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

以下のインサート文で表現可能な値より大きい又は小さい値を設定している。
mysql> insert into
-> num_test(r_mediumint, r_mediumint_unsigned)
-> values(-8388609,-1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_mediumint, r_mediumint_unsigned)
-> values(8388608,16777216);
Query OK, 1 row affected (0.00 sec)

mysql> select
-> r_mediumint,
-> r_mediumint_unsigned
-> from
-> num_test
-> limit 7,-1;
+-------------+----------------------+
| r_mediumint | r_mediumint_unsigned |
+-------------+----------------------+
| -8388608 | 0 |
| 8388607 | 16777215 |
| -8388608 | 0 |
| 8388607 | 16777215 |
+-------------+----------------------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.38 sec)

mysql>

4)int型と符号なしint型

mysql> insert into
-> num_test(r_int, r_int_unsigned)
-> values(-2147483648,0), (2147483647,4294967295);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

以下のインサート文では表現可能な値より大きい又は小さい値を設定している。
mysql> insert into
-> num_test(r_int, r_int_unsigned)
-> values(-2147483649,-1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_int, r_int_unsigned)
-> values(2147483648,4294967296);
Query OK, 1 row affected (0.00 sec)

mysql> select
-> r_int,
-> r_int_unsigned
-> from
-> num_test
-> limit
-> 9,-1;
+-------------+----------------+
| r_int | r_int_unsigned |
+-------------+----------------+
| -2147483648 | 0 |
| 2147483647 | 4294967295 |
| -2147483648 | 0 |
| 2147483647 | 4294967295 |
+-------------+----------------+
4 rows in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.39 sec)

mysql>

5)bigint型と符号なしbigint型 

3行目のインサート文では、符号なしbigint型に −1 を設定しているが丸められて 0 にはならなず、符号なしbigint型の最大値が設定される。4行目のインサート文では、正の最大値を超える値(9223372036854775808)を設定してるにもかかわらず、負の最大値が設定されている。 (不具合だと思われる。)

mysql> insert into
-> num_test(r_bigint, r_bigint_unsigned)
-> values(-9223372036854775808,0), (9223372036854775807,18446744073709551615);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

以下のインサート文では表現可能な値より大きい又は小さい値を設定している。
mysql> insert into
-> num_test(r_bigint, r_bigint_unsigned)
-> values(-9223372036854775809, -1);
Query OK, 1 row affected (0.00 sec)

mysql> insert into
-> num_test(r_bigint, r_bigint_unsigned)
-> values(9223372036854775808, 18446744073709551616);
Query OK, 1 row affected (0.00 sec)

mysql> select
-> r_bigint,
-> r_bigint_unsigned
-> from
-> num_test
-> limit
-> 11,-1;
+----------------------+----------------------+
| r_bigint | r_bigint_unsigned |
+----------------------+----------------------+
| -9223372036854775808 | 0 |
| 9223372036854775807 | 18446744073709551615 |
| -9223372036854775808 | 18446744073709551615 |
| -9223372036854775808 | 18446744073709551615 |
+----------------------+----------------------+
4 rows in set (0.00 sec)

mysql>


尚、MySQL4.1.13aでは3行目と4行目のインサート文でワーニングが1件返される。(ワーニングは2件じゃないのかな? これも不具合のようだが・・・。)
5.x以降ではどのようになるかは分からないが、少なくともMySQL4.x台を対象にしたGeneric Connectivityで、bigint型は利用しないほうがよいだろう。(厳密に範囲チェックし精度を超えないようにすればなんとかなるかもしれないが・・・・・所詮そのプログラムも人が作るもの。バグがないとも限らない。)

mysql> insert into
-> num_test(r_bigint, r_bigint_unsigned)
-> values(-9223372036854775808,0), (9223372036854775807,18446744073709551615);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql>
mysql> commit;
Query OK, 0 rows affected (0.07 sec)

mysql>
以下のインサート文では表現可能な値より大きい又は小さい値を設定している。
mysql> insert into
-> num_test(r_bigint, r_bigint_unsigned)
-> values(-9223372036854775809, -1);
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql>
mysql> insert into
-> num_test(r_bigint, r_bigint_unsigned)
-> values(9223372036854775808, 18446744073709551616);
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select
-> r_bigint,
-> r_bigint_unsigned
-> from
-> num_test
-> limit
-> 11,99;
+----------------------+----------------------+
| r_bigint | r_bigint_unsigned |
+----------------------+----------------------+
| -9223372036854775808 | 0 |
| 9223372036854775807 | 18446744073709551615 |
| -9223372036854775808 | 18446744073709551615 |
| -9223372036854775808 | 18446744073709551615 |
+----------------------+----------------------+
4 rows in set (0.00 sec)

mysql>

次回につづく。

| |

トラックバック


この記事へのトラックバック一覧です: Mac De Oracle Heterogeneous! #34:

コメント

コメントを書く