テーブルの作成・変更に必要な基礎知識について解説します。「int」「text」「datetime」などのデータ型や、「NOT NULL制約」「INDEX」などのオプションについて取り上げます。
CREATE TABLE
( テーブル作成 )
CREATE TABLE文
を使ってテーブルを作成できます。
CREATE TABLE DB名.テーブル名 (
カラム名1 データ型 オプション,
カラム名2 データ型 オプション,
...
オプション
);
以下、実行例です。
CREATE TABLE `sampleDB`.`sampleTable` (
`ID` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR( 30 ) NULL DEFAULT NULL ,
`update_time` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
PRIMARY KEY ( `ID` )
);
テーブルが存在しないときだけ作成としたい場合、以下のようにします。
CREATE TABLE IF NOT EXISTS DB名.テーブル名 ();
ALTER TABLE
( テーブル構造の変更 )
ALTER TABLE文
を使ってテーブル構造を変更できます。
/* カラムの追加 */
ALTER TABLE テーブル名 ADD カラム名 データ型 オプション;
/* カラム指定の変更 */
ALTER TABLE テーブル名 CHANGE 変更前のカラム名 変更後のカラム名 データ型 オプション;
/* カラムの削除 */
ALTER TABLE テーブル名 DROP カラム名;
データ型
使用頻度の高いデータ型
使用頻度の高いデータ型について取り上げます。
データ型 | 範囲 | 備考 |
---|---|---|
boolean | tinyint(1) が使われる。0 がfalse で、それ以外がtrue になる。 | |
int | -2147483648 ~ 2147483647 符号なしの場合 0 ~ 4294967295 | 4バイト |
bigint | -9223372036854775808 ~ 9223372036854775807 符号なしの場合 0 ~ 18446744073709551615 | 8バイト |
float | -3.402823466E+38 ~ -1.175494351E-38 0 1.175494351E-38 ~ 3.402823466E+38 | 概数値として格納 4バイト (符号部1ビット, 指数部8ビット, 仮数部23ビット) |
double | -1.7976931348623157E+308 ~ -2.2250738585072014E-308 0 2.2250738585072014E-308 ~ 1.7976931348623157E+308 | 概数値として格納 8バイト (符号部1ビット, 指数部11ビット, 仮数部52ビット) |
decimal | 真数値として格納 | |
varchar(M) | Mはカラムの最大の長さを文字数で表す。 Mの範囲は 0 ~ 65,535 | 可変長文字列 |
text | 最大 65,535 (216 -1) 文字 のデータを格納 | 値にマルチバイト文字が含まれる場合、有効な最大長は小さくなる |
date | '1000-01-01' ~ '9999-12-31' | 3バイト |
datetime | '1000-01-01 00:00:00' ~'9999-12-31 23:59:59' | 8バイト タイムゾーンの情報をもたない。そのため、地球上のどこの国の時間か特定できいので、サーバー変更時などに注意が必要。 |
timestamp | '1970-01-01 00:00:01' ~'2038-01-19 03:14:07' | 4バイト INSERT または UPDATE 操作の日付と時刻を自動記録するのに利用されることが多い。タイムゾーン情報をもつが、 2038年問題 に注意。 |
geometry | 5.7からInnoDBでもキーをはれる。 | SPATIAL KEY `latlng` (`latlng`) Geometry型で緯度・経度を管理 |
json | 5.7から利用可能。 | JSON型の使い方(検索, 抽出, 挿入, 更新, 置換) |
桁数指定
float、double、decimalは精度(数値を表現する細かさ)と小数点以下の桁数を次のように指定できます。
DOUBLE(全体の桁数, 小数点以下の桁数)
float、doubleは丸め誤差に注意
float
とdouble
は、仮数部の精度以上の数値を保存すると丸め処理が行われます。10進法の小数の多くが2進法では無限小数となることが多く、無限小数を有限の型に入れるため丸め処理が頻繁に行われます。そのため、=演算子
<>演算子
による値の比較を行う場合には、float
やdouble
を使用してはいけません。小数部がある数値を指定どおり正確に格納したい場合は、decimal
を利用します。
動作確認用にテーブルを作成します。次のクエリを実行します。
CREATE TABLE `test`.`test` (
`float` FLOAT NOT NULL ,
`float2` FLOAT(5,2) NOT NULL ,
`double` DOUBLE NOT NULL ,
`double2` DOUBLE(5,2) NOT NULL ,
`decimal` DECIMAL NOT NULL,
`decimal2` DECIMAL(5,2) NOT NULL
) ENGINE = InnoDB;
下記テーブルが作成されました。
mysql> SHOW COLUMNS FROM test;
+----------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------------+------+-----+---------+-------+
| float | float | NO | | NULL | |
| float2 | float(5,2) | NO | | NULL | |
| double | double | NO | | NULL | |
| double2 | double(5,2) | NO | | NULL | |
| decimal | decimal(10,0) | NO | | NULL | |
| decimal2 | decimal(5,2) | NO | | NULL | |
+----------+---------------+------+-----+---------+-------+
6 rows in set (0.00 sec)
データを挿入します。
INSERT INTO `test` (`float`, `float2`, `double`, `double2`, `decimal`, `decimal2`)
VALUES (0.1, 0.1, 0.1, 0.1, 0.1, 0.1);
結果は以下の通りです。
mysql> SELECT * FROM test;
+-------+--------+--------+---------+---------+----------+
| float | float2 | double | double2 | decimal | decimal2 |
+-------+--------+--------+---------+---------+----------+
| 0.1 | 0.10 | 0.1 | 0.10 | 0 | 0.10 |
+-------+--------+--------+---------+---------+----------+
1 row in set (0.00 sec)
100000000倍してみます。
mysql> SELECT `float` * 100000000, -> `float2` * 100000000,
-> `double` * 100000000,
-> `double2` * 100000000,
-> `decimal` * 100000000,
-> `decimal2` * 100000000
-> FROM `test`;
+---------------------+----------------------+----------------------+-----------------------+-----------------------+------------------------+
| `float` * 100000000 | `float2` * 100000000 | `double` * 100000000 | `double2` * 100000000 | `decimal` * 100000000 | `decimal2` * 100000000 |
+---------------------+----------------------+----------------------+-----------------------+-----------------------+------------------------+
| 10000000.149011612 | 10000000.15 | 10000000 | 10000000.00 | 0 | 10000000.00 |
+---------------------+----------------------+----------------------+-----------------------+-----------------------+------------------------+
1 row in set (0.00 sec)
datetime、timestamp
MySQL 5.6.5以前だと、DATETIME型のカラムにCURRENT_TIMESTAMP
を設定できません。 また、CURRENT_TIMESTAMP
を設定したTIMESTAMP型はテーブル内に1つだけしか作成できません。
バージョンによる動作の違いについては、https://dev.mysql.com/doc/refman/5.6/ja/timestamp-initialization.html で確認できます。
テーブル作成時に利用可能なオプション
PRIMARY
UNIQUE
と INDEX
を指定したのと同じです。NULL入力
は不可です。
UNIQUE
重複したものを入力しようとしたときエラーとします。NULL入力
は可能です。
INDEX
インデックスを作成します。一般的に検索は速くなりますが、データ挿入が遅くなる可能性があります。
NULL、NOT NULL
NOT NULL
を指定したカラムは入力必須となります。
AUTO_INCREMENT
自動採番されます。
DEFAULT
データ挿入時のデフォルト値を指定します。DEFAULT CURRENT_TIMESTAMP
と指定することで、日付時刻を自動初期化できます。
ON UPDATE CURRENT_TIMESTAMP
日付時刻を自動更新します。
FOREIGN KEY
外部キー制約を設定します。
以下オプションを指定できます。
ON UPDATE reference_option
ON DELETE reference_option
reference_option
に設定できる値は以下の通りです。
reference_option | 動作 |
---|---|
RESTRICT | エラーになる(デフォルト) |
CASCADE | 参照先の変更と同じ変更が参照元で行われる |
SET NULL | 参照元でNULLになる |
NO ACTION | RESTRICTと同じ |
「参照先が更新されたら同時更新」「参照先が削除されたらNULL設定」としたい場合、以下のようにします。
FOREIGN KEY (`顧客コード`) REFERENCES 顧客(`顧客コード`)
ON UPDATE CASCADE
ON DELETE SET NULL