20190507のMySQLに関する記事は9件です。

【MySQL】ユーザーの作成方法について解説!

データベースごとにユーザーの権限を分けて管理する

データベースを操作する際に、あらかじめ用意されている「root」ユーザーは、全ての操作(テーブルの削除、追加 など)ができてしまいます。
そのため、新規で作業ユーザーを作成して、ユーザーごとに操作できる範囲を設定する必要があります。

rootユーザーとは

  • 「root」ユーザーとは、あらかじめ用意されているユーザーで、すべての操作(テーブルの削除、追加 など)が可能な権限を持っています。

作業ユーザーとは

  • 特定の操作のみ行えるように設定したユーザー。(例:テーブルの追加、削除が行える など)

ユーザーの権限を分ける理由

  • 「root」ユーザーは何でも操作ができてしまうため、誰かが誤って操作をしてしまうとデータが失われる危険性があります。
  • そのため、操作できる内容を制限した作業用ユーザーを作成してデータベースを操作します。

作業用ユーザーを作成する方法

grant all on データベース名.* to ユーザー名@loacalhost identified by 'パスワード';
実行結果
Query OK, 0 rows affected (0.00 sec)

解説

  • grant all onは全ての権限を与えるという意味になります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby2.6.x WSLでbrewを使用し、bundle installのmysqlでコケる際の対処。

tl;dr

WSLのbrewで管理しているのであれば

$ bundle config --local build.mysql2 "--with-ldflags=-L/home/linuxbrew/.linuxbrew/opt/openssl/lib"

上記コマンド後にbundle installで多分解決します。

状態

Using kaminari-core 1.1.1                                                                                                                 
Using kaminari-actionview 1.1.1                                                                                                           
Using kaminari-activerecord 1.1.1                                                                                                         
Using kaminari 1.1.1                                                                                                                      
Using launchy 2.4.3                                                                                                                       
Using ruby_dep 1.5.0                                                                                                                      
Using listen 3.1.5                                                                                                                        
Fetching mysql2 0.5.2                                                                                                                     
Installing mysql2 0.5.2 with native extensions                                                                                            
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.                                                                        

    current directory: /home/iruk/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2                                  
/home/iruk/.rbenv/versions/2.6.0/bin/ruby -I /home/iruk/.rbenv/versions/2.6.0/lib/ruby/2.6.0 -r ./siteconf20190507-7094-1spvp3a.rb        
extconf.rb --with-ldflags\=-L/usr/local/opt/openssl/lib                                                                                   
checking for rb_absint_size()... yes                                                                                                      
checking for rb_absint_singlebit_p()... yes                                                                                               
checking for rb_wait_for_single_fd()... yes                                                                                               
-----                                                                                                                                     
Using mysql_config at /home/linuxbrew/.linuxbrew/bin/mysql_config                                                                         
-----                                                                                                                                     
checking for mysql.h... yes                                                                                                               
checking for errmsg.h... yes                                                                                                              
checking for SSL_MODE_DISABLED in mysql.h... yes                                                                                          
checking for SSL_MODE_PREFERRED in mysql.h... yes                                                                                         
checking for SSL_MODE_REQUIRED in mysql.h... yes                                                                                          
checking for SSL_MODE_VERIFY_CA in mysql.h... yes                                                                                         
checking for SSL_MODE_VERIFY_IDENTITY in mysql.h... yes                                                                                   
checking for MYSQL.net.vio in mysql.h... yes                                                                                              
checking for MYSQL.net.pvio in mysql.h... no                                                                                              
checking for MYSQL_ENABLE_CLEARTEXT_PLUGIN in mysql.h... yes                                                                              
checking for SERVER_QUERY_NO_GOOD_INDEX_USED in mysql.h... yes                                                                            
checking for SERVER_QUERY_NO_INDEX_USED in mysql.h... yes                                                                                 
checking for SERVER_QUERY_WAS_SLOW in mysql.h... yes                                                                                      
checking for MYSQL_OPTION_MULTI_STATEMENTS_ON in mysql.h... yes                                                                           
checking for MYSQL_OPTION_MULTI_STATEMENTS_OFF in mysql.h... yes                                                                          
checking for my_bool in mysql.h... no                                                                                                     
-----                                                                                                                                     
Setting libpath to /home/linuxbrew/.linuxbrew/Cellar/mysql/8.0.16/lib                                                                     
-----                                                                                                                                     
creating Makefile                                                                                                                         

current directory: /home/iruk/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2                                      
make "DESTDIR=" clean                                                                                                                     

current directory: /home/iruk/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2/ext/mysql2                                      
make "DESTDIR="                                                                                                                           
compiling client.c                                                                                                                        
In file included from ./mysql2_ext.h:39:0,                                                                                                
                 from client.c:1:                                                                                                         
client.c: In function ‘rb_set_ssl_mode_option’:                                                                                           
./client.h:22:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]                                     
   mysql_client_wrapper *wrapper; \                                                                                                       
   ^                                                                                                                                      
client.c:127:3: note: in expansion of macro ‘GET_CLIENT’                                                                                  
   GET_CLIENT(self);                                                                                                                      
   ^~~~~~~~~~                                                                                                                             
client.c:128:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]                                      
   int val = NUM2INT( setting );                                                                                                          
   ^~~                                                                                                                                    
client.c:133:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]                                      
   int result = mysql_options( wrapper->client, MYSQL_OPT_SSL_MODE, &val );                                                               
   ^~~                                                                                                                                    
client.c: At top level:                                                                                                                   
cc1: warning: unrecognized command line option ‘-Wno-self-assign’                                                                         
cc1: warning: unrecognized command line option ‘-Wno-parentheses-equality’                                                                
cc1: warning: unrecognized command line option ‘-Wno-constant-logical-operand’                                                            
cc1: warning: unrecognized command line option ‘-Wno-cast-function-type’                                                                  
compiling infile.c                                                                                                                        
compiling mysql2_ext.c                                                                                                                    
compiling result.c                                                                                                                        
compiling statement.c                                                                                                                     
statement.c: In function ‘rb_raise_mysql2_stmt_error’:                                                                                    
statement.c:47:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]                                    
   VALUE rb_error_msg = rb_str_new2(mysql_stmt_error(stmt_wrapper->stmt));                                                                
   ^~~~~                                                                                                                                  
statement.c:53:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]                                    
   rb_encoding *default_internal_enc = rb_default_internal_encoding();                                                                    
   ^~~~~~~~~~~                                                                                                                            
In file included from ./mysql2_ext.h:39:0,                                                                                                
                 from statement.c:1:                                                                                                      
statement.c: In function ‘rb_mysql_stmt_execute’:                                                                                         
./client.h:22:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]                                     
   mysql_client_wrapper *wrapper; \                                                                                                       
   ^                                                                                                                                      
statement.c:261:3: note: in expansion of macro ‘GET_CLIENT’                                                                               
   GET_CLIENT(stmt_wrapper->client);                                                                                                      
   ^~~~~~~~~~                                                                                                                             
statement.c:389:13: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]                                  
             VALUE rb_val_as_string = rb_funcall(argv[i], intern_to_s, 0);                                                                
             ^~~~~                                                                                                                        
In file included from ./mysql2_ext.h:39:0,                                                                                                
                 from statement.c:1:                                                                                                      
statement.c: In function ‘rb_mysql_stmt_fields’:                                                                                          
./client.h:22:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]                                     
   mysql_client_wrapper *wrapper; \                                                                                                       
   ^                                                                                                                                      
statement.c:491:3: note: in expansion of macro ‘GET_CLIENT’                                                                               
   GET_CLIENT(stmt_wrapper->client);                                                                                                      
   ^~~~~~~~~~                                                                                                                             
statement.c: At top level:                                                                                                                
cc1: warning: unrecognized command line option ‘-Wno-self-assign’                                                                         
cc1: warning: unrecognized command line option ‘-Wno-parentheses-equality’                                                                
cc1: warning: unrecognized command line option ‘-Wno-constant-logical-operand’                                                            
cc1: warning: unrecognized command line option ‘-Wno-cast-function-type’                                                                  
linking shared-object mysql2/mysql2.so                                                                                                    
/usr/bin/ld: cannot find -lssl                                                                                                            
/usr/bin/ld: cannot find -lcrypto                                                                                                         
collect2: error: ld returned 1 exit status                                                                                                
Makefile:259: recipe for target 'mysql2.so' failed                                                                                        
make: *** [mysql2.so] Error 1                                                                                                             

make failed, exit code 2                                                                                                                  

Gem files will remain installed in /home/iruk/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/mysql2-0.5.2 for inspection.                 
Results logged to /home/iruk/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/extensions/x86_64-linux/2.6.0-static/mysql2-0.5.2/gem_make.out     

An error occurred while installing mysql2 (0.5.2), and Bundler cannot continue.                                                           
Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'` succeeds before bundling.                                 

In Gemfile:                                                                                                                               
  mysql2                                                                                                                                  

MacOS

参考 : mysql2 gemインストール時のトラブルシュート

/usr/bin/ld: cannot find -lssl

この部分が問題となっており、MacOSにおける解決の為のコマンドとしては下記コマンドになります。

$ gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/' -- --with-cppflags=-I/usr/local/opt/openssl/include --with-ldflags=-L/usr/local/opt/openssl/lib

しかし、WSLのbrewではopensllの存在するディレクトリが違うため上記コマンドでは問題の解決には至りません。

WSL

最初のエラー文を眺めると、

-----                                                                                                                                     
Setting libpath to /home/linuxbrew/.linuxbrew/Cellar/mysql/8.0.16/lib                                                                     
-----    

とあります。
WSLのbrewでは/home/linuxbrew/.linuxbrew/Cellar以下で管理をしているようですね。

 
 
では上記のbundle configを上記ディレクトリに合うように書き換えると、最初のコマンドになります。

$ bundle config --local build.mysql2 "--with-ldflags=-L/home/linuxbrew/.linuxbrew/opt/openssl/lib"

これでopensllを読み取れるようになってbundle installを正常にパスできるはず。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

phpMyAdminでストアドプロシージャを呼び出したけどなぜかWHEREが効かない…

忘備録として残しておきます。
似たようなエラーが出て似たような調べ方している人が見つけられますように…!

DBをphpMyAdminで管理していて、今回ストアドプロシージャを新しく作成しました。
その時にWHEREが効かず、テーブルで管理しているデータが全て更新されるといったことが起きました。
書いているコードは

BEGIN
UPDATE tablename SET update=true WHERE id=1;
END

みたいなの。名前は適当です。
「データが全て更新される」というのは、例えば全500データのupdateカラムが一度にtrueになる、といった状態のことを指しています。

本来やりたかったこと

・WHEREで指定したIDが持っている、特定のカラムを更新すること。

試したこと

・同じSQL文を書いてSQLタブで実行すると、1件だけの更新は上手くいく。
・ストアドプロシージャに引数を指定しないで直接書いて呼び出すだけにすると、上手くいく。
・ストアドプロシージャに引数を指定し、BEGIN〜END内では引数を使わないようにすると、上手くいかず、データが全て更新される。

→MySQLに問題はなく、ストアドプロシージャ作成時に引数を指定することによって問題が起きているので引数まわりを確認

解決方法

・引数の名前をカラム名と同じにしない

DELIMITER ;;
CREATE PROCEDURE sp_name(IN test_id INT, IN test_flag BOOLEAN)
BEGIN
UPDATE tablename SET update=test_flag WHERE test_id=test_id;
END;

このような、引数の名前とカラム名が同じになっていました。これを、

DELIMITER ;;
CREATE PROCEDURE sp_name(IN id INT, IN test_flag BOOLEAN)
BEGIN
UPDATE tablename SET update=test_flag WHERE test_id=id;
END;

と直すと、1件ずつ実行され、期待通りの動きになりました。

一通り書き終わってから見つけた参考ページ

別件で調べ物をしていた時に偶然情報を見つけるという…。
https://www.bnote.net/mysql/appendix/select_into.shtml

MySQLのマニュアルには、「SQL文で使用する変数名は、項目名と違う名前を使う」よう 注意書きされています。(引用)

とのことなので、知ってる人は知ってるエラーかも?phpMyAdminでしか確認していなかったせいで原因がわかりづらかったです…。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

値によって列名重複エラーが出る場合

前書

prepared statementなのに値によってsyntax errorが出て混乱したのでメモ

現象

全く関係ない二列に同じ値を設定するとDuplicate column nameが発生する

対処法

ASを使用し列名を設定する
dual表を使用する

-- 実行出来る
select
    'abc'
    , 'abc';

-- 実行出来る
select
    *
from
    (
        select
            'abc'
            , 'xyz'
    ) as temp;

-- 実行出来ない
select
    *
from
    (
        select
            'abc'
            , 'abc'
    ) as temp;

-- 実行出来る
select
    *
from
    (
        select
            'abc' as c1
            , 'abc' as c2
    ) as temp;

-- 多分これが一番正しい
select
    'abc'
    , 'abc'
from
    dual;

-- 次点
select
    'abc'
    , 'abc'
from
    (
        select
            1
    ) as temp;

※リテラル部分は実際にはprepared statementから指定して実行した

因みに

なんでこんな構成が出現したのかというと、insert into valuesにwhere条件を付けたくてinsert into selectに変換
その際from句が必要になったため
MySQLにdualがある(互換性のためらしい)ことを知っていればこんなことには

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

mysql laravel で ユーザー別にランキング順位を求める

例えば 3位/1000人中
とかやりたい。

ただ、これは関連テーブルをSUMして・・・とやるのは無理みたい。
ということで、裏でパッチ処理させておいて、メインテーブルに格納。
それをソートする。
socials テーブル
id sum_social_day7pageviews

があって
指定ユーザーIDが
sum_social_day7pageviews 順に何位か?を求める。

参考
https://qiita.com/hmuronaka/items/1afc132ddf400363efc2

DB::statement(DB::raw('set @c:=0'));//こうやって set を分けておくのが味噌
$res = DB::select("SELECT tmp.id, tmp.sum_social_day7pageviews, tmp.rank rank FROM (SELECT id, sum_social_day7pageviews, @c:=@c+1 rank FROM uranaibako.socials ORDER BY sum_social_day7pageviews DESC) tmp WHERE id=296640879");


これで結果が

Array
(
    [0] => stdClass Object
        (
            [id] => 296640879
            [sum_social_day7pageviews] => 97
            [rank] => 2
        )



やったね!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

mysql -u root -p でERROR 1045 (28000)に遭遇する

「mysql -u root -p」コマンドでmysqlにログインすると以下のエラーが発生

$ mysql -u root -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

対処方法

こちらの記事を参考に以下のコマンドを打っていく


まずmysqlを一旦停止

# service mysql stop


次に権限システムを起動せずにMySQLを起動

# mysqld_safe --skip-grant-tables &


上のコマンドを打った後に再度mysqlにログインを試みると...

# mysql -u root -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)


エラーが発生。一旦DBサーバからexitしてmysqlを打つとこちらでも似たようなエラーが発生。

$ mysql
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)


そこで次はこちらの記事を参考に対処していく。mysqlサーバに接続する際にはmysql.sockファイルを使っているがそのファイルが消えている可能性が。そこでmysql.sockファイルを作り、mysqlを再起動する

$ sudo touch /tmp/mysql.sock
$ sudo mysql.server restart
 ERROR! MySQL server PID file could not be found!
Starting MySQL
.Logging to '/usr/local/var/mysql/[ホームディレクトリ名].local.err'.
 ERROR! The server quit without updating PID file (/usr/local/var/mysql/[ホームディレクトリ名].local.pid).

権限を確認してみる

$ ls -la /usr/local/var/mysql


それでも権限は正常にユーザー名だったので、こちらを参考にmysqlのプロセスを確認してみる

$ ps -ef | grep mysql

確認するとmysqldのプロセスが稼働していたので、こちらは大丈夫なよう。

結果

以下のコマンドでmysqlサーバをrestartし、socketのエラーは解消しました!

$ mysql.server restart
 ERROR! MySQL server PID file could not be found!
Starting MySQL
. SUCCESS!


ただ他の問題は解決せず

# mysql -u root -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
# service mysql stop
$ mysqld_safe --skip-grant-tables &
[1] 2643
[ホームディレクトリ名]:project [ユーザー名]$ 2019-05-06T23:35:44.6NZ mysqld_safe Logging to '/usr/local/var/mysql/[ホームディレクトリ名].local.err'.
2019-05-06T23:35:44.6NZ mysqld_safe A mysqld process already exists


プロセスがすでに走っているとのことなので再度プロセスを調べてみる

$ ps aux| grep mysqld

3つのプロセスが走っていたのでこれらを全てkillする(参考


その後

$ mysql.server start
Starting MySQL
 SUCCESS!

これで行けた!!

$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.25 Homebrew

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RDBMSに格納したGTFSデータから時刻表を作成してみる

GTFS Advent Calendar 7日目の記事です。
今日はRDBMSに格納したGTFSデータに対してSQLクエリを実行し、時刻表を作成する手順を紹介しようと思います。

6日目の記事で作成したER図を眺めてみると、どうやら以下の4つのテーブルの情報を組み合わせると時刻表が作成できそうです。

SnapCrab_NoName_2019-5-7_5-58-59_No-00.png

さっそくSQLクエリを作成してみましょう。経路ID( route_id )と便ID( trip_id )、そして標柱ID( stop_id )をそれぞれ組み合わせることになります。「ある経路を走っている便と、その便の停留所(標柱)をまとめたものが時刻表だよね」という話になります。

SELECT
   r.route_short_name AS 経路略称,
   r.route_long_name AS 経路名,
   t.trip_id AS 便ID,
   t.trip_short_name AS 便名称,
   t.trip_headsign AS 便行先,
   s.stop_id as 停留所・標柱ID,
   s.stop_name as 停留所・標柱名称,
   st.arrival_time as 到着時刻,
   st.departure_time as 出発時刻
  FROM
    stop_times AS st,
    stops AS s,
    trips AS t,
    routes AS r
  WHERE
    r.route_id = t.route_id
    AND t.trip_id = st.trip_id
    AND st.stop_id = s.stop_id
  ORDER BY
    st.trip_id,
    st.arrival_time
  ;

このSQLクエリを実行すると、以下の結果が得られます。何となくそれっぽい結果ですが、ホントに時刻表の形になっているのでしょうか?

SnapCrab_NoName_2019-5-7_6-36-13_No-00.png

北恵那交通株式会社GTFSデータを用いた探索はGoogleマップからも行えるので、その探索結果を使って答え合わせ(?)してみます。

9:30 に中津川駅前を出発して中京大学口に行くバスをGoogleマップ上で探索し、その結果と先のSQLクエリの結果を照らし合わせると良さそうです。

SnapCrab_NoName_2019-5-7_6-14-53_No-00.png

SQLクエリの結果と一致しています。ちゃんと時刻表が作成できていますね!

まとめ

RDBMSに格納したGTFSデータに対してSQLクエリを実行し、時刻表を作成する方法を紹介しました。
GTFSデータは経路情報や便情報、通過時刻情報といった単位でファイル(CSV)が分けられていますが、IDをキーにしてデータをまとめる(RDBMS的には表結合する)ことで、比較的理解しやすい形でデータを処理できそうです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GTFSデータをSQLに変換してみる

GTFS Advent Calendar 3日目の記事です。
今日はGTFSデータをSQL文に変換する方法を紹介しようと思います。

2日目の記事では、GTFSデータをRDBMSに格納する手順を紹介しました。その際、あらかじめGTFSデータをSQLに変換しておき、それをMySQLに流し込むという方法でデータを用意していました。
具体的なSQLファイルは以下になります。

用意したRDBMS環境では、GTFSのファイル(CSVファイル)名をDBのテーブル名にし、CSVのフィールドをテーブルのフィールド名に対応付けているので、比較的簡単にGTFSデータをSQLに変換できています。
変換用のスクリプトは以下の場所に用意してあります。

GTFSデータを展開したディレクトリで gtfs_csv2sql.rb を実行するとSQLが生成されます。

$ git clone https://github.com/ValLaboratory/advcal.git
$ cd advcal/2019/gw/docker_env/script
$
$ # 北恵那交通株式会社(http://www.kitaena.co.jp)のGTFSデータ。
$ curl -s -o kitaena.zip 'http://www.kitaena.co.jp/info/GTFS%282019-03-13_1606%29.zip'
$ unzip kitaena.zip
Archive:  kitaena.zip
 extracting: agency.txt
 extracting: agency_jp.txt
 extracting: calendar.txt
 extracting: calendar_dates.txt
 extracting: fare_attributes.txt
 extracting: fare_rules.txt
 extracting: feed_info.txt
 extracting: routes.txt
 extracting: shapes.txt
 extracting: stops.txt
 extracting: stop_times.txt
 extracting: translations.txt
 extracting: trips.txt
$
$ # SQLを生成します。
$ ruby gtfs_csv2sql.rb
  INSERT INTO routes(route_id,agency_id,route_short_name,route_long_name,route_desc,route_type,route_color,route_text_color) VALUES ('4033','3200001023316','','馬籠線[上り・中切経由]','','3','FF0080','FFFFFF') ;
  INSERT INTO routes(route_id,agency_id,route_short_name,route_long_name,route_desc,route_type,route_color,route_text_color) VALUES ('2006','3200001023316','','加子母線[下り]','','3','FF0080','FFFFFF') ;

適当なファイルに出力して...。

$ ruby gtfs_csv2sql.rb > kitaena.sql

MySQLからSQLを読み込ませれば完了です。

$ docker cp kitaena.sql mysql01:/tmp
$ docker exec -ti mysql01 mysql -uroot -p
mysql>
mysql> -- SQLファイルを読み込ませる。
mysql> source /tmp/kitaena.sql
...中略...
mysql> -- 投入されたデータを確認する。
mysql> SELECT * FROM fare_attributes LIMIT 10 ;
+---------+-------+---------------+----------------+-----------+-------------------+
| fare_id | price | currency_type | payment_method | transfers | transfer_duration |
+---------+-------+---------------+----------------+-----------+-------------------+
| 170_00  |   170 | JPY           | 0              | 0         |              NULL |
| 180_00  |   180 | JPY           | 0              | 0         |              NULL |
| 190_00  |   190 | JPY           | 0              | 0         |              NULL |
| 200_00  |   200 | JPY           | 0              | 0         |              NULL |
| 210_00  |   210 | JPY           | 0              | 0         |              NULL |
| 220_00  |   220 | JPY           | 0              | 0         |              NULL |
| 230_00  |   230 | JPY           | 0              | 0         |              NULL |
| 240_00  |   240 | JPY           | 0              | 0         |              NULL |
| 250_00  |   250 | JPY           | 0              | 0         |              NULL |
| 260_00  |   260 | JPY           | 0              | 0         |              NULL |
+---------+-------+---------------+----------------+-----------+-------------------+
10 rows in set (0.00 sec)

mysql>

これでGTFSとして提供されているデータをRDBMSに格納することができました。

まとめ

GTFSデータをSQLに変換するスクリプトを紹介しました。
RDBMSにデータを格納することで、CSVの形ではちょっと煩雑になりがちなデータの結合や抽出等も、SQLクエリの実行という形で楽に処理できそうです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RDBMSにGTFSデータを格納してみる(環境作成編)

GTFS Advent Calendar 2日目の記事です。
今日はGTFSデータをデータベース(RDBMS)に格納するための手順を紹介しようと思います。

GTFSデータとRDBMS

GTFS(General Transit Feed Specification)は零細事業者の利用を視野に入れており、テキストエディタや表計算ソフトでの閲覧が容易なCSV形式を採用しています。具体的には経路情報(routes.txt)や便情報(trips.txt)のような情報の単位でCSVファイルが分かれています。

CSVファイル内のフィールドには他のCSVファイルのフィールドと関連付く項目があり、RDBMSにおける表結合の操作と相性が良さそうです。

というワケで、実際にGTFSデータをRDBMSに格納してSQLを介してGTFSデータを処理してみましょう。

RDBMS環境の準備

まずはRDBMS環境の準備です。Dockerを使用して手早く用意しましょう。
Dockerイメージ作成用のDockerfileは以下のリポジトリに用意してあります。

$ git clone https://github.com/ValLaboratory/advcal.git
$ cd advcal/2019/gw/docker_env/
$ docker-compose build gtfs_db

git cloneしたのち docker-compose build を実行します。

$ docker images
REPOSITORY  TAG     IMAGE ID      CREATED         SIZE
gtfs_db     latest  eab624c5d7f2  38 minutes ago  449MB

Dockerイメージが作成されるので、イメージからコンテナを起動します。

$ docker run --name mysql01 -e MYSQL_ROOT_PASSWORD=mysql -d -p 3306:3306 gtfs_db
$ docker exec -ti mysql01 mysql -uroot -p

上記の docker exec を実行すると、MySQLのコンソールにログインできます。
コンソール上から以下の手順を実行し、必要なデータベーススキーマとテーブルの作成、GTFSデータの投入を行います。
(必要なSQLファイルはDockerイメージ作成時にコンテナにコピーしています)

mysql> -- データベーススキーマを作成する。
mysql> source /tmp/setup_gtfs_db.sql
mysql>
mysql> -- ER図作成用のデータベースを作成し、テーブルを作成する。
mysql> use gtfs_db_reference
mysql> source /tmp/gtfs_reference.sql
mysql>
mysql> -- GTFSデータ格納用のデータベースを作成し、テーブルを作成する。
mysql> use gtfs_db
mysql> source /tmp/gtfs.sql
mysql> source /tmp/kitaena_gtfs_data.sql

これでRDBMSの準備は完了です。ER図作成用のデータベースは後のAdvent Calendarで解説します。
まずはGTFSデータ格納用のデータベースを触ってみます。

$ docker exec -ti mysql01 mysql -uroot -p
Enter password:
...中略...
mysql>
mysql> -- GTFSデータ格納用のデータベースに切り替えます。
mysql> use gtfs_db ;
mysql>
mysql> -- 適当なテーブルの定義を表示させてみます。
mysql> desc feed_info ;
+---------------------+-------------+------+-----+---------+-------+
| Field               | Type        | Null | Key | Default | Extra |
+---------------------+-------------+------+-----+---------+-------+
| feed_publisher_name | text        | NO   |     | NULL    |       |
| feed_publisher_url  | text        | NO   |     | NULL    |       |
| feed_lang           | varchar(16) | NO   |     | NULL    |       |
| feed_start_date     | varchar(12) | YES  |     | NULL    |       |
| feed_end_date       | varchar(12) | YES  |     | NULL    |       |
| feed_version        | text        | YES  |     | NULL    |       |
+---------------------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

mysql>
mysql> -- データを見てみる。
mysql> SELECT * FROM feed_info ;
+-----------------------------+---------------------------+-----------+-----------------+---------------+-------------------------------------------------+
| feed_publisher_name         | feed_publisher_url        | feed_lang | feed_start_date | feed_end_date | feed_version                                    |
+-----------------------------+---------------------------+-----------+-----------------+---------------+-------------------------------------------------+
| 北恵那交通株式会社          | http://www.kitaena.co.jp/ | ja        | 20190401        | 20200331      | 20190401_2019年04月01日(北恵那バス)           |
+-----------------------------+---------------------------+-----------+-----------------+---------------+-------------------------------------------------+
1 row in set (0.00 sec)

GTFSの各CSVファイル名をテーブル名、CSV内の各項目をテーブルのフィールドに対応させる形のテーブル定義となっています。そして、GTFSのデータとして北恵那交通株式会社GTFSデータを格納しています。

これでGTFSを格納したDBが用意できました。

まとめ

CSVの形で提供されているGTFSデータをRDBMSに格納するための環境作成を行いました。
次回以降のAdvent Calendarでは、このDBを使ってGTFSデータの処理をいろいろ試してみようと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む