MySQL5.7から追加されたGenerated Column(生成列)を使って、色々と便利な事が出来るようになりました。
先日、Generated Columnを利用してMySQLの照合順を説明したのでその時に利用した生成列をサンプル兼メモです。
Default: utf8_general_ci or utf8mb4_general_ciの場合
英語の大文字、小文字は同じ文字として扱う。
root@localhost [CONFIRM]> show create table T_Character\G *************************** 1. row *************************** Table: T_Character Create Table: CREATE TABLE `T_Character` ( `pid` int(10) unsigned NOT NULL AUTO_INCREMENT, `string1` char(1) DEFAULT NULL, `string2` char(1) DEFAULT NULL, `string1_w_string` char(4) GENERATED ALWAYS AS (hex(weight_string(`string1`))) VIRTUAL, `string2_w_string` char(4) GENERATED ALWAYS AS (hex(weight_string(`string2`))) VIRTUAL, `compare` char(1) GENERATED ALWAYS AS ((`string1` = `string2`)) VIRTUAL, PRIMARY KEY (`pid`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 1 row in set (0.01 sec) root@localhost [CONFIRM]> select * from T_Character; +-----+---------+---------+------------------+------------------+---------+ | pid | string1 | string2 | string1_w_string | string2_w_string | compare | +-----+---------+---------+------------------+------------------+---------+ | 1 | A | a | 0041 | 0041 | 1 | | 2 | あ | ぁ | 3042 | 3041 | 0 | | 3 | か | が | 304B | 304C | 0 | | 4 | あ | ア | 3042 | 30A2 | 0 | | 5 | ア | ア | 30A2 | FF71 | 0 | | 6 | は | ぱ | 306F | 3071 | 0 | | 7 | ハ | パ | 30CF | 30D1 | 0 | +-----+---------+---------+------------------+------------------+---------+ 7 rows in set (0.00 sec) root@localhost [CONFIRM]>
Default: utf8_bin or utf8mb4_binの場合
英語の大文字、小文字は異なる文字として扱う。
root@localhost [CONFIRM]> show create table T_Character_COLLATE_utf8mb4_bin\G *************************** 1. row *************************** Table: T_Character_COLLATE_utf8mb4_bin Create Table: CREATE TABLE `T_Character_COLLATE_utf8mb4_bin` ( `pid` int(10) unsigned NOT NULL AUTO_INCREMENT, `string1` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, `string2` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL, `string1_w_string` char(8) GENERATED ALWAYS AS (hex(weight_string(`string1`))) VIRTUAL, `string2_w_string` char(8) GENERATED ALWAYS AS (hex(weight_string(`string2`))) VIRTUAL, `compare` char(1) GENERATED ALWAYS AS ((`string1` = `string2`)) VIRTUAL, PRIMARY KEY (`pid`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 1 row in set (0.00 sec) root@localhost [CONFIRM]> select * from T_Character_COLLATE_utf8mb4_bin; +-----+---------+---------+------------------+------------------+---------+ | pid | string1 | string2 | string1_w_string | string2_w_string | compare | +-----+---------+---------+------------------+------------------+---------+ | 1 | A | a | 000041 | 000061 | 0 | | 2 | あ | ぁ | 003042 | 003041 | 0 | | 3 | か | が | 00304B | 00304C | 0 | | 4 | あ | ア | 003042 | 0030A2 | 0 | | 5 | ア | ア | 0030A2 | 00FF71 | 0 | | 6 | は | ぱ | 00306F | 003071 | 0 | | 7 | ハ | パ | 0030CF | 0030D1 | 0 | +-----+---------+---------+------------------+------------------+---------+ 7 rows in set (0.00 sec) root@localhost [CONFIRM]>
BIT型やINT型の変換等の確認にも利用可能
root@localhost [CONFIRM]> show create table T_BIT\G *************************** 1. row *************************** Table: T_BIT Create Table: CREATE TABLE `T_BIT` ( `pid` int(10) unsigned NOT NULL AUTO_INCREMENT, `string1` bit(8) DEFAULT NULL, `string2` char(8) GENERATED ALWAYS AS ((`string1` + 0)) VIRTUAL, `string3_BIT` char(8) GENERATED ALWAYS AS (conv((`string1` + 0),10,2)) VIRTUAL, `string4_OCT` char(8) GENERATED ALWAYS AS (conv((`string1` + 0),10,8)) VIRTUAL, `string5_HEX` char(8) GENERATED ALWAYS AS (hex((`string1` + 0))) VIRTUAL, PRIMARY KEY (`pid`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 1 row in set (0.00 sec) root@localhost [CONFIRM]> select * from T_BIT; +-----+---------+---------+-------------+-------------+-------------+ | pid | string1 | string2 | string3_BIT | string4_OCT | string5_HEX | +-----+---------+---------+-------------+-------------+-------------+ | 1 | | 1 | 1 | 1 | 1 | | 2 | | 2 | 10 | 2 | 2 | | 3 | | 3 | 11 | 3 | 3 | | 4 | | 4 | 100 | 4 | 4 | | 5 | | 5 | 101 | 5 | 5 | +-----+---------+---------+-------------+-------------+-------------+ 5 rows in set (0.00 sec) root@localhost [CONFIRM]> show create table T_BIGINT\G *************************** 1. row *************************** Table: T_BIGINT Create Table: CREATE TABLE `T_BIGINT` ( `pid` int(10) unsigned NOT NULL AUTO_INCREMENT, `string1` bigint(64) DEFAULT NULL, `string2_2` char(8) GENERATED ALWAYS AS (conv(`string1`,10,2)) VIRTUAL, `string3_8` char(8) GENERATED ALWAYS AS (conv(`string1`,10,8)) VIRTUAL, `string2_16` char(8) GENERATED ALWAYS AS (conv(`string1`,10,16)) VIRTUAL, PRIMARY KEY (`pid`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 1 row in set (0.00 sec) root@localhost [CONFIRM]> select * from T_BIGINT; +-----+---------+-----------+-----------+------------+ | pid | string1 | string2_2 | string3_8 | string2_16 | +-----+---------+-----------+-----------+------------+ | 1 | 1 | 1 | 1 | 1 | | 2 | 2 | 10 | 2 | 2 | | 3 | 3 | 11 | 3 | 3 | | 4 | 4 | 100 | 4 | 4 | | 5 | 5 | 101 | 5 | 5 | | 6 | 255 | 11111111 | 377 | FF | | 7 | 100 | 1100100 | 144 | 64 | +-----+---------+-----------+-----------+------------+ 7 rows in set (0.00 sec) root@localhost [CONFIRM]>
色々と簡素化出来る事が出来るので、良く使う集計などは上記の様に、
GENERATED COLUMN(生成列)でまとめておくと楽かもしれません。
その他
生成列はJSONデータ型との相性が良いので、是非JSONデータ型と合わせて利用してみて下さい。
MySQLによるJSONデータ型処理
JSONデータとGenerated_Columnを使う場合の考慮事項
PlanetMySQL Voting: Vote UP / Vote DOWN