Category ‘MySQL’

mysqldumpで出力したsqlを実行するときにはLOCK TABLESオプションに注意する

このエントリーをはてなブックマー>クに追加 このエントリをtwitterにつぶやく


仕事でMySQLを触る時間が増えてくると、いろいろ知らなかったことやハマりが出てくる。いろいろ勉強になって楽しいなぁと思いつつ、今週引っかかったネタをひとつご紹介。

概要

mysqldumpコマンドでダンプしたSQLは、デフォルトオプションではテーブルロックが付与されている。INSERTを高速にする効用があるが、投入するユーザに「LOCK TABLES」の権限がないと失敗する。

% mysql -u{username} -p{password} {database} < dump.sql
error: 1044: Access denied for user '{username}'@'localhost' to database '{database}' when using LOCK TABLES
(続きを読む…)

MySQLとsequelで文字列の照合順序について調べる

このエントリーをはてなブックマー>クに追加 このエントリをtwitterにつぶやく


概要

MySQLで文字列を検索対象にした場合、一般的なデフォルト設定では大文字・小文字を区別しない。この問題にしっかりハマってしまったので、調査と対策を行ったメモを晒すことにした。

基本的なことがらなのにものすごく長いので「ダイジェスト」を読んでいただければおおむねOKにしてある。検証過程に興味のある方はその続きをどうぞ。

ダイジェスト

MySQLはデフォルトで運用すると文字列の比較 / 並び替えで大文字 / 小文字を区別しない。

大文字小文字を区別して検索するには…

  • テーブル単位
  • カラム単位
  • クエリ単位

…での対応が可能。

データ定義
テーブル単位
-- CREATE TABLE時にテーブルのデフォルト文字コードと照合順序を指定する
CREATE TABLE hoge1 (
    id   INTEGER PRIMARY KEY AUTO_INCREMENT,
    str  VARCHAR(16)
  )
  ENGINE  = InnoDB,
  CHARSET = utf8,
  COLLATE = utf8_bin ;
-- ALTER TABLEで文字コードと照合順序を変換する
ALTER TABLE hoge2 CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin ;
カラム単位
-- CREATE TABLE時にカラムの文字コードと照合順序を指定する
CREATE TABLE hoge2 (
    id        INTEGER PRIMARY KEY AUTO_INCREMENT,
    ci_str    VARCHAR(16),
    cs_str    VARCHAR(16) BINARY,
    other_str VARCHAR(16) CHARACTER SET utf8 COLLATE utf8_bin
  )
  ENGINE  = InnoDB ;
-- カラムの文字コードと照合順序を変換する
ALTER TABLE hoge2 CHANGE COLUMN ci_str ci_str VARCHAR(16) COLLATE utf8_bin ;
データ取得
SQL
-- 大文字小文字を区別するカラムで区別せずに検索
mysql> SELECT * FROM hoge2 WHERE LOWER(cs_str) = 'fuga' ;
-- 大文字小文字を区別しないカラムで区別して検索
SELECT * FROM hoge2 WHERE BINARY ci_str = 'fuga' ;
sequel
# 普通にfilterする => カラムのcollationに依存
ruby-1.9.1-p378 > Hoge2.filter(:ci_str => 'fuga').sql
=> "SELECT * FROM `hoge2` WHERE (`ci_str` = 'fuga')"

# likeでfilter => BINARYキーワードをつけてくれる ruby-1.9.1-p378 > Hoge2.filter(:ci_str.like 'fuga').sql
=> "SELECT * FROM `hoge2` WHERE (`ci_str` LIKE BINARY 'fuga')"

# ilikeでfilter => カラムのcollationに依存 ruby-1.9.1-p378 > Hoge2.filter(:ci_str.ilike 'fuga').sql
=> "SELECT * FROM `hoge2` WHERE (`ci_str` LIKE 'fuga')"

# case-sensitiveなカラムを大文字小文字無視してSELECT ruby-1.9.1-p378 > Hoge2.filter{ |f| [f.lower(:cs_str) => 'fuga'] }.sql
=> "SELECT * FROM `hoge2` WHERE ((lower(`cs_str`) = 'fuga'))"
sequelを使う場合のお勧め
  • テーブル / カラムはデフォルトの照合順序(case-insensitive)にしておく
  • SQLでは大文字小文字を区別したいときBINARYキーワードでキャストを行う
  • sequelでは文字列でfilterする場合普段はlikeを使い、明示的に大文字小文字を同一視したいときだけilikeを使う

以上がダイジェスト。あとは検証過程なので興味と時間的余裕がある方はどうぞ。

(続きを読む…)

インストールしたてのMySQLにスキーマを投入する

このエントリーをはてなブックマー>クに追加 このエントリをtwitterにつぶやく


時々発生する「インストールしたてのMySQLに開発環境を構築する」という作業のために手順メモ。レベルの低い記事で恐縮だが、自分用メモということでご容赦願いたい。

前提条件

  • 開発用サーバ(CentOS5 on XEN)
  • MySQL 5.0
  • localhostからの接続しか受け付けない
  • 他のMySQLにスキーマは登録済み
(続きを読む…)