時間周りの便利そうななにかのメモ
Timeのメソッド
日
beginning_of_day
midnight
週
beginning_of_week
monday
月
beginning_of_month
end_of_month
四半期
beginning_of_quarter
年
beginning_of_year
beginning_of_quarterっていつか使うかな。。。
endがmonthしかないのが気になる。。。
曜日もmondayしかない。。。
mysqlのバグ?ORDER BY DESCが無効になる
5.1.23-rc で発生。
SELECT * FROM entries WHERE blog_id = 1 ORDER BY point DESC LIMIT 2000;
みたいなクエリで ORDER BY point DESC が無視されるという現象が発生(blog_id, point はインデックスを張ってある)。
無視されるというか、ORDER BY id DESC になっていた(id は PRIMARY KEY)。
前日までは正常に並び替えもされていて突然順番が変になった。
100万レコードを超えたりしてたんだけど、このあたり関係あるかな?
十分な検証ができておりませんが、とりあえず、
SELECT * FROM entries WHERE blog_id = 1 ORDER BY point DESC, id LIMIT 2000;
って書くと正常に動作します(ORDER BY に id を追加した)。
parser あたりのバグでしょうか?
railsでのパーティショニング使用
パーティショニングそのものについてはmysql5.1のパーティショニングを使う - d2mrの日記参照
rails経由でパーティショニングの追加をmigrationファイルに以下のように記述する
class AddPartition < ActiveRecord::Migration def self.up # パーティショニングに使う値がプライマリキーでないと怒られるので複合キーに変更する execute("ALTER TABLE entries DROP PRIMARY KEY, ADD PRIMARY KEY (id, updated_at);") # パーティショニングの追加 execute("ALTER TABLE entries PARTITION BY RANGE (TO_DAYS(updated_at)) (PARTITION p200803 VALUES LESS THAN (TO_DAYS('2008-04-01')), PARTITION p200804 VALUES LESS THAN (TO_DAYS('2008-05-01')));") end def self.down # パーティショニングの取り消し execute("ALTER TABLE entries REMOVE PARTITIONING;") # id プライマリキーに戻す execute("ALTER TABLE entries DROP PRIMARY KEY, ADD PRIMARY KEY (id);") end end
複合主キー(composite primary keys)を扱うことになるが、
実質的な主キーはidのみなのでアプリ側を変更する必要はありません。
mysql5.1のパーティショニングを使う
mysql5.1の新機能であるパーティショニング(PARTITIONING)を使ってみたので使い方やら注意点やらまとめ。
最初にパーティションの区切りの基準になるカラムはプライマリキーじゃないといけないという制約があるのでプライマリキーを変更する。
ALTER TABLE entries DROP PRIMARY KEY, ADD PRIMARY KEY (id, blog_id);
実際にパーティションに分割する
ピンポイント数値で分割
ALTER TABLE entries PARTITION BY LIST (blog_id) ( PARTITION p1 VALUES IN (1,3,7), PARTITION p2 VALUES IN (10,11) );
数値範囲で分割
ALTER TABLE entries PARTITION BY RANGE (blog_id) ( PARTITION p1 VALUES LESS THAN 3, PARTITION p2 VALUES LESS THAN 10, PARTITION p_max VALUES LESS THAN MAXVALUE );
日付(DATE, DATETIME)の年で分割
ALTER TABLE entries PARTITION BY LIST (YEAR(updated_at)) ( PARTITION p2007 VALUES IN (2007), PARTITION p2008 VALUES IN (2008) );
日付(DATE, DATETIME)の月で分割
ALTER TABLE entries PARTITION BY RANGE (TO_DAYS(updated_at)) ( PARTITION p200804 VALUES LESS THAN (TO_DAYS('2008-05-01')), PARTITION p200805 VALUES LESS THAN (TO_DAYS('2008-06-01')), PARTITION p200806 VALUES LESS THAN (TO_DAYS('2008-07-01')) );
パーティションを追加する
ALTER TABLE entries ADD PARTITION (PARTITION p3 VALUES LESS THAN 100));
注意:RANGE分割でMAXVALUEを使っている場合に、ADD PARTITION をするとそのテーブルの操作が一切できなくなります。(5.1.23-rc で確認)
パーティショニング(分割)をやめる
ALTER TABLE entries REMOVE PARTITIONING;
よくやる意味のないコード
自戒の意味をこめて。
entry = Entry.find(params[:id]) return false unless entry
実際には entry が見つからなかったら
ActiveRecord::NotFound
の例外が起こるので entry が nil になって次の行が実行されることは実はない。
ちなみに、引き数に配列をいれた場合は、
引き数に入っているidのレコードが全部見つからないと例外になる。
解決策は
begin entry = Entry.find(params[:id]) rescue ActiveRecord::NotFound return false end
か
entry = Entry.find_by_id(params[:id]) return false unless entry
あたりかな。他にもあると思いますが。
CapistranoでWindowsから踏み台サーバを経由して公開鍵認証でデプロイ
Capistranoでいろいろ詰まったのメモしておきます。
基本的な使い方はとりあえず他に任せる方針で。。。
踏み台サーバを経由する
set :gateway, "gateway.nanika.jp" set :ssh_options, :forward_agent => true, :port => 12345
SSHポートを変更する
role :app, "192.168.1.1", :port => 12345
db:migrateする環境を変更する(デフォルトは production)
set :rails_env, "development"
sudo を利用しなくする
set :use_sudo, false