Symfoware

Symfowareについての考察blog

Nim トランザクションを使用し、郵便番号と住所情報をMySQLに登録する

読み仮名データの促音・拗音を小書きで表記するもの(zip形式)
NimでこちらのデータをMySQLに登録してみようと思います。

ファイルの読み込みと重複排除



ファイルの読み込みや郵便番号の重複チェックはこちら。
Nim 文字コードを指定したファイルの読み書き
Nim 文字列の結合、分割とトリム(strutils, split, strip)
Nim HashSetの使い方


データベース接続と登録



データベースへの接続、登録はこちら。
Nim MySQLに文字コードを指定して接続し、データの検索、登録を行う(db_mysql)

登録用にこんなテーブルを用意しておきました。


  1. CREATE TABLE post (
  2. zip_code CHAR(7) NOT NULL PRIMARY KEY,
  3. address VARCHAR(255) NOT NULL
  4. );





サンプル



試行錯誤の末のサンプルはこんな感じになりました。


  1. import strutils
  2. import encodings
  3. import sets
  4. import db_mysql
  5. proc mystrip(s: string):string =
  6.     return strip(s, chars={'"'})
  7. proc main() =
  8.     let enc = encodings.open("UTF-8", "CP932")
  9.     let f : File = open("KEN_ALL.CSV" ,FileMode.fmRead)
  10.     let db = open("localhost", "root", "P@ssw0rd", "sample")
  11.     discard setEncoding(db, "utf8mb4")
  12.     
  13.     defer:
  14.         close(enc)
  15.         close(f)
  16.         db.close()
  17.     var zipcodeSet = initSet[string]()
  18.     while not f.endOfFile:
  19.         # 1行読み込み
  20.         let line = enc.convert(f.readLine)
  21.         # カンマで分割
  22.         let data = split(line, ',')
  23.         # 2番目:郵便番号
  24.         let zipcode = mystrip(data[2])
  25.         # 6,7,8番目:住所
  26.         let address = mystrip(data[6]) & mystrip(data[7]) & mystrip(data[8])
  27.         # 郵便番号の重複チェック
  28.         if zipcode in zipcodeSet:
  29.             echo "skip " & zipcode
  30.             continue
  31.         zipcodeSet.incl(zipcode)
  32.         # 登録実行
  33.         db.exec(sql"INSERT INTO post (zip_code, address) VALUES (?, ?)", zipcode, address)
  34. main()



このプログラムを動かしてみましたが、びっくりするほど遅いです。
途中で実行を停止しました。



トランザクション



ちゃんとトランザクションをかけるように修正します。


  1. import strutils
  2. import encodings
  3. import sets
  4. import db_mysql
  5. proc mystrip(s: string):string =
  6.     return strip(s, chars={'"'})
  7. proc main() =
  8.     let enc = encodings.open("UTF-8", "CP932")
  9.     let f : File = open("KEN_ALL.CSV" ,FileMode.fmRead)
  10.     # データベースに接続し文字コードをセット
  11.     let db = open("localhost", "root", "P@ssw0rd", "sample")
  12.     discard setEncoding(db, "utf8mb4")
  13.     # トランザクション開始
  14.     db.exec(sql"START TRANSACTION")
  15.     defer:
  16.         close(enc)
  17.         close(f)
  18.         db.close()
  19.     var zipcodeSet = initSet[string]()
  20.     while not f.endOfFile:
  21.         # 1行読み込み
  22.         let line = enc.convert(f.readLine)
  23.         # カンマで分割
  24.         let data = split(line, ',')
  25.         # 2番目:郵便番号
  26.         let zipcode = mystrip(data[2])
  27.         # 6,7,8番目:住所
  28.         let address = mystrip(data[6]) & mystrip(data[7]) & mystrip(data[8])
  29.         # 郵便番号の重複チェック
  30.         if zipcode in zipcodeSet:
  31.             echo "skip " & zipcode
  32.             continue
  33.         zipcodeSet.incl(zipcode)
  34.         # 登録実行
  35.         db.exec(sql"INSERT INTO post (zip_code, address) VALUES (?, ?)", zipcode, address)
  36.     db.exec(sql"COMMIT")
  37. main()



これで現実的な速度でプログラムが終了するようになりました。
関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/08/27(月) 22:55:44|
  2. nim
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<Nim デバッグビルドとリリースビルドの実行速度 | ホーム | Nim HashSetの使い方>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
https://symfoware.blog.fc2.com/tb.php/2259-75552af1
この記事にトラックバックする(FC2ブログユーザー)