- 投稿日:2019-04-11T22:57:49+09:00
[Rails][mysql] 絵文字を保存できるようにする
「?」みたいな絵文字をMySQLに保存したい。
方法
my.cnf に以下を追記
「/etc/my.cnf」「/etc/mysql/my.cnf」あたりにあるはず。
my.cnf[mysql] default-character-set=utf8mb4 [mysqld] character-set-server = utf8mb4 skip-character-set-client-handshake character-set-server = utf8mb4 collation-server = utf8mb4_general_ci init-connect = SET NAMES utf8mb4 innodb_file_format = Barracuda innodb_file_per_table = 1 innodb_large_prefixdatabase.ymlを変更
database.ymlencoding: utf8 # 変更前 ↓ encoding: utf8mb4 # 変更後databaseを作成
bashbundle exec rake db:create bundle exec rake db:migrate参考
https://qiita.com/okamu_/items/5eb81688849fbe351350
https://y-hilite.com/3192/
- 投稿日:2019-04-11T22:57:49+09:00
[Rails][MySQL] 絵文字を保存できるようにする
「?」みたいな絵文字をMySQLに保存したい。
方法
my.cnf に以下を追記
「/etc/my.cnf」「/etc/mysql/my.cnf」あたりにあるはず。
※最後の3行は、
MariaDB >= 10.3.1ならデフォルトで設定されているので追記しなくてよい。
(設定自体が出来なくなってもいる。 参考)my.cnf[mysql] default-character-set=utf8mb4 [mysqld] character-set-server = utf8mb4 skip-character-set-client-handshake character-set-server = utf8mb4 collation-server = utf8mb4_general_ci init-connect = SET NAMES utf8mb4 innodb_file_format = Barracuda # MariaDB >= 10.3.1 なら削除 innodb_file_per_table = 1 # MariaDB >= 10.3.1 なら削除 innodb_large_prefix # MariaDB >= 10.3.1 なら削除※AWSのRDSでこの設定をする場合はこちら。
database.ymlを変更
database.yml# 変更前 encoding: utf8 ↓ # 変更後 encoding: utf8mb4 charset: utf8mb4 collation: utf8mb4_unicode_cidatabaseを作成
bashbundle exec rake db:create bundle exec rake db:migrate確認
bashmysql # mysqlにログインmysqluse データベース名; # データベースを選択 show variables like 'character_set%'; # 文字コード表示こんな風に表示されるはず。
+--------------------------+--------------------------------+ | Variable_name | Value | +--------------------------+--------------------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql-8.0/charsets/ | +--------------------------+--------------------------------+追記(経験談)
AWSのproduction環境で上記設定をした時、database.ymlが反映されず、SQL発行時に「SET NAMES utf8」が出てしまい、絵文字が保存出来ないという状況が起きました。インスタンスを再起動してみたら直りました。
Capistranoを使っていて、「shared/config/」にdatabase.ymlを置いていたので、これが理由なのかなと思っています。
参考
https://qiita.com/okamu_/items/5eb81688849fbe351350
https://y-hilite.com/3192/
- 投稿日:2019-04-11T18:11:17+09:00
【MySQL+Java】採番プロシージャ
はじめに
MySQL + Java な環境で採番の仕組みを用意する必要があったので、
下記の記事を参考に作ってみました。MySQL で採番テーブル
MySQL で シーケンス 機能実現
LAST_INSERT_IDを使って採番テーブルを扱うOracleのシーケンスがMySQLにもあればなー。
環境
MySQL 5.7
Java 8やったこと
- 採番用のテーブルを用意する。×2
- 採番プロシージャを用意する。×2
- Javaで検証する。
採番用テーブル
テーブル1CREATE TABLE `seq1` ( `prefix` varchar(8) NOT NULL, `id` int(11) NOT NULL DEFAULT '0' ) ENGINE=InnoDB DEFAULT CHARSET=utf8テーブル2CREATE TABLE `seq2` ( `prefix` varchar(8) NOT NULL, `id` int(11) NOT NULL DEFAULT '0' ) ENGINE=InnoDB DEFAULT CHARSET=utf8それぞれ1レコードずつ登録しておく。
採番プロシージャ
プロシージャ1CREATE DEFINER=`trial`@`localhost` PROCEDURE `nextval_seq1`(out seqnum varchar(12)) BEGIN START TRANSACTION; update seq1 set id = LAST_INSERT_ID(id + 1); select CONCAT(prefix, LPAD(LAST_INSERT_ID(id), 10, '0')) into seqnum from seq1; COMMIT; ENDプロシージャ2CREATE DEFINER=`trial`@`localhost` PROCEDURE `nextval_seq2`(out seqnum varchar(12)) BEGIN START TRANSACTION; update seq2 set id = LAST_INSERT_ID(id + 1); select CONCAT(prefix, LPAD(LAST_INSERT_ID(id), 10, '0')) into seqnum from seq2; COMMIT; END検証Javaコード
以下の観点で検証コードを実装しました。
- マルチスレッドでも問題ない事
- プロシージャを利用してもコネクションが死なない事
- 複数の採番用テーブル、採番プロシージャでちゃんと?採番される事
private void execute(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(100); try { List<Callable<Boolean>> taskList = new ArrayList<>(); for (int i = 0; i < 50; i++) { taskList.add(() -> callProcedureAndUpdatePrefix1()); taskList.add(() -> callProcedureAndUpdatePrefix2()); } pool.invokeAll(taskList); } catch (InterruptedException e) { e.printStackTrace(); } finally { pool.shutdown(); } } private boolean callProcedureAndUpdatePrefix1() { try (Connection conn = ConnectionManager.getConnection()) { conn.setAutoCommit(false); callProcedure1(conn); updateSeq1(conn); conn.commit(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } private boolean callProcedureAndUpdatePrefix2() { try (Connection conn = ConnectionManager.getConnection()) { conn.setAutoCommit(false); callProcedure2(conn); updateSeq2(conn); conn.commit(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } private void callProcedure1(Connection con) throws SQLException { try (CallableStatement cs = con.prepareCall("call nextval_seq1(?)")) { cs.executeQuery(); System.out.println(cs.getString(1)); } } private void callProcedure2(Connection con) throws SQLException { try (CallableStatement cs = con.prepareCall("call nextval_seq2(?)")) { cs.executeQuery(); System.out.println(cs.getString(1)); } } private void updateSeq1(Connection con) throws SQLException { boolean b = (new Random()).nextInt(99) % 2 == 0 ? true : false; String sql = "update seq1 set prefix = " + (b ? "'XA'" : "'XB'"); try (Statement st = con.createStatement()) { st.execute(sql); } } private void updateSeq2(Connection con) throws SQLException { boolean b = (new Random()).nextInt(99) % 2 == 0 ? true : false; String sql = "update seq2 set prefix = " + (b ? "'YA'" : "'YB'"); try (Statement st = con.createStatement()) { st.execute(sql); } }検証結果
XA0000000001 YA0000000006 YA0000000004 XA0000000006 XA0000000005 XA0000000002 XA0000000004 XA0000000007 YA0000000003 YA0000000005 XA0000000019 XA0000000018 YA0000000012 XA0000000013 YA0000000008 YA0000000011 YA0000000007 YA0000000015 YA0000000013 XA0000000003 XA0000000012 XA0000000016 XA0000000015 YA0000000014 XA0000000014 XA0000000017 YA0000000009 YA0000000010 YB0000000022 XB0000000023 XB0000000022 YB0000000021 YB0000000019 YA0000000018 YB0000000020 YA0000000016 YB0000000023 XA0000000020 YA0000000017 XA0000000021 XA0000000025 XB0000000026 XA0000000024 XA0000000011 XA0000000008 YA0000000001 XA0000000010 XA0000000009 YB0000000029 YB0000000026 YB0000000028 YB0000000030 YA0000000002 YB0000000024 YB0000000025 YB0000000027 YA0000000034 YA0000000037 YA0000000031 YA0000000032 YA0000000033 YA0000000035 YA0000000038 YA0000000039 YA0000000036 YA0000000043 XA0000000027 XA0000000029 XA0000000035 YA0000000041 XA0000000034 YA0000000042 YA0000000040 XA0000000030 XA0000000028 XA0000000036 XA0000000033 XA0000000032 XA0000000031 XB0000000045 XB0000000046 XB0000000041 XB0000000047 XB0000000048 XB0000000038 YB0000000050 XB0000000037 XB0000000050 YA0000000045 YB0000000047 YA0000000044 XB0000000042 XB0000000043 XB0000000044 XB0000000049 XB0000000039 XB0000000040 YB0000000048 YB0000000046 YB0000000049以上
- 投稿日:2019-04-11T16:02:50+09:00
CakePHP2系でLOAD DATA LOCAL INFILE のエラー
CSVファイルをDBにぶち込むのに LOAD DATA LOCAL INFILEを使いたかった
MySQLクライアントでやってみたら難なくできたのにPHPでやろうとするとこんなエラー
PDOStatement::execute(): LOAD DATA LOCAL INFILE forbidden
使えないの...><
PDOの設定を変えたいので、
/Config/database.phpを書き換えます。databse.phppublic $default = array( 'datasource' => 'hoge', 'persistent' => false, 'host' => 'hoge', 'port' => '', 'login' => 'root', 'password' => 'password', 'database' => 'dbs', 'schema' => '', 'prefix' => '', 'encoding' => 'utf8', //以下を追加 "flags" => array( PDO::MYSQL_ATTR_LOCAL_INFILE => PDO::MYSQL_ATTR_LOCAL_INFILE ) );でよろし。
- 投稿日:2019-04-11T14:13:56+09:00
docker-compose から docker network を少しだけ理解したい
docker-compose での疑問
docker公式っぽいやつの docker-compose の例 : https://docs.docker.com/compose/gettingstarted/
ここでの
app.pyのredisのhostが以下のように指定されています。cache = redis.Redis(host='redis', port=6379)なぜ
host='redis'で別のコンテナのredisにつなぐことが出来るんだい?上記の公式サイトには以下のように解説されています。
In this example, redis is the hostname of the redis container on the application’s network. We use the default port for Redis, 6379.
はぇ〜
application’s network ってなに
ここでいう
application’s networkとはdocker containerにおけるネットワークのことっぽい?
docker-compose up等で起動されたコンテナ群は、すべて同一のネットワークに所属することになるようです。参考にさせていただいた記事 : https://qiita.com/roba4coding/items/efd3a38db08eb476d412
つまりどういうことだってばよ
docker inspectコマンドを使うことでふわっと概要がわかります。
inspectするためにまず コンテナのIDを調べます。$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES aa690f2ae5d4 example_docker_compose_web "python app-server/s…" 2 minutes ago Up 2 minutes 0.0.0.0:5000->5000/tcp example_docker_compose_web_1 4f39c7c9cc47 redis:alpine "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 6379/tcp example_docker_compose_redis_1
inspectします。$ docker inspect 4f39c7c9cc47 ... "Networks": { "example_docker_compose_default": { "IPAMConfig": null, "Links": null, "Aliases": [ "4f39c7c9cc47", "redis" ], ... } } ...コンテナのID :
4f39c7c9cc47(example_docker_compose_redis_1) がredisというエイリアスで登録されているのですね。このエイリアスを使うことが出来るのが、同一
docker networkに所属するものだけだということですね。上記でいうと コンテナ
aa690f2ae5d4(example_docker_compose_web_1) が エイリアスを使うことが出来るということですね。どこで
redisというエイリアスの名前が決まったかということですが、docker-compose.ymlに書いてあるservicesの直下の定義の名のことみたいですね。version: '3' services: # ↓これ web: build: . ports: - "5000:5000" # ↓これ redis: image: "redis:alpine"docker network ってなに
docker network lsで現在存在するdocker networkの一覧を見ることができます。$ docker network ls NETWORK ID NAME DRIVER SCOPE ac27f0096628 bridge bridge local e72136cdac25 example_docker_compose_default bridge local d2b0552308a8 host host localここで 最初の
docker-composeのexampleで作られたであろうexample_docker_compose_defaultのdocker networkの詳細を見てみましょう。コマンドは
docker network inspectです。$ docker network inspect example_docker_compose_default [ { "Name": "example_docker_compose_default", "Id": "e72136cdac25de9dbc9875467aacd59e916ba8b7122cbede91f81387a2a18715", ... "Containers": { "4f39c7c9cc478dc30aca3bd21c6dc1eda2bb189c0b5264a325f98b38ad8cd7c6": { "Name": "example_docker_compose_redis_1", ... }, "aa690f2ae5d483c0c2cf213d9929a3d49025859464abe095f861c05bbb66ee32": { "Name": "example_docker_compose_web_1", ... } }, ... ]
Containersに 先ほどdocker-composeで作られたコンテナ達がありますね。コンテナIDも一致しているようです。参考にさせていただいた記事 : https://qiita.com/TsutomuNakamura/items/ed046ee21caca4a2ffd9
docker-compose を使わずにやってみよう
今回は別の例として
mysqlが起動しているコンテナ に対してpythonが起動したコンテナからアクセスしたいと思います。docker networkを知らなかった時
まず
mysqlのコンテナをたてます。$ docker run -e MYSQL_ROOT_PASSWORD=root -d -p 3307:3306 --name test-mysql mysql:5.6 4f7475ea1ac4db5d4aad630cbe585faf2dca39db61d7e405e14e9554414bd486
pythonが起動しているコンテナからmysqlのコンテナにアクセスするためには、そのコンテナのアドレスを知る必要があります。$ docker exec test-mysql cat /etc/hosts 127.0.0.1 localhost .. 172.17.0.2 4f7475ea1ac4こうすることでようやく接続することができました。(もっといいやり方あったら教えてください..)
>>> import mysql.connector >>> conn = mysql.connector.connect(host="172.17.0.2",user="root",password="root",port=3306,database="mysql") >>> conn.is_connected() Truedocker networkを使った場合
まず、コンテナが所属するための
docker networkを作ります。
docker networkに関して参考にさせていただいたブログ : https://www.sambaiz.net/article/7/$ docker network create -d bridge test-network 25d355cf117def0e6ce801341e1b535320cd688435a436ce063dc49bbb3c9c0e $ docker network ls NETWORK ID NAME DRIVER SCOPE ac27f0096628 bridge bridge local e72136cdac25 example_docker_compose_default bridge local d2b0552308a8 host host local 07263a6d0de1 test-network bridge localコンテナが作成される時に、作ったネットワークに所属してもらうようにするには、
--netオプションを使うようです。$ docker run -e MYSQL_ROOT_PASSWORD=root -d -p 3307:3306 --name test-mysql --net=test-network --net-alias mysql mysql:5.6 0f901dbda634c3d05cce10d2bf91fb0ef82d39fbd1b1046f284db522bc8387f8こうすることで、
docker-composeで起動したコンテナと同様にエイリアスが登録されます。$ docker inspect 0f901dbda634 ... "Networks": { "test-network": { ... "Aliases": [ "mysql", "0f901dbda634" ] ... } ...そして python が起動するコンテナも同一
docker network上にたててあげれば、$ docker run -it --net=test-network test-python >>> import mysql.connector >>> conn = mysql.connector.connect(host='mysql',user='root',password='root',port=3306,database='mysql') >>> conn.is_connected() True無事、コンテナを名前解決できるようになり、
host='mysql'で接続できているのがわかると思います。
--linkの場合$ docker run -e MYSQL_ROOT_PASSWORD=root -d -p 3307:3306 --name test-mysql --net=test-network mysql:5.6 2d96784fb9ae77cec276558d3439e3b455782bb4bac4291b76b65a27d5c27480 $ docker run -it --net=test-network --link test-mysql:mysql test-python Python 3.7.3 (default, Mar 27 2019, 23:48:15) [GCC 8.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import mysql.connector >>> conn = mysql.connector.connect(host='mysql',user='root',password='root',port=3306,database='mysql') >>> conn.is_connected() True同様に繋ぐことが出来ました。
linkの場合AliasesではなくLinksに名前解決するための情報が書かれていました。... "Networks": { "test-network": { ... "Links": [ "test-mysql:mysql" ], "Aliases": [ "d0d2ed057334" ], ... } } ...
--net-aliasと--linkの使い分けに関してはまだ知識が浅いのでいつか調べたいと思います。まとめ
docker-compose を使おう!
- 投稿日:2019-04-11T13:22:47+09:00
コマンドプロンプト自体の文字コードの変更-MySQLで文字化けした時の対処-
コマンドプロンプトで日本語が文字化けしてしまう!
コマンドプロンプト上でMySQLの各カラムを表示すると、日本語のみ文字化けしてしまっていた。
MariaDB [testdb]> insert into test(name,skill)values('みき','HTML'); MariaDB [testdb]> select* from test; +----+------+-------+ | id | name | skill | +----+------+-------+ | 1 | ・ン・ォ | HTML | +----+------+-------+これを解決するのに、丸3日くらいかかりました。
途中嫌になって放り出していましたが(笑)、teratailで神様のような方々からご回答頂き、解決することができました。
原因はいつも通り単純だったわけですが…前提・環境
・プログラミング学習を始めて4か月くらいの新人プログラマー
・今までMySQLは自分のMacで触っていたが今回は会社のWindowsを使っており、コマンドでの文字化けは初体験。
・Windows10
・XAMPP 7.2.6
・MySQL Ver 15.1 Distrib 10.1.33-MariaDB, for Win32
※SQL文はコマンドプロンプトで打ち込んでいます結論
コマンドプロンプト自体の文字コードと、DB・テーブルの文字コードが一致していなかったことが原因。
chcpでコマンドプロンプト自体の文字コードを確認し、chcp 65001で文字コードをUTF8に変更したらちゃんと表示されました。試したこと
せっかく3日もかけたので、試したこと全部載せておきます。
初心者さんの参考になれば。①まずはDBの文字コード設定を確認。
MariaDB [testdb]> show variables like "chara%"; +--------------------------+--------------------------------+ | Variable_name | Value | +--------------------------+--------------------------------+ | character_set_client | cp932 | | character_set_connection | cp932 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | cp932 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | C:\xampp\mysql\share\charsets\ | +--------------------------+--------------------------------+MariaDB [testdb]> show create database testdb; +----------+-----------------------------------------------------------------+ | Database | Create Database | +----------+-----------------------------------------------------------------+ | testdb | CREATE DATABASE `testdb` /*!40100 DEFAULT CHARACTER SET utf8 */ | +----------+-----------------------------------------------------------------+デフォルトがutf8なのが分かります。
②my.iniの[client]と[mysqld]の文字コードをutf8に書き換え
参考URL:https://qiita.com/YusukeHigaki/items/2cab311d2a559a543e3aこの記事を参考にmy.iniの2箇所を書き換えましたが、DBの設定を確認すると文字コードの設定が最初と変わっていなかったので
③my.iniの[mysql]のdefault-set-characterもutf8に書き換え
で、DBの設定を確認MariaDB [(none)]> show variables like "chara%"; +--------------------------+--------------------------------+ | Variable_name | Value | +--------------------------+--------------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | C:\xampp\mysql\share\charsets\ | +--------------------------+--------------------------------+ちゃんとutf8に変わりました。
この状態で新たにDB作成し、INSERT。MariaDB [(none)]> create database test2; MariaDB [test2]> create table table1(id int auto_increment,name varchar(20),skill varchar(20),index(id)); MariaDB [test2]> insert into table1(name,skill)values('みき','PHP'); MariaDB [test2]> select* from table1; +----+------+-------+ | id | name | skill | +----+------+-------+ | 1 | ?ン・? | PHP | +----+------+-------+これでもダメだったので、
④https://teratail.com/questions/58424を参考にset namesしてみた
MariaDB [(none)]> set names cp932; MariaDB [(none)]> create database newone; MariaDB [newone]> create table tbl3(id int,name varchar(10),skill varchar(10)); MariaDB [newone]> insert into tbl3(id,name,skill)values(1,'みき','HTML'); MariaDB [newone]> select* from tbl3; +------+------+-------+ | id | name | skill | +------+------+-------+ | 1 | ・ン・ォ | HTML | +------+------+-------+これでもダメだったので、もうお手上げ状態。
teratailに質問を投げて、返ってきた回答をくまなく試しました。⑤文字コードを「utfmb4」に設定した
MariaDB [(none)]> show variables like "chara%"; +--------------------------+--------------------------------+ | Variable_name | Value | +--------------------------+--------------------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | C:\xampp\mysql\share\charsets\ | +--------------------------+--------------------------------+ MariaDB [test1]> create table test2(id int,name varchar(20))default charset=utf8mb4; MariaDB [test1]> insert into test2(id,name)values(1,'みき'); MariaDB [test1]> select* from test2; +------+------+ | id | name | +------+------+ | 1 | ?ン・? | +------+------+⑥文字コードをsjisに設定した
参照:https://teratail.com/questions/153238MariaDB [test3]> SET character_set_results = sjis; MariaDB [test3]> SET character_set_client = sjis; MariaDB [test3]> create table test2(id int,name varchar(20))default charset=sjis; MariaDB [test3]> insert into test2(id,name)values(1,'みき'); MariaDB [test3]> select* from test2; +------+------+ | id | name | +------+------+ | 1 | ??? | +------+------+これでついに解決!
teratailで神様のような回答を頂き、解決。
sjis自体が文字化けしている事に対して
そこから設定すべきです。Mysqlの問題以前かも知れません。
https://qiita.com/user0/items/a9116acc7bd7b70ecfb0とコメントいただき、コマンドプロンプト自体の文字コードをUTF8に変更(テーブルの文字コードがUTF8であるため)。
# chcp 現在のコード ページ: 932 # chcp 65001 Active code page: 65001で、確認してみると…
MariaDB [trainingdb]> select* from userprofile; +--------+-------------+-----------+-----------------+--------------+ | userid | name | bloodtype | origin | skill | +--------+-------------+-----------+-----------------+--------------+ | 6 | みき | O型 | 九州・沖縄 | HTML,CSS | | 7 | miki | O型 | 九州・沖縄 | HTML,CSS,PHP | | 8 | みき | A型 | 神奈川県 | HTML,CSS | +--------+--------------+-----------+-----------------+---------------+苦節3日、やっとのことで解決しました!!
teratailで優しいご回答をくださった皆さんには感謝しかないです。こういう初歩的な問題でハマるの早くやめたい・・・!
初学者の皆さん、一緒に頑張っていきましょう。。。teratailでの質問
- 投稿日:2019-04-11T11:36:27+09:00
Auroraの性能検証(EC2との比較,データ量と計算時間の関係)
TL;DR
下記の観点で,AWS Auroraの性能検証を行いました.
- AWS Auroraと,EC2上に構成したMariaDBで性能比較しました
- RDBベンチマークTPC-Hによる計算時間の計測
- BI(Business Intelligence)向けの処理で,比較的大きな複数のテーブルからなるDBに対してクエリを発行するものです.
- 意思決定(Decision Making)などで使用される傾向がある処理です
- どちらかというと,Webサービスで使用される際の性能ではなく,バッチ処理での性能評価をしています
データ量と処理時間の関係
- 対象データ量ごとにAWS Auroraでの性能評価を行います
この記事は,下記の記事の続編です.この記事から読み始めることもできます
実験設定
TPC-Hは,使用するテーブルサイズを指定する(SF: Scale Factor)ことができるので,
SF=1, 4, 8でベンチマークするテーブルを用意しました.Aurora
以下の表のパラメータでAuroraを設定します.
設定名 パラメータ エディション MySQL 5.6 との互換性 DBエンジン Aurora(MySQL)-5.6.10a インスタンスタイプ db.r5.large 2vCPU, 16GiB RAM マルチAZ なし MariaDB
- t2.smallを作成
- MariaDBインストール,自動起動の設定
sudo yum -y update sudo yum -y install mariadb mariadb-server sudo systemctl start mariadb sudo systemctl enable mariadb
- 初期設定(ルートパスワードなどの設定)
sudo mysql_secure_installationその他は,auroraと同じように,テーブルの作成,データの登録,インデックスの作成を行います.
実験手順
- Query1からQuery22まで,順番に実行し,
- クエリの実行ごとに
RESET QUERY CACHE;を実行し,キャッシュクリアしてパフォーマンスを正しい計測を行いますfor i in `seq 1 22`; do (time mysql -u [ユーザ名] -h [DBMSエンドポイント] -D [データベース名] -p[パスワード] < ${i}.sql) >> log.txt 2>&1; mysql -u [ユーザ名] -h [DBMSエンドポイント] -p[パスワード] -e 'RESET QUERY CACHE;' done計測結果
TPC-Hで使用するテーブルおよびクエリの詳細は,ドキュメント(tpc-h_v2.18.0.pdf)を参照してください.
AuroraとEC2の比較
計算結果
考察:フルマネージドRDBサービスauroraの利点
- インスタンスタイプに応じた性能が得られているように見えます
- auroraはec2に比べて計算時間上の利点が示されています
- インスタンスタイプの差以上に,EC2よりも良い性能を示すクエリもあります(Query9, 10, 13, 14, 18)
- 大きなテーブル(lineitem)の結合処理を含むクエリ(Query 9, 10, 14, 18)
- likeを含むクエリ(Query 13, 14)
- これらの,重たい処理を含む場合に,auroraの利点が得られるようです
Auroraの結果の比較
計算結果
- AWS auroraで, SF=1, 4, 8 を対象にした計算結果を示します
考察: RDBのスケーラビリティ問題
- データ量に応じて,計算時間を要します
- 結合処理を含む場合(Query1以外)は,データの量に対して, $O(n^2)$ の計算時間を要します
- MySQLの結合処理はNested-loop joinであることから,苦手な処理です
- 大きなテーブル(lineitem)の結合を含むクエリで,極端に計算時間が大きくなるものもあります(Query3, 8, 9, 10, 12, 14, 16, 18, 20, 21)
- メモリ不足で計算時間が増大したようにも見えます
まとめ
- Auroraは,フルマネージドなRDBとして,一定程度のBI(Bussiness Intelligence)処理に効果が得られることが示されました
- EC2上に自分でDBを作るよりも,性能が出そうです
- とは言え,テーブルサイズが大きくなると,(EC2はもちろんauroraでも)計算時間が激増してしまいます
- そもそもRDBで実施するクエリではないとも言えるので,巨大データの結合を含むような処理は,別の方法を考えたほうが良いかもしれません
参考

