ホーム ブログ ページ 47

アプリからサクサクお買いもの『DHCオンラインショップ』のレビュー

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


大変ご無沙汰しております。アプリレビューアです。

私がレビューしないうちにAndroid端末もかなり普及し、またアプリのトレンドもどんどん変わってきているかと思っていますが、そんな中、弊社では最近、ECアプリをお手伝いさせていただく機会が増えています。
 
そして、数あるECアプリの中で、弊社が自信を持ってお勧めさせていただくのが、今回のDHCオンラインショップアプリ(iPhone版/Android版)です!
お勧めのポイントは何と言っても、使いやすいこと!
DHC様の素敵な商品がアプリからサクサクお買いもの出来ちゃいます。
 
このシンプルで見やすい画面が使いやすいポイントです。
 
また、商品の検索はもちろんのこと、セール情報や売れ筋ランキングもここからチェックできます。
 
 
検索結果一覧はこんな感じ。

ここから売れ筋順/新着順/価格が安い順等の並べ替え検索もできます。
 
 
どこにいてもスマホから手軽に、サクサクお買いものが出来るのは便利ですね。
 
また、お気に入りの商品がキャンペーン価格になったら自動でお知らせ(Push通知)してくれる、アプリならではの便利機能も搭載!
これで、いつも購入しているサプリのセールも見逃しません。
 
アプリの価格は無料です。iPhone版もAndroid版もあります。
iPhone版ダウンロードはこちらから
Android版ダウンロードはこちらから
 
お買い物がどんどん便利になってきて、また今後どんな機能が追加されるのか、楽しみですね。

redmine ガントチャート チケットの開始日順でソートする

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

redmine ガントチャート チケットの開始日順でソートする

 Redmineでタスク管理

Redmineで公私含めたタスクの管理を行っています。

なんといってもガントチャートが出るのが便利ですね。

Redmineでタスク管理を行うノウハウについては

ほかにたくさんの優れた情報がありますのでここでは詳しくは触れませんが、

個人的にガントチャートを出したいという点を踏まえて気をつけていることは

・チケットには必ず開始日、期日を入力する

・進捗(~%)をつけていく

という点です。

きっちりしすぎると管理コストが高くなりますので、あまり原則にとらわれずにやってます。

本記事はRedmine trunkバージョン リビジョン10485 をもとに書いています。

記事内でソースコードを変更する箇所がありますが、利用する場合は自己責任でお願いします。

 ガントチャートがちょっとみづらい?

本題に入っていきます。

ガントチャートを見てみましょう。

チケット#6の中に子チケットが並んでいます。

現時点ではソートがチケット番号順になっていて、どの順番で作業を行うか少しみづらいです。

 ソース改修

ソート順を変えるため、ソースを変更します。

下記は改修後のソースをsvn diffした結果です。

Index: lib/redmine/helpers/gantt.rb
===================================================================
--- lib/redmine/helpers/gantt.rb        (リビジョン 10485)
+++ lib/redmine/helpers/gantt.rb        (作業コピー)
@@ -638,7 +638,21 @@

       # Sorts a collection of issues by start_date, due_date, id for gantt rendering
       def sort_issues!(issues)
-        issues.sort! { |a, b| gantt_issue_compare(a, b, issues) }
+        default_date = Date.new(1970, 1, 1)
+        issues.sort! do |a, b|
+          a_is_child = a.id != a.root_id ? 1 : 0
+          b_is_child = b.id != b.root_id ? 1 : 0
+          a_start_date = a.start_date || default_date
+          b_start_date = b.start_date || default_date
+          a_child_start_date = Issue.find(a.root_id).children.minimum(:start_date)
+          b_child_start_date = Issue.find(b.root_id).children.minimum(:start_date)
+          a_root_start_date = a_child_start_date || a_start_date
+          b_root_start_date = b_child_start_date || b_start_date
+          (a_root_start_date <=> b_root_start_date).nonzero? ||
+            (a.root_id <=> b.root_id).nonzero? ||
+            (a_is_child <=> b_is_child).nonzero? ||
+            (a_start_date <=> b_start_date)
+        end
       end

       # TODO: top level issues should be sorted by start date

第一ソート: チケットの開始日(子チケットを持つ場合は子チケットの中で最も古い開始日)

第二ソート: 親チケットのチケット番号

第三ソート: チケットの開始日

と複数の条件でソートしています。

ここで単純にチケットの開始日順だけでソートしてしまうと、親チケットは開始日情報を持たずにエラーとなります。また強制的に何か日付を持たせると今度はチケットの親子関係が崩れてしまい、これまたみづらい状況になってしまいます。

 改修後のガントチャート

開始日順になっています。

チケットの親子関係も崩れていないですね。

見やすくなりました。

VirtualBoxの仮想ディスクを圧縮したい

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

VirtualBoxを開発環境に使い、データベースのインポート等繰り返すと仮想ディスクがどんどん肥大化します。

仮想ディスクを圧縮する方法を紹介します。

 VirtualBoxの仮想ディスクの肥大化

VirtualBoxで開発に利用しておりますが、使うにつれ仮想ディスクのサイズがどんどん大きくなります。

仮想ディスクを最適化したい!

今回は、以下の条件での説明になります

ホストOSWindows
ゲストOSLinux

 ゲストOSの不要ファイルの削除

不要なデータベースを削除します。(小職の環境には不要なデータベースをたくさん作ってしまった、今は不要になったため削除する)

不要なファイルを削除する。

 開発時に作成した不要なファイルを削除します。

 空き容量のゼロ埋め

以下のコマンドをゲストOS上で実行する。

dd if=/dev/zero of=zero bs=4k; \rm zero

 VirtualBoxに含まれるツールで最適化

以下を実行すると、最適化が始まります。。。しばらく待ちます。

VBoxManage modifyvdi “D:\SYSTEM_DEVELOPMENT\SYSTEM_DEVELOPMENT.vdi” compact

0%…10%…20%…30%…40%…50%…60%…70%…

100% になり処理が終わると。。。

           ↓のように小さくなりました!

みなさんも、仮想ディスクの肥大化に困った際は、お試しください。

ios6 UICollectionView を試してみた

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ios6から追加されたUICollectionViewのサンプルを作成してみました。

実装画面

下記が実装したアプリ画面です。

UICollectionViewDemoController.h

#import <uikit /uikit.h>

@interface UICollectionViewDemoController : UIViewController 
<uicollectionviewdatasource , uicollectionviewdelegate> {
    UICollectionView *_collectionView;
}

@property (nonatomic, retain) UICollectionView *collectionView;


@end

UICollectionViewDemoController.m

#import "UICollectionViewDemoController.h"

@interface UICollectionViewDemoController (Private)
- (void)setUp;
- (CGFloat)getRandInt:(int)min max:(int)max;
@end


@implementation UICollectionViewDemoController


- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setUp];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)setUp
{
    UICollectionViewFlowLayout *flowLayout = [[[UICollectionViewFlowLayout alloc] init] autorelease];
    [flowLayout setItemSize:CGSizeMake(79, 80)];
    [flowLayout setMinimumLineSpacing:1.0f];
    [flowLayout setMinimumInteritemSpacing:1.0f];
    //[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    
    UICollectionView *collectionView = 
[[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:flowLayout] autorelease];
    self.collectionView = collectionView;
    self.collectionView.delegate   = self;
    self.collectionView.dataSource = self;
    
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"UICollectionViewCell"];
    [self.view addSubview:self.collectionView];
}

-(CGFloat)getRandInt:(int)min max:(int)max {
	static int randInitFlag;
	if (randInitFlag == 0) {
		srand(time(NULL));
		randInitFlag = 1;
	}
	return min + (rand()*(max-min+1.0)/(1.0+RAND_MAX));
}

#pragma UICollectionViewDelegate

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 1000;
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

#pragma UICollectionViewDataSource

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell =
 [collectionView dequeueReusableCellWithReuseIdentifier:@"UICollectionViewCell" forIndexPath:indexPath];

    CGFloat red   = [self getRandInt:1 max:1000] / 1000;
    CGFloat green = [self getRandInt:1 max:1000] / 1000;
    CGFloat blue  = [self getRandInt:1 max:1000] / 1000;
    
    UIColor *color = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
    [cell setBackgroundColor:color];
    
    return cell;
}


@end

以上です。

Postgresqlでカレンダーを使わずに日付を列挙する方法(generate_series)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

今回、カレンダーテーブルを使わずに日付を列挙する方法を書きます。

 運用中のシステムでカレンダーと結合したい要求が発生!

カレンダーテーブルを作りたいが、データベースにテーブル追加ができない場合、どうしよう?

 generate_series

Postgresql8.xから、generate_series という集合関数が出来た。

version 8と9で拡張されているので注意

 9.xの場合

関数引数型戻り型説明
generate_series(start, stop)intまたはbigintsetof intまたはsetof bigint(引数の型と同一)startからstopまで、刻み1で連続する値を生成します。
generate_series(start, stop, step)intまたはbigintsetof intまたはsetof bigint(引数の型と同一)startからstopまで、刻みstepで連続する値を生成します。
generate_series(start, stop, step interval)timestamp または timestamp with time zonesetof timestamp または setof timestamp with time zone(引数型と同じ)startからstopまで、刻みstepで連続する値を生成します。

SELECT * FROM generate_series(‘2008-03-01 00:00’::timestamp,

‘2008-03-04 12:00′, ’10 hours’);

generate_series

———————

2008-03-01 00:00:00

2008-03-01 10:00:00

2008-03-01 20:00:00

2008-03-02 06:00:00

2008-03-02 16:00:00

2008-03-03 02:00:00

2008-03-03 12:00:00

2008-03-03 22:00:00

2008-03-04 08:00:00

(9 rows)http://www.postgresql.jp/document/9.1/html/functions-srf.html

これを使って日付の列挙をしてみる。

6月一か月分の日付を以下のSQLで取得してみる。

SELECT

*

FROM

generate_series( cast(‘2012/06/01’ as timestamp) ,

DATE_TRUNC(‘month’, cast(‘2012/06/01’ as timestamp) + ‘1 months’) + ‘-1 days’,

‘1 days’)

以下のように出力出来ました。

generate_series

———————

2012-06-01 00:00:00

2012-06-02 00:00:00

2012-06-03 00:00:00

2012-06-04 00:00:00

2012-06-05 00:00:00

2012-06-06 00:00:00

2012-06-07 00:00:00

2012-06-08 00:00:00

2012-06-09 00:00:00

2012-06-10 00:00:00

2012-06-11 00:00:00

2012-06-12 00:00:00

2012-06-13 00:00:00

2012-06-14 00:00:00

2012-06-15 00:00:00

2012-06-16 00:00:00

2012-06-17 00:00:00

2012-06-18 00:00:00

2012-06-19 00:00:00

2012-06-20 00:00:00

2012-06-21 00:00:00

2012-06-22 00:00:00

2012-06-23 00:00:00

2012-06-24 00:00:00

2012-06-25 00:00:00

2012-06-26 00:00:00

2012-06-27 00:00:00

2012-06-28 00:00:00

2012-06-29 00:00:00

2012-06-30 00:00:00

(30 rows)

 8.xの場合

関数引数型戻り値の型説明
generate_series(start, stop)int または bigintsetof int またはsetof bigint (引数の型と同一)startからstopまでの刻み1で連続する値を生成します。
generate_series(start, stop, step)int または bigintsetof int または setof bigint (引数の型と同一)startからstopまでの刻みstepで連続する値を生成します。

select current_date + s.a as dates from generate_series(0,14,7) as s(a);

dates

————

2004-02-05

2004-02-12

2004-02-19

(3 rows)http://www.postgresql.jp/document/pg800doc/html/functions-srf.html

以下のSQLで先ほどと同様に6月の一か月分の日付を出力してみます。

SELECT

to_char( ‘2012-06-01’::Date + arr.i, ‘YYYY/MM/DD’ ) as date1

FROM

generate_series( 0,

(select EXTRACT(DAY FROM DATE_TRUNC(‘month’, cast(‘2012/06/01’ as timestamp) + ‘1 months’) + ‘-1 days’) – 1)::int

) as arr(i)

date1

————

2012/06/01

2012/06/02

2012/06/03

2012/06/04

2012/06/05

2012/06/06

2012/06/07

2012/06/08

2012/06/09

2012/06/10

2012/06/11

2012/06/12

2012/06/13

2012/06/14

2012/06/15

2012/06/16

2012/06/17

2012/06/18

2012/06/19

2012/06/20

2012/06/21

2012/06/22

2012/06/23

2012/06/24

2012/06/25

2012/06/26

2012/06/27

2012/06/28

2012/06/29

2012/06/30

(30 rows)

 応用

この日付一覧をテーブルと結合してみます。

以下のデータを例とします。

テーブル名:test1

idfield1create_date
1test2012-09-01
2test22012-09-01
3test32012-09-09

9.xの場合

SELECT

cal.date1,

COALESCE( test1_date.cnt, 0 ) as cnt

FROM

  • 日付一覧

(SELECT

to_char(arr,’YYYY/MM/DD’) as date1

FROM

generate_series( cast(‘2012/09/01’ as timestamp) ,

DATE_TRUNC(‘month’, cast(‘2012/09/01’ as timestamp) + ‘1 months’) + ‘-1 days’,

‘1 days’) as arr

) as cal

  • 結合テーブル

LEFT JOIN

(

SELECT

to_char(create_date, ‘YYYY/MM/DD’) as date2,

count(*) as cnt

FROM

test1

GROUP BY

date2

) as test1_date

ON cal.date1 = test1_date.date2

ORDER BY

cal.date1

以下のように集計結果が出ました。

date1 | cnt

————+—–

2012/09/01 | 2

2012/09/02 | 0

2012/09/03 | 0

2012/09/04 | 0

2012/09/05 | 0

2012/09/06 | 0

2012/09/07 | 0

2012/09/08 | 0

2012/09/09 | 1

2012/09/10 | 0

2012/09/11 | 0

2012/09/12 | 0

2012/09/13 | 0

2012/09/14 | 0

2012/09/15 | 0

2012/09/16 | 0

2012/09/17 | 0

2012/09/18 | 0

2012/09/19 | 0

2012/09/20 | 0

2012/09/21 | 0

2012/09/22 | 0

2012/09/23 | 0

2012/09/24 | 0

2012/09/25 | 0

2012/09/26 | 0

2012/09/27 | 0

2012/09/28 | 0

2012/09/29 | 0

2012/09/30 | 0

8.xの場合

SELECT

cal.date1,

COALESCE( test1_date.cnt, 0 ) as cnt

FROM

  • 日付一覧

(

SELECT

to_char( ‘2012-09-01’::Date + arr.i, ‘YYYY/MM/DD’ ) as date1

FROM

generate_series( 0,

(select EXTRACT(DAY FROM DATE_TRUNC(‘month’, cast(‘2012/09/01’ as timestamp) + ‘1 months’) + ‘-1 days’) – 1)::int

) as arr(i)

) as cal

  • 結合テーブル

LEFT JOIN

(

SELECT

to_char(create_date, ‘YYYY/MM/DD’) as date2,

count(*) as cnt

FROM

test1

GROUP BY

date2

) as test1_date

ON cal.date1 = test1_date.date2

ORDER BY

cal.date1

以下のように集計結果が出ました。

date1 | cnt

————+—–

2012/09/01 | 2

2012/09/02 | 0

2012/09/03 | 0

2012/09/04 | 0

2012/09/05 | 0

2012/09/06 | 0

2012/09/07 | 0

2012/09/08 | 0

2012/09/09 | 1

2012/09/10 | 0

2012/09/11 | 0

2012/09/12 | 0

2012/09/13 | 0

2012/09/14 | 0

2012/09/15 | 0

2012/09/16 | 0

2012/09/17 | 0

2012/09/18 | 0

2012/09/19 | 0

2012/09/20 | 0

2012/09/21 | 0

2012/09/22 | 0

2012/09/23 | 0

2012/09/24 | 0

2012/09/25 | 0

2012/09/26 | 0

2012/09/27 | 0

2012/09/28 | 0

2012/09/29 | 0

2012/09/30 | 0

このように、generate_series関数を駆使すれば、カレンダーテーブルが無くとも

データの集計処理に使えます。

generate_series関数は他にも使い方があるので、詳しくは、PostgreSQLのドキュメントを参照ください。

サーバ単体に負荷テストを行う「stress」

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Web開発では負荷テストというとjmeter や ab を思い浮かべますが、今回はマシン単体に直接負荷をかけるツール「stress」を使用します。

 このツールの便利なところ3点

  1. インストール手順が簡単。
  2. ネットワークには余計な負荷をかけない。
  3. 使い方が簡単でリソースの使用量を直接指定できる。

 入手からインストールまでの流れは次のとおりです。

入手方法:下記ページにてダウンロードしました。

http://weather.ou.edu/~apw/projects/stress/

 今回調査したかったマシンのOSは CentOS6 でしたのでリンク先の下記 rpmファイルをインストールすることにしました。

http://apt.sw.be/redhat/el6/en/i386/rpmforge/RPMS/stress-1.0.2-1.el6.rf.i686.rpm

インストール:

# rpm -ivh stress-1.0.2-1.el6.rf.i686.rpm 
警告: stress-1.0.2-1.el6.rf.i686.rpm: ヘッダ V3 DSA/SHA1 Signature, key ID 6b8d79e6: NOKEY
準備中...                ########################################### [100%]
   1:stress                 ########################################### [100%]

 ちなみに Debian系といった apt が使用できるOSでは apt-get install stress でインストールできるそうです。

使い方について:

 引数を渡さずに実行すると使用方法が表示されます。

# stress 
`stress' imposes certain types of compute stress on your system

Usage: stress [OPTION [ARG]] ...
 -?, --help         show this help statement
     --version      show version statement
 -v, --verbose      be verbose ← 詳細なメッセージを出力
 -q, --quiet        be quiet
 -n, --dry-run      show what would have been done
 -t, --timeout N    timeout after N seconds ← 負荷をかける時間を指定
     --backoff N    wait factor of N microseconds before work starts
 -c, --cpu N        spawn N workers spinning on sqrt() ← CPU負荷をかけるワーカーの数を指定
 -i, --io N         spawn N workers spinning on sync() ← IO負荷のワーカー数


 -m, --vm N         spawn N workers spinning on malloc()/free() ← メモリ負荷のワーカー数


     --vm-bytes B   malloc B bytes per vm worker (default is 256MB)← 使用するメモリ量を指定


     --vm-stride B  touch a byte every B bytes (default is 4096)
     --vm-hang N    sleep N secs before free (default is none, 0 is inf)
     --vm-keep      redirty memory instead of freeing and reallocating
 -d, --hdd N        spawn N workers spinning on write()/unlink()
     --hdd-bytes B  write B bytes per hdd worker (default is 1GB)
     --hdd-noclean  do not unlink files created by hdd workers

Example: stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s

Note: Numbers may be suffixed with s,m,h,d,y (time) or B,K,M,G (size)

好みの引数を渡して実行してください。別のプロンプトで接続し top や vmstat などを表示していると負荷状態の変化が見れて面白いです。

例:メモリ負荷をどんどん上げていく。

stress –cpu 2 –io 2 –vm 2 –vm-bytes 512M –timeout 60s

stress –cpu 2 –io 2 –vm 2 –vm-bytes 1024M –timeout 600s

stress –cpu 2 –io 2 –vm 2 –vm-bytes 2048M –timeout 1200s

stress –cpu 2 –io 2 –vm 2 –vm-bytes 4096M –timeout 1200s

stress –cpu 2 –io 2 –vm 2 –vm-bytes 3072M –timeout 1200s

 負荷の上げ過ぎで stress が起動しなくなったのでさげた。

タイムアウト設定した時間より前に停止させるには Ctrl + C を押します。

必要なライブラリ:

# ldd /usr/bin/stress 
        linux-gate.so.1 =>  (0x00d0c000)
        libm.so.6 => /lib/libm.so.6 (0x0048c000)
        libc.so.6 => /lib/libc.so.6 (0x00e3a000)
        /lib/ld-linux.so.2 (0x008d9000)

 インストールがうまくいかない場合などご参照ください。

postgresqlでデータベース間でテーブル結合する方法(dblink)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

postgresqlでデータベース間でテーブル結合する方法を紹介します。

 dblink

contlibにdblinkというモジュールが登録されているのでこれを利用する。

windowsのインストーラーからインストールした場合同梱されています。

以下のデータベースを例に記載します

データベース host名
db1カレントのデータベースhost1
db2接続先のデータベースhost2

テーブル

データベース名テーブル名
db1table1
db2table2

table1のフィールド

フィールド名
db1_field1int
db1_field2text
db1_field3timestamp

table2のフィールド

フィールド名
db2_field1int
db2_field2text
db2_field3timestamp

 データベースにモジュールを適用する。

ログインする

psql -U [ユーザ―名] -d [モジュールを適用するデータベース名]

モジュールをインストール

create extension dblink;

これでインストールされます。

 接続

以下のSQLを発行すると’接続名’で定義した名前でコネクションを生成します。

select dblink_connetct(‘接続名’,’host=host2 port=5432 dbname=db2 user=xxx password=xxx’);

 切断

以下のSQLを発行すると’接続名’で定義したコネクションを切断します。

select dblink_disconnect(‘接続名’);

 接続先のデータベースにSELECT文を実行するには

上記の接続を実行後に以下のSQL実行することで、値が取得出来ます。

※SQLの返り値の型指定をしないとけないのが面倒。

select *

from dblink(‘接続名’,’ select db2_field1, db2_field2, db2_field3 from table2 ‘)

as t1 ( db2_field1 int, db2_field2 text, db2_field3 timestamp)

 このままでは、SQLが複雑になるのでビューにするとよい。

以下のようにビューを作ると。。。

create view db2_view as

select *

from dblink(‘接続名’,’ select db2_field1, db2_field2, db2_field3 from table2 ‘)

as t1 ( db2_field1 int, db2_field2 text, db2_field3 timestamp);

通常のテーブルのようにSQLが発行出来る。

select * from db2_view;

カレントデータベースにあるテーブルと結合してみる。

普通の結合文のように実行すれば結果が取得出来ます。

select db1.*, db2_view.* from db1

join db2_view on db2_view.db2_field1 = db1.db1_field1;

このように、データベースが異なる場合でもテーブル結合ができるので

活用してみてはいかがでしょうか?

詳細は、PostgreSQLのドキュメント、付録 F.追加で提供されるモジュールの項のdblinkに詳しく書いてあります。

http://www.postgresql.jp/document/9.1/html/dblink.html

DBの実データサイズを調べる(PostgreSQL編)

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

DBを運用していると、どのテーブルが実際にどれくらいのファイルサイズなのかを知りたい場面があるかと思います。

そんな時、DBが使用している実データサイズを調べる方法を説明したいと思います。(データベース/テーブル)

今回はPostgreSQLが対象です。※9.1で確認しました。おそらく8系でも同じ方法かと思います

 データベースの実データサイズを調べる

データベースにはそれぞれoidという識別子が設定されています。

そして、実際にデータが格納されているディレクトリ名にもこのoidが付いています。

ですので、このoidが分かれば、あとは該当のディレクトリのサイズを調べることで、データベースの実データサイズが分かるのです。

oidはpg_stag_databaseという稼働統計情報から調べることができます。

# select datid,datname from pg_stat_database;
 datid  |            datname             
--------+--------------------------------
      1 | template1
  12172 | template0
  12180 | postgres
  30310 | hoge

このdatidというのがデータベースのoidです。hogeデータベースのoidは30310ということになります。

次にPostgreSQLのデータディレクトリから30310という名前のディレクトリを探します。

※データディレクトリの場所は環境やinitdb時の指定により異なります。よく使われるのは/usr/local/pgsql/data/などでしょうか。

[/usr/local/pgsql9.1/data/base]$ du -sh ./*
5.7M    ./1
5.7M    ./12172
5.8M    ./12180
 32M    ./30310
  0B    ./pgsql_tmp

duなどでディレクトリのファイルサイズを調べます。30310は32Mなので、hogeの実データサイズは32MBだと判明しました!

 テーブルの実データサイズを調べる

テーブルの実データサイズの調べ方も基本はデータベースと同じです。

テーブルのoidを調べ、データディレクトリから同じidのディレクトリを探します。

oidはpg_classのrelfilenodeカラムで確認できます。

hoge=# select relfilenode,relname from pg_class order by relname;
 relfilenode |                             relname                             
-------------+-----------------------------------------------------------------
       11868 | _pg_foreign_data_wrappers
       11877 | _pg_foreign_servers
       11886 | _pg_foreign_tables
       11896 | _pg_user_mappings
       30311 | users

usersテーブルのoidは30311だと分かりました。あとは先程調べたhogeデータベースのデータディレクトリ内の同名ディレクトリのファイルサイズを調べればOKです。

[/usr/local/pgsql9.1/data/base/30310]$ du -sh ./* | grep 30311
 16K    ./30311
 24K    ./30311_fsm

grepすると2件ヒットしますが、30311_fsmの方はVACUUM で発見されたすべてのフリースペースが記録されているファイルですので今は無視してOKです。

ですので、上記よりusersテーブルの実データサイズは16KBと分かりました。

以上です。もっと簡単に調べることができれば便利なのですが・・・。

ともあれ、この方法でDBの実データサイズを調べることができますので、ぜひご活用ください。

AWS Management ConsoleからAmazon EC2のインスタンスをセットアップしてみた

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。アピリッツの本多です。

前回に引き続きAWSの記事です。

今回はAmazon EC2のインスタンスをセットアップする手順を紹介します。

※注意:ブラウザはFirefoxを推奨。理由は後述

まずは前回の記事で作成したAWSのアカウントを用意しましょう。

アマゾンウェブサービス(AWS)のアカウントを作成してみました。

1.アマゾンウェブサービスTOPにアクセス

http://aws.amazon.com/jp/

2.ページ右上の「アカウント/コンソール」⇒「AWS Management Console」をクリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.02.AWS_TOP_menu.png

画像の赤枠のリンクです。

3.作成したAWSアカウントでAWS Management Console Homeにログイン

http://doruby.kbmj.com/honda_on_rails/files/ec2.03.Amazon_Web_Services_Sign_In.png

“My e-mail address is:”にメールアドレスを、

“I am a returning user and my password is:”にチェックしてパスワードを入力し

「Sign in using our secure server」をクリック。

ログインに成功すると、↓のようなページに遷移します。

http://doruby.kbmj.com/honda_on_rails/files/ec2.04.AWS_Management_Console_Home.png

4.EC2 Management Consoleに移動

Amazon Web Servicesのメニューの中にある”EC2″をクリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.04.AWS_Management_Console_Home_EC2_link.png

画像の赤枠のリンクです。

以下のページに遷移します。

http://doruby.kbmj.com/honda_on_rails/files/ec2.17.EC2_Management_Console.png

5.インスタンスセットアップ開始

http://doruby.kbmj.com/honda_on_rails/files/ec2.17.EC2_Management_Console2.png

Regionが”Asia Pacific (Tokyo)”になっている事を確認(画像左上の緑枠)し、

画像中央の赤枠の”Launch Instance”をクリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.05.Create_a_New_Instance.png

Classic Wizardを選択して「Continue」をクリック

6.OSを選択

http://doruby.kbmj.com/honda_on_rails/files/ec2.06.Choose_an_ami.png

特に決めているものが無ければ”Amazon Linux AMI”の64bitを選択

インスタンスのタイプ次第ではメモリが4GBを超えるものもあるため、64bitを選択しておくのが無難だと思います。

7.インスタンスタイプを選択

http://doruby.kbmj.com/honda_on_rails/files/ec2.07.Instance_Type.png

言い換えればサーバースペックの選択ですね。

業務の場合は用途に合ったスペックのインスタンスタイプを選択してください。

今回は、無料で使用出来るMicroを選択しています。

8.Availability Zoneを選択

http://doruby.kbmj.com/honda_on_rails/files/ec2.08.Availability_Zone.png

特に決めていない場合は”No Preference”を選択で良いです。

ただし、webサーバー用インスタンスを複数台用意する等、冗長化構成を取る場合は予め使用するAvailability Zoneを決めておき、

明示的に”ap-northeast-1a”、”ap-northeast-1b”を選択するようにしてください。

http://doruby.kbmj.com/honda_on_rails/files/ec2.09.Advanced_Instance_Options.png
http://doruby.kbmj.com/honda_on_rails/files/ec2.10.Storage_Device_Configuration.png

途中のAdvanced Instance OptionsやStorage Device Configurationはそのままで次へ。

Shutdown Behaviorが”Stop”になっている事だけ確認しておいてください。

9.サーバー名を設定

http://doruby.kbmj.com/honda_on_rails/files/ec2.11.Add_tags_to_your_instance.png

これはインスタンス一覧に表示する際に使われるタグの設定です。

Nameのvalueにサーバー名を入れておきましょう。

10.鍵ファイルの作成&設定

ログインするのに必要な鍵ファイルを作成する

http://doruby.kbmj.com/honda_on_rails/files/ec2.18.Create_a_new_Key_Pair.png

“Enter a name for your key pair”のフォームに名前を入力して”Create & Download your Key Pair”をクリックする。

すると鍵ファイルのダウンロードが始まるので任意の場所に保存。

保存後は次の画面に自動で遷移します。

※なお、IEだとダウンロードに失敗するという情報があるので、firefoxで実施する

既存の鍵ファイルを流用する際は”Choose from your existing Key Pairs”から鍵ファイル名を選択する

11.セキュリティグループの作成&指定

外部からのアクセスを制限するため、IPアドレスやポートの設定を行う。

http://doruby.kbmj.com/honda_on_rails/files/ec2.12.Create_a_new_security_group.png

デフォルトでSSHの22番ポートが全IPアドレスに対して開放されている状態です。

http://doruby.kbmj.com/honda_on_rails/files/ec2.13.Create_a_new_security_group_list.png

HTTPやHTTPS等の良く使われる設定は、いちいち番号を入力せずともリストから選択可能です。

設定して「Continue」をクリック

12.確認画面の内容をチェック

http://doruby.kbmj.com/honda_on_rails/files/ec2.14.review_the_information.png

問題なければ”Launch”をクリックしてインスタンス起動

http://doruby.kbmj.com/honda_on_rails/files/ec2.15.Your_instances_are_now_launching.png

正常に起動されれば↑のような画面に遷移します。

以上の手順でインスタンスを起動する事が出来ました。

それでは最後に接続確認をしましょう。

13.作成したインスタンスにSSHでログイン出来る事を確認

EC2 Management Consoleからインスタンス一覧に遷移する

“INSTANCES”⇒”Instances”をクリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.17.EC2_Management_Console_2.png

画像の赤枠のリンクです

インスタンス一覧に作成したインスタンスが追加されている事を確認し、クリック

http://doruby.kbmj.com/honda_on_rails/files/ec2.16.EC2_Instance_selected.png

インスタンス詳細に大きくPublic DNSが表示されているので、メモしておく

画像の赤枠の部分です。

14.SSHクライアントでログイン

13で確認したPublic DNSと、10で作成した鍵ファイルを元にSSH接続

※SSHクライアントにputtyを使用している場合は、別途変換する必要有

ID: ec2-user

PASS: なし

でログイン出来る事が確認できればOKです。

あとがき

今回は手順を細かく砕いて説明したため、14もの工程になりましたが、手順そのものはさほど難しくなく

行う事が出来たのではないかと思います。

次回はEC2を業務利用する上で必要な作業の1つであるEIPの設定手順を紹介したいと思います。

rails3のログ解析ツール「request-log-analyzer」について

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rails3のログ解析ツールを紹介します。

 request-log-analyzer

rails3のproduction.logを解析する事になったので、調べてみると

request-log-analyzerというツールが良いとの記事を見た。

 インストールしてみる。

railsが入っている環境であれば以下のコマンドでインストールされます。

 gem install request-log-analyzer

 小職の環境では、以下にインストールされました。

/usr/local/bin/request-log-analyzer

 使ってみる

以下を入力すると。。。。

request-log-analyzer production.log

解析が始まり、解析が終わると

Request summary リクエストのサマリー
  • Parsed lines 解析した行数
  • Skipped lines スキップした行数
  • Parsed request 解析したリクエスト
  • Skipped lines スキップしたリクエスト
  • Warnings 警告数
  • First request 最初のリクエストの日時
  • Last reuquest 最後のリクエストの日時
  • Total time analyzed 解析した期間
Request distribution per hour 時間当たりのリクエスト数
Most requested リクエストの多い順(TOP20)
HTTP methods HTTPメソッド毎のリクエスト数
HTTP status returned HTTPのステータス毎のリクエスト数
REQUEST DURATION – BY SUM リクエストの所要時間の合計
REQUEST DURATION – BY MEAN リクエストの所要時間の平均
VIEW RENDERING TIME – BY SUM ビューのレンダリング時間の合計
VIEW RENDERING TIME – BY MEAN ビューのレンダリング時間の平均
DATABASE TIME – BY SUM データベースからの応答時間の合計
DATABASE TIME – BY MEAN データベースからの応答時間の平均
Process blockers (> 1 sec duration) 
Parse warnings 解析時のワーニングが表示されます

 railsのログ以外での使い方

Apacheのログを解析したい。

request-log-analyzer apache.log

rails ログと同様に解析した結果が出力されます。

 さまざまなオプション

入力オプション

–format, -f 解析するログのフォーマットを指定します。

  rails,rails3 rails のログとして解析します。

  apache apacheのログとして解析します。

  この他にも、merb,rack,delayed_job,amazon_s3,mysql,postgresql,oink,haproxy等を解析できるようです。

出力オプション

–output , -o 出力するフォーマットを指定します。

デフォルトだとコンソールに整形された文字列として出力されます。

   HTML HTML形式で整形された文字列として出力されます。

–file 指定したファイルに出力します。

–database,-d 指定したSQLite3形式のデータベースとして出力します。

詳しくは以下に載っています。あなたもこれでログ解析ライフを!

https://github.com/wvanbergen/request-log-analyzer/wiki

アマゾンウェブサービス(AWS)のアカウントを作成してみました。

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。KBMJ改めアピリッツの本多です。

最近仕事で利用しているAWSについての記事を書かせて頂きます。
今回は、アカウントの作成手順を紹介します。

■予め必要なもの

・クレジットカード
・有効な電話番号
・メールアドレス

1.アマゾンウェブサービスTOPにアクセス

http://aws.amazon.com/jp/

2.ページ右の「今すぐ申し込む」または右上の「サインアップ」をクリック


画像の赤枠のリンクです。

3.ログイン用のメールアドレスを入力してサインアップを開始


My e-mail address isの欄に自身のメールアドレスを入力し、
I am a new user.をチェックして「Sign in using our secure server」をクリック。

4.ログイン用の情報を登録


アカウント名及びログインするためのメールアドレス/パスワードを入力して「Continue」をクリック
My e-mail address isの欄には、先ほど入力したメールアドレスが予め入っている状態です。

5.利用者の個人情報の登録


お問い合わせ情報のフォームに住所、氏名、電話番号等を入力し、
利用規約に同意して「アカウントを作成して続行」をクリック。
注意点としては、氏名や住所等の情報が全て半角英数字で入力しなければならないという事です。
例えば“渋谷区”⇒”Shibuya-ku”みたいな書き方をしないといけないので、慣れない入力に戸惑うかもしれません。

6.クレジットカードの情報を登録


クレジットカードの情報を入力して「続ける」をクリック
請求先は5で登録した住所をそのまま指定する事ができます。

7.電話による身元確認を実施

なんと、AWSから実際に電話を受けて認証を行うシステムが導入されています。
おそらく一個人・団体がアカウントを大量に取得する事を防ぐための対策だと思いますが、ここまでやるかAmazonと関心しました。


国コードは”Japan(+81)”を選択し、電話番号(必要な場合は内線番号も)を入力して「確認用に自分に電話をする」をクリック。


しばらくするとAWSから電話がかかってくるので、案内にしたがって画面に表示されている暗証番号を通知する。


暗証番号の通知に成功すると、画面が↑のように切り替わって身元確認が完了します。
「続ける」をクリック。

8.確認画面に遷移し、AWS側の認証を待つ


認証が完了したら登録したメールアドレス宛に

「AWS Unified Registration Sign-Up Confirmation」

というタイトルで登録完了メールが送られてきます。
メールが届けば、AWSが利用可能になります。

あとがき

以上の手順で、AWSへのアカウント登録が完了しました。
英語での住所の入力や、電話を使っての身元確認はあまり他で見かけないため戸惑うかもしれませんが、
難しくは無いので頑張って挑戦してみてください。

次回は作成したアカウントを使って、Amazon EC2 Instanceの作成手順を紹介したいと思います。

Mysql(InnoDB)のロックの変化について

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

最近、MysqlでUpdate を行った際、更新対象件数によって、書き込みロックが行ロックからテーブルロックに変化することがあったので

その原因と対処方法について書こうと思います。

環境は下記の通りです。

OS: CentOS 5.6, MacOSX 10.7.3
Mysql 5.1(InnoDB)

↓のテーブルに、1000件レコードが存在すると仮定して説明していきます。

CREATE TABLE `sample_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `val` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ロックが行ロックからテーブルロックに変化する現象が発生するのは、

以下のSQL文です。

UPDATE sample_table SET val = "hoge" WHERE id in (100件分のid); => 行ロック
UPDATE sample_table SET val = "hoge" WHERE id in (500件分のid); => テーブルロック

ロックの変化の原因を探っていると、EXPLAINの結果に違いがあることがわかりました。

対象件数が100件の場合にはtypeがrangeなのに対し

対象件数が500件の場合にはtypeがALLになり、インデックスが使われていません。

対象件数 100件
EXPLAIN SELECT * FROM sample_table WHERE id IN (100件分のid);
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table            | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | products         | range | PRIMARY       | PRIMARY | 4       | NULL |  500 | Using where |
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+

対象件数 500件
EXPLAIN SELECT * FROM sample_table WHERE id IN (500件分のid);
+----+-------------+------------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table            | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+------------------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | products         | ALL  | PRIMARY       | NULL | NULL    | NULL | 1000 | Using where |
+----+-------------+------------------+------+---------------+------+---------+------+------+-------------+

このフルテーブルスキャンが原因でテーブルロックが発生していました。

ロックの変化についてMysqlリファレンスを調べたところ、下記のような記述がありました。

 MySQL では利用可能な場合でもインデックスが使用されない場合があることに注意し
てください。この一例として、インデックスの使用によって、MySQL がテーブルの 30% 
を超えるレコードにアクセスする必要が生じる場合が挙げられます(この場合は、必要な
シークが大幅に減少するため、テーブルスキャンのほうが高速になる可能性が高くなり
ます)。 ただしこのクエリに、レコードの一部のみを取り出す LIMITが使用されている場
合、結果で返される少数のレコードを迅速に検索できるため、MySQL はインデックスを
使用します。

上記を参考に、LIMITを付け加えることでインデックスが使用され、テーブルロックになることが防げました。しかし、速度が犠牲になる可能性があるため、使いどころは考える必要がありそうです。

10分ではじめるウェブサービス

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


よしだです。

今回は無料で使える PaaS「Heroku」を利用して、簡単にウェブサービスを作成、公開する方法を紹介します。

 概要

Heroku」は無料で使える PaaS です。

PaaS とは IaaS (一般的なVPS)をベースにしたもので、実用に不可欠であるウェブサーバや DBMS などを最初から備えているサービスを指します。PaaS を利用すれば「ちょっとしたウェブサービスを作って公開したい!」といったときに、自らサーバ構築を行う必要がなくなります。とくに「Heroku」は無料で利用することができ、さらに「サービスの人気向上に伴うサーバ強化」などのスケーリングが必要になった際にも、課金サービスを受けることで柔軟な対応が可能になります。

今回はこの「Heroku」の利用方法を紹介します。

 1. Heroku に登録

1. メールアドレスの登録

まずは Heroku のアカウント登録ページでメールアドレスを入力します。

https://api.heroku.com/signup

メールアドレスを登録すると下記の画面に遷移します。

https://api.heroku.com/signup/ok

2. メールの確認

Heroku から届いたメールを確認し、記載されている URL にアクセスします。

「Welcome to Heroku」と書かれた入力フォームが開かれます。

3. パスワードを設定

適当なパスワードを設定し、「Save」ボタンを押します。

Heroku への登録はこれだけでおしまいです。

次にクライアント側のセットアップに移ります。

 Heoku に必要なソフトウェアをセットアップ

1. git 、ruby、rubygems をインストール

今回はウェブサービスの作成に Ruby on Rails を使用することにします。

Heroku では Rails3 がサポートされているので、これに対応するソフトウェアをインストールします。

CentOS の場合:

# yum -y install git
# wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p290.tar.gz
# tar xvzf ruby-1.9.2-p290.tar.gz
# cd ruby-1.9.2-p290.tar.gz
# ./configure
# make
# make install
# cd
# wget http://rubyforge.org/frs/download.php/74619/rubygems-1.7.2.tgz
# tar xvzf rubygems-1.7.2.tgz
# cd rubygems-1.7.2
# ruby setup.rb
FreeBSD の場合:

# echo 'RUBY_DEFAULT_VER=1.9' >> /etc/make.conf
# cd /usr/ports/lang/ruby19
# make install clean
# cd /usr/ports/devel/ruby-gems
# make install clean
# cd /usr/ports/devel/git
# make install clean

2. Heroku のセットアップ

Heroku 専用のコマンドをインストールします。

# gem install heroku
# heroku keys:add
Enter your Heroku credentials.
Email: hyoshida@appirits.com
Password: 
Uploading ssh public key /home/hyoshida/.ssh/id_rsa.pub

 ウェブサービスのセットアップ

1. Rails のアプリケーションを作成

適当な名前のアプリケーションを作成します。

% rails new simple-sg

2. Heroku 向けに編集

ここは少し引っかかりやすいところになります。

Heroku では DBMS に PostgreSQL をサポートしているので、これに合わせた設定が必要になります。

% cp Gemfile /tmp
% vim Gemfile
% diff Gemfile /tmp/Gemfile
8,14c8
< group :preoduction do
<   gem 'pg'
< end
< 
< group :development, :test do
<   gem 'sqlite3'
< end
---
> gem 'sqlite3'
% cp config/database.yml /tmp
% vim config/database.yml
% diff config/database.yml /tmp/database.yml

3. 必要な gem のインストール

Rails アプリに必要な gem のインストールを行います。

今回は Rails 主題の話ではないので、細かい説明は割愛します。

% bundle install --path vender/bundle --without production

4. git の初期化

git に、作成したアプリケーションのファイル群をコミットします。

先ほど追加した gem のファイル群は、コミットする必要がないため除外しています。

% cd simple-sg
% git init
% echo 'vender/bundle' >> .gitignore
% git add .
% git commit -m 'first commit'

 Heroku にアップロード(デプロイ)

1. Heroku 上にアプリケーション枠を用意する

いよいよウェブサービスを公開していきます。

まずは適当なアプリケーション名を Hroku に登録します。

% heroku create simple-sg
Creating simple-sg... done, stack is cedar
http://simple-sg.herokuapp.com/ | git@heroku.com:simple-sg.git
Git remote heroku added

2. リモートリポジトリを追加する

1. で出力された内容を元にして、git にリモートリポジトリを追加します。

% git remote add heroku git@heroku.com:simple-sg.git

3. デプロイする

下記のコマンドで git のコミット内容をリモートリポジトリに反映させるだけで、Heroku 上にウェブサービスが立ち上がります。

% git push heroku master

 おわりに

少し早足になりましたが、このように簡単にウェブアプリケーションをはじめることができます。

次回は、Heroku 上に簡単なソーシャルゲームを作成する手順について紹介したいと思います。

タッチイベントを用いたスワイプ&フリックの実装サンプル

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

スマートフォンのタッチイベントを用いて、画像を横方向にスライドさせる実装をご紹介します。

※PCではマウスイベントで代用可能だと思われます。

※Android/iPhone両方で動作するはずです。

ポイントとしては、スワイプとフリックの動作です。

スワイプ

画面をタッチした状態で指を動かす動作

フリック

画面をタッチした状態で指を「素早く動かす、弾く」動作

この2つの動作を組み込むことで、ネイティブアプリのようなスムーズな動きが実現できます。

 sample.css

body {margin:0;padding:0;}

#slider {
    position: relative;
    width: 320px;
}

#slider a:focus {
    outline: 0;
}

.slider-view {
    position: relative;
    border: 1px solid #bbb;
    width: 320px; /* スライダーで表示するエリアの大きさ */
    height: 360px;
    overflow: hidden; /* 必須 */
}

.slider-container {
    position: absolute;
    top: 0;
    left: 0;
    background-color: black;
	width: 2000px; /* 本来はコンテンツの横幅を取得して動的に設定すべきです */
}

/* スライドするコンテンツ部分 */
.slider-container div {
    position: relative; /* ループ処理に使う */
    float: left;
}

/* チラツキ対策 */
.slider-container {
  -webkit-transform:translate3d(0,0,0);
}

 sample.html

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
  <title>Sample</title>
  <script src="/assets/jquery.js" type="text/javascript"></script>
  <script src="/assets/sample.js" type="text/javascript"></script>
  <link href="/assets/sample.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="slider">
  <div class="slider-view">
    <div class="slider-container">
      <div id=1><img src="/images/01.jpg" /></div>
      <div id=2><img src="/images/02.jpg" /></div>
      <div id=3><img src="/images/03.jpg" /></div>
    </di>
  </div>
</div>
</body>
</html>

sample.jsではjQueryを利用しているので、jQueryをロードしておきます。

※HTMLタグは都合上全角になっております。実際は半角です。

 sample.js

$(function () {

// 対象となる要素を変数に格納しておく
var $slider     = $('#slider'),
    $container  = $slider.find('div.slider-container'),
    $containerDiv = $slider.find('div.slider-container div');
var distance = 0;    //移動距離を指定するのに使う

// スライド関数
var slide = {
  
  // スライド(進む)
  next: function (index, spd, flick_flg) {
    distance = distance + index;
    slide.scroll(distance, spd, flick_flg);
  },
  
  // スライド(戻る)
  prev: function (index, spd, flick_flg) {
    distance = distance - index;
    slide.scroll(distance, spd, flick_flg);
  },
  
  //移動距離分スクロール
  scroll : function (d, spd, flick_flg) {
    var move = -d
    var env = 'translate3d(' + move + 'px,0,0)';
    
    if (flick_flg) {
      /* フリック時はwebkit-transformプロパティを設定し、滑らかなアニメーションにする */
      transit_property = '-webkit-transform ' + spd + 'ms cubic-bezier(0,0,0.25,1)';
    } else {
      transit_property = 'none';
    }
    
    $container.css({
      '-webkit-transform':env,
      '-webkit-transition':transit_property
    }).bind('webkitTransitionEnd', function(){
       //ここで移動後の終了イベントが取れます     
    });
  }
}

$(window).load(function() {
  var pageX;      //リアルタイムのX座標
  var pageY;      //リアルタイムのY座標
  var startPageX; //スタート時のX 座標の位置
  var startTime;  //スタート時の時間
  var move_time = 0;
  
  /* タッチの開始時のイベント */
  $('#slider').bind('touchstart', function() {
    event.preventDefault();     // ページが動いたり、反応を止める(A タグなど)
    pageX = event.changedTouches[0].pageX;
    pageY = event.changedTouches[0].pageY;
    startPageX = pageX;
    startTime = +new Date();
  });
  
  /* タッチしたまま動かしたときのイベント */
  $('#slider').bind('touchmove', function() {
    var moveX = event.changedTouches[0].pageX; // X 座標の位置
    var absX = Math.abs(pageX - moveX); // 移動距離の絶対値
    var spd = 0.5;
    pageY = event.changedTouches[0].pageY;
    
    /* スワイプ処理 */
      if (pageX > moveX) {
        slide.next(absX, spd);
      } else if (pageX < moveX) {
        slide.prev(absX, spd);
      }
      pageX = moveX;
  });
  
  /* タッチ状態から離れたときのイベント */
  $('#slider').bind('touchend', function() {
  	/* 終了処理が必要ならここに書く */
    /* このイベントは、位置を取得できないので注意 */
    
    var diffX = startPageX - pageX;
    var absX = Math.abs(diffX);
    var mv = 200; //フリック移動距離
    var spd = 700; //フリックスピード
    var now = +new Date(); //現在時間
    var diffTime = now - startTime; //touchstartからの経過時間

    /* フリック処理(touchstartからの経過時間が短い場合) */
    if (diffTime < 400) {
      if (diffX > 0) {
        slide.next(mv, spd, true);
      } else if (diffX < 0) {
        slide.prev(mv, spd, true);
      }
    }
    
    move_time = 0;
  });
});
});

スワイプかフリックかの判定は、touchstart(タッチした瞬間)からtouchend(離した瞬間)までの時間で判定します。

上記サンプルでは400ミリ秒未満の場合はフリックと判定するようにしています(diffTime < 400)

以上です。スワイプとフリックでネイティブアプリのような動きを実現しましょう!

CentOS disk容量 dfとduの値の違い

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rick No26です。
ついこの間、サーバの容量が圧迫されduコマンドなどで調べても全然使用していないのにdfでみると使用率80%近くいっていたことがあったので、解決方法を紹介します。

環境

CentOS 5.4

dfの値

# df -h
Filesystem サイズ 使用 残り 使用% マウント位置
???秘密???    113G  83G  24G  78%    /
・・・省略・・・
???秘密???     379G  220G  140G 62% /var
これを見ていただくと
「/」と「/var」で約300G使用していることになる。

duの値

# du -h /
これで出てきた最後の「.」は、235Gだった。

疑問

「/var」をduすると220Gで合っていた。
それ以外をduすると、全部で15Gしかなかった。
確かにduで「/」から行った時の合計は235Gだ、
だが、dfで行った時の合計は300G近く、
「/var」があっているので「/」がおかしい、
83Gと15G、、、68Gはいったいどこで使用されているのか?

原因

どうやら削除しても削除しきれていないファイルデータがあるらしい。
# ls -al /proc/*/fd/* | grep deleted
これで出てきたものが削除しきれていないファイルです。
このログをみて、ファイル移動したなとか、プロセス強制終了したなとか思い当たるフシがあるはずです。
そのファイルを操作しているアプリを再起動してみてください。
「/」のdisk使用量が一気に下がるはずです。
自分の場合は、40G程一気に解放されました。

以上、困った時の参考になると幸いです。

鍵がカギで無くなる日

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

先日、米国で開催された「Hackers on Planet Earth 2012」で、とあるデモが行われた。

このデモは、3Dスキャナと3Dプリンタを用い、カギを複製する物だった。

3Dプリンターは、安い物では10万円前後で買うことが出来、1つあたりのコストもわずか数十円とお手軽である。大きな物を作ることは出来ないが、手のひらサイズなら問題なく作成できる。この3Dプリンターは、底辺から輪郭を含めて、すべてを「印刷」することで、オブジェクトを作成する。こうして作成されたオブジェクトは、通常の彫刻や削りでは再現することが難しい、完全につなぎ目の無いモノを作成することが出来る。

次に、3Dスキャナー*1だが、見たモノを見たままに、3Dとして記憶することが出来る。このプリンターと先ほどの3Dプリンターを用いることで、完全にうり二つのモノを作成することが容易に出来る。

 カギの脆弱性

カギが物理形状を成している以上、3Dプリンターの前では、なすすべが無い。

たとえば、ピッキング対策として、採用されているディンプルキーと呼ばれるカギですら、3Dプリンターと3Dスキャナーを組み合わせれば、いとも簡単に同じモノを複製することができる。もはや、物理形状の複雑さだけでは、家を守ることが出来なくなっているのかもしれない。3Dプリンターといえども、磁気情報やIC情報、電波などの物理的に見えるモノ以外の情報を複製できない。もし、真剣に守りたいなら、ディンプルキーではなく、ICカードや磁気カードなどを複数組み合わせたモノを採用する必要が出てくるのかもしれない。

 日本独自のカギ文化

日本独自と言っても過言では無いカギがある。それは、多くの金融機関で採用されており、他国ではほぼ採用されていないもの。そう、印影である。

印影が一致しない限り、現金を引き出すことが出来ない。逆に言えば、印影が一致すれば、現金を引き出すことが出来るもの。それが印影で有り、印鑑だ。通常、印影は印鑑と対になっており、「印鑑をお持ちください」と言われれば、すなわち「印影」を示すことが多い。こうした印影は、当然のように3Dプリンターと3Dスキャナの前では、為す術無く複製されてしまう。欧米のように、簡単には複製できない、筆圧や書き順などに対応した、署名に移行する時期も近いのかもしれない

*1: 安いモノで、300万円ほどする

Rails migrationでbigint型のidカラムを作成

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Railsのmigrationでbigint型のカラムを作成する方法です。

Rails3.1.3, Postgresql 9.1.0 にて確認。

Railsではmigrationのadd_columnでprimary_keyオプションを指定すると、自動でシーケンステーブルとオートインクリメントの付いたカラムを作成してくれます。

class AddColumnIdToUsers < ActiveRecord::Migration
  def up
       add_column :users, :id, :primary_key
  end

  def down
    remove_column :users, :id
  end

end

ですが、これでは型がintegerになってしまいます。型を変更するオプションなども無いようです。

bigintでカラムを作成するため、SQLを直接発行することにします。

class AddColumnIdToUsers < ActiveRecord::Migration
  def up
    execute <<-SQL
      ALTER TABLE users ADD COLUMN id bigint DEFAULT nextval('users_id_seq') PRIMARY KEY;
    SQL
  end

  def down
    remove_column :users, :id
  end

end

Postgresqlでのシーケンステーブルは以下のように作成できます。

class CreateUsersSeq < ActiveRecord::Migration
  def up
    ActiveRecord::Base.connection.execute("create sequence users_id_seq;")
  end

  def down
    ActiveRecord::Base.connection.execute("drop sequence users_id_seq;")    
  end
end

AndroidでGoogle Mapsを表示

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

AndroidでGoogle Mapsを表示するための方法をご紹介します。

 Maps APIキーの取得

Android上でGoogle Mapsを使用するためにMaps APIキーが必要です。

その際、Googleのアカウントと証明書が必要となります。

証明書はデバッグ用のものが以下の手順で取得できます。

$ keytool -list -keystore ~/.android/debug.keystore
...
Certificate fingerprint (MD5): 94:1E:43:49:87:73:BB:E6:A6:88:D7:20:F1:8E:B5:98

パスワードを聞かれますが、入力せずにEnterを押します。

次に以下のサイトにアクセスします。

Android Maps API Key

規約確認のチェックボックスをONにし、

先ほど出力したフィンガープリントを入力して、「Generate API Key」ボタンを押すと、

Maps Keyを取得できます。

 Google APIsインストール

Android Mapsを使用するためにはGoogle APIを使用します。

プロジェクト作成時のビルドターゲットに「Google APIs」が無い場合は、Android SDK and AVD Managerでインストールしてください。

※Google APIsはプラットフォーム別に複数あるので、開発に使うプラットフォームのものは必ずインストールします。 まあ全部インストールしちゃってもいいと思います。

1. Android SDK and AVD Managerを開く

(開発にEclipseを使用している場合は、[ウィンドウ] – [Android SDK and AVD Manager] などで開けます)

2. Available PackageでインストールするGoogle APIsにチェックを入れる

3. [Install Selected]をクリックしてインストール

 AVDの作成

Google APIs用のAVD(Android Virtual Device)を作成しておきます。

Google APIsをインストールした時と同じようにAndroid SDK and AVD Managerで作成します。

1. Android SDK and AVD Managerを開く

(開発にEclipseを使用している場合は、[ウィンドウ] – [Android SDK and AVD Manager] などで開けます)

2. Virtual Devicesで[新規]をクリック

3. 「名前」は適当なものを入れ、「ターゲット」には開発で使用するGoogle APIsのプラットフォームを入力して、[Create AVD]をクリック

 サンプルプロジェクトの作成

最後に簡単にGoogle Mapを表示するためのサンプルプロジェクトを紹介します。

新規プロジェクトの作成では、ビルドターゲットに先ほどインストールしたGoogle APIsを選択します。

package com.exapmple.androidmaps2;

import android.app.Activity;
import android.os.Bundle;

import android.os.Bundle;
import com.google.android.maps.*;
 
public class AndroidMaps2 extends MapActivity {
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MapView map = new MapView(this, "[Android Maps API Key]");
        map.setEnabled(true);
        map.setClickable(true);
        setContentView(map);
    }
 
    @Override
     protected boolean isRouteDisplayed() {
        return false;
    }
}

[Android Maps API Key]に準備で取得したAndroid Maps API Keyを入力して下さい。

AndroidManifest.xmlは下記のようになります。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.androidmaps" android:versioncode="1" android:versionname="1.0">
    <uses-sdk android:minsdkversion="1.5" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".AndroidMaps" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
		 <uses-library android:name="com.google.android.maps" /> ←追加
    </application>
    <uses-permission android:name="android.permission.INTERNET" /> ←追加
</manifest>

これでGoogle Mapが表示されます!

リアルタイム多人数じゃんけんゲーム「JANG Battle」をリリースしました

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

 概要

  • Node.js+socket.io+expressアプリはとっても簡単
  • herokuにデプロイしたら予想外のところで詰まった
  • 格闘ジャンケンゲームJANG Battle!みんな遊んでね!

 リアルタイム通信するアプリを作ったことありますよね

 こんにちは,Rails厨のわたなべ(hackugyo)です.

 ところでみなさんはNode.jsって知っていますか.Node.jsのヴァージョンを管理するソフトにナベっていうのがあるんですが,私はワタナベなのでライバル視しています.

 node.js+Socket.IOのNon-blockingI/O環境を見ると,一刻も早くリアルタイムに通信するアプリを作りたくなりますよね.私もそうです.ざっと見たところ,リアルタイム通信ときいて一番にみなさんが思いつくのはチャットアプリのようで,node.jsの前開発リーダRyan Dahlさんもgithubでサンプルを公開されています(https://github.com/ry/node_chat).

 私も学習のためにチャットアプリを作ろうと思ったのですが,リアルタイム通信といえばゲームだよなと思い直し,途中から格闘ゲームに切り替えて作りました.といっても中身はほとんどチャットで,パンチ・ガード・ジャンプキックの3つのうちどれかをコマンド選択して,相手のコマンドとの相性で勝敗を決めるという,簡単なものです.

こちらがアプリです

 対戦格闘じゃんけんゲーム

 JANG Battle!!

  1. ぐー・ちょき・ぱーから手を選びます
  2. 他のプレイヤの選んでいる手に勝っていれば,1点ゲット
  3. 連打によってどんどん点を稼げます
  4. 他のプレイヤがリアルタイムに手を変えるので,同じ手を連打していても勝てないかもしれません
  5. 20点とったら勝ちです

 このアプリの作成にあたっては,ゲーマの友人の今井晋さん(facebookページ)より企画・アイデアをいただきました.貴重なアイデアを無償で公開していただき感謝します.

 勝敗判定など,今後もアップグレードを続けていきます!

(ソースもこちらで公開します.https://github.com/hackugyo/ChatJangBattle

 ヘロクにデプロイする

 さて,せっかく作ったのですから,localhostで動かすだけでなく,公開してみんなに遊んでもらいたいものです.チャットアプリもそうですが,リアルタイム通信の面白みを知るにはやはり多くのクライアントをさばく様子を見たいわけです.ましてや今回は対戦型格闘ゲームを作ってしまったので,ひとりで複数タブからパンチ……ガード……していてもむなしいだけです.

 最近は恐ろしいことに,Paasなホスティング環境が無料でたくさんそろっています.DotCloud, Cloud Foundry, OpenShift, Node Ninja, Nodejitsu, etc.(node.js対応のホスティング環境の一覧はこちらにまとまっています).いまやWebアプリを試すのにも,localだけで満足する理由はほとんどなくなりました(セキュリティまわりの問題はありますが).さあ,どこにホスティングさせてもらいましょうか?

 さあ,私はRails厨なので、ここでもちろんHerokuを選びます.HerokuはRubyの作者まつもとゆきひろ氏をチーフアーキテクトに迎えるなど,Rubyに対しなみなみならぬ優しさをもったプラットフォームです.言語としてはほかにもScala, Java, Pythonなどにも対応しており,もちろんnode.jsもOKです.

herokuデプロイ時の注意

masterブランチをpushすること

 gitを利用し,ふだんのヴァージョン管理とほとんど変わらない気軽さでデプロイできるのが,Herokuの大きな魅力ですが,ここにはちょっとした心理的落とし穴があります.

 私は最近,gitのブランチモデルについて勉強し,release / develop / featureなどのブランチをごりごり切り替えて使っているのですが,その影響で,herokuに大してもうっかり

$ git push heroku release

とreleaseブランチをpushしてしまったのです.これではさしものherokuも理解してくれません.ここは,正しくは

$ git push heroku relase:master

とすべきでした.あるいは,おとなしくmasterブランチをrelease目的に使ってもいいでしょうね.

ポート番号には注意

 ローカル環境でWebアプリを試して,それをherokuにデプロイする場合,気をつけたいのはポート番号の設定です.ほかにも,Procfileを書くなどの追加点はありますが,既存のソースに手を入れるのはつい忘れがちです.

 さて,ローカル環境で試したWebアプリには,主に2カ所,ポート番号を書いているところがあります.

  1. サーバサイドのjs
  2. クライアントサイドのjs

 あたりまえですね.

 サーバサイドは簡単です.app.jsのここを

var port = 5000;
app.listen(port, function(){
  console.log("Express server listening on port %d in %s mode", 
    app.address().port, app.settings.env);
});

こう変えるわけです.

var port = process.env.PORT || 5000;
app.listen(port, function(){
  console.log("Express server listening on port %d in %s mode", 
    app.address().port, app.settings.env);
});

これで,herokuデプロイ時にはprocess.env.PORTの値が使われるようになります.(デフォルトポートが5000なのは,foremanというマネージャに合わせたためです)

 問題はクライアントです.jadeからclient.jsを切り出したのはいいのですが,その中でこういう記述をしていました.

var socket = io.connect('http://localhost:5000/chat');

// 一覧表示要請を検知し,ログを表示する
socket.on('chat.list', function(list) {
  ...
});

ソケット接続を要求するためのコードですが,ポート5000がまるのまま出てきていますね.io.connectを使った書きかたは,node.jsのv0.7以降で登場したものだそうで,ネットを見てもあまり情報がありません.

 ここは素直にこう変えます.

var socket = io.connect('/chat');

// 一覧表示要請を検知し,ログを表示する
socket.on('chat.list', function(list) {
  ...
});

これで,ポートやホスティング先URLに関係なく,正しい接続要求をすることができます.

 みなさんもnode.jsでherokuに楽しいアプリを作ってください!

 ご参考

  1. herokuへのnode.jsアプリのデプロイについては,本家ブログに記事があります. https://devcenter.heroku.com/articles/nodejs
  2. node.jsじたいの解説は, Web+DBPRESS vol.58(技術評論社, 2012)の特集”Node.js実践入門”がたいへん参考になります.著者は名村卓(@snamura)さんです.
  3. チャットアプリのUIについては,いくつもライブラリが公開されています.最近だとBaloons.IOなどかっこいい. https://github.com/gravityonmars/Balloons.IO
  4. テンプレートエンジンにはexpressのデフォルトのJadeを使いました.こちらのコンヴァータは便利:http://html2jade.aaron-powell.com/
  5. 開発環境はEmacsでしたが,Nideもちょっと触りました.面白いですね.http://coreh.github.com/nide/

ここ最近使ってみたiOSのライブラリまとめ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

最近になって仕事としては約1年ぶりにiOSアプリの開発をしております。

その間にiOSが5になったり、iPhone4Sが出たりと状況が変わっており一瞬浦島太郎気分を味わったり、そんな自分がここ最近触ってみたiOSのライブラリを紹介したと思います。

 AFNetworking

https://github.com/AFNetworking/AFNetworking

ネットワーク用のライブラリです。今までネットワークのライブラリはASIHTTPRequestを使っていましたが、開発が止まってしまい、新たな案件で使い続けるのも不安だったのでこっちに乗り換えてみました。

通信終了後の処理をブロックで書けるのが何気に便利ですね。

XMLやJSONをダウンロードするためのクラスも用意されております。

JSONをJSONKitと組み合わせて使ってみましたが、特に意識することなくダウンロードしたJSONをNSDictionary、NSArrayの形で展開してくれてすごく便利でした。

 SVProgressHUD

https://github.com/samvermette/SVProgressHUD

ライブラリを取り込んで、下の1行を書くだけでクールなインジケータを出すことができます。

[SVProgressHUD showWithStatus:@"ダウンロード中" maskType:SVProgressHUDMaskTypeGradient];

 OHAttributedLabel

https://github.com/AliSoftware/OHAttributedLabel

これを使うと下のように1つのラベルで色を変えたり、文字のサイズを変更したり、リンクを貼ることが出来ます。

コードはこんな感じです。

    NSString *text = @"赤文字、青文字、大文字、太字、http://doruby.kbmj.com/";
    NSMutableAttributedString *attrStr = [NSMutableAttributedString attributedStringWithString:text]; 
    [attrStr setTextColor:[UIColor redColor] range:[text rangeOfString:@"赤文字"]];
    [attrStr setTextColor:[UIColor blueColor] range:[text rangeOfString:@"青文字"]];
    [attrStr setFont:[UIFont systemFontOfSize:16] range:[text rangeOfString:@"大文字"]];
    [attrStr setFont:[UIFont boldSystemFontOfSize:12] range:[text rangeOfString:@"太字"]];
    _label.attributedText = attrStr;
    [_label addCustomLink:[NSURL URLWithString:@"http://doruby.kbmj.com/"] inRange:[text rangeOfString:@"http://doruby.kbmj.com/"]];

一つのラベルで色を変えたり、リンクを貼ることが出来たり便利なライブラリですが、いくつか何点もありました。

  • iOS5でテーブルビューのセルで使うとカクカクになりやすい。
  • 複数行表示させると標準のUILabelに比べて行間が広い。

売買される個人情報

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

皆さんは、自分の個人情報について、どれくらい気を使っているだろうか。その昔、メールと名前、性別がセットで1件当たり○○円で売買しているなんて記事が、ネットに流れたこともあった。現在は、そういったセット販売の価格が暴落し、単純に1件でいくらという価格出はなくなりつつあると聞く。

 売買される個人情報の価値

まず、売買される個人情報について考えてみよう。売買される個人情報には、いくつかのランクがあり、まず、単なるメールアドレスだけの場合。これはほとんど無価値と呼ばれており、数十万レコード有ったとしても、その価値は高くても数千円止まり。下手をすると、数百円ってこともある。これは、そのメールアドレスが本当に現在も使われているか(流通しているか)が確定していないためだ。もし、これが、すべて使われている場合は、10倍程度の価値がつく。ただし、本当にすべてのメールアドレスが使われていれば・・・の話だ。また、それがフリーのメールアドレスなのか、それとも、企業が使っているメールアドレスかによっても、価値が変わる。もし、企業が使っているメールアドレスの場合、おいそれと変更するわけにいかず、使い続ける可能性が高い。逆に、フリーメールの場合は、簡単に変えられるため、使い続ける可能性が低く、大量に迷惑メールを受信した場合は、そのメールアドレスを捨てる可能性が十分に有る。そのため、企業とフリーのメールアドレスでは、その価値が大きく異なる。ただし、メールアドレスだけでは、先ほども書いた通り、あまり価値はなく、それ以外にヒモ付けされたものがあれば、その価値はぐっと上がる。

先ほど、企業のメールアドレスの場合は、価値がフリーアドレスに比べ、高いと書いたが、これは変更されない事と、もうひとつ理由がある。それは、その企業に属していることがほぼ確定しているためだ。.co.jp の場合、その企業に属しているもしくは、何らかの関係者であるため、個人を特定しやすい。たとえば、katayama@appirits.com といった場合、「アピリッツに勤めている片山」さんとわかるわけだ。このように、個人を特定する事ができる情報はきわめて価値が高い。これに、クレジットカード情報と性別、電話番号が含まれていれば、1件あたり10円前後の価値があるかもしれない。1件10円と聞くと、あまり価値がないように感じられるかもしれないが、数万件集めれば、ちょっとした小遣い稼ぎになる。

先ほども述べたように、個人を特定する情報は価値が高いが、逆に個人を特定できない情報はあまり価値がないと書いた。最近では、買い取り時には金銭が発生しないケースが有る。このケースでは、どんな状態(情報)で有っても、個人情報を渡す際には一切の金銭授受が発生しない。では、どのように行うかというと、アフィリエイト型と呼ばれる方法だ。この方法では、先ほどのように、1件いくらといった相場は存在しない。たとえば、Aさんの情報を含んだものを、アピリッツ商事に私が渡したとする。この時点では、金銭授受が発生しない。Aさんがアピリッツ商事で100万円の買い物をするとする、買い物額の25%である、25万円が私の懐に入る。Aさんが、アピリッツ商事で買い物をし続ける限り、延々と私の手元には、購入金額に応じ数%〜20%前後が振り込まれる。個人情報を渡した時点で金銭授受が発生しない分、売り逃げはできないが、システム上いくらの売り上げが有ったのかを確認することができ、そして、いくらの振り込みが有るのかを確認することができるため、個人情報の売り手にとって非常においしい仕組みになっている。仮に、渡した個人情報が10万件有ったとして、そのうち1%、つまり、1千人が、毎月1万円の買い物をした場合、何もしなくても、毎月25万円の小遣いだ。

とはいえ、10万件ものメールアドレスや個人情報を集めるのは、相当骨の折れる作業だ。しかも、目の前に有るような個人情報をわしづかみにして、売り払うと、某証券会社のような状態になりかねない。しかも、売却額よりも損害賠償額の方が、はるかに大きい状況では、割に合わない。そこで、個人情報を集めてる人に聞いた、さまざまな方法を書いて見よう。

 マルウェアを用いる方法

世の中には、マルウェアを自分好みにアレンジしてくれるサイトがいくつかある。マルウェアに感染させ、中に含まれるさまざまな情報を、根こそぎ奪ったり、キーロガーを仕掛けて、さまざまな情報を抜く方法も有る。特に、銀行や証券会社のIDとパスワード、名前セットは非常に高く売買されている。

 メールサーバ の仕様上の問題を突く

メールサーバには、受け入れられるメールアドレスをメール本文を送信する前に送信者に返答する仕様が有る。辞書を使って、大量に存在していると思われるユーザを片っ端に調べることで、その企業やISPに所属しているメールアドレスを大量にかつ確実に入手することができる。

 SQLインジェクションを用いる

最近、中国や韓国から、日本のネットショップが狙われている方法だ。それも、かなり自動化されており、ほぼ100%人が介在していない。最も今用いられている方法の一つだ。

 同業他社の情報をいただく

こういった情報を収集している企業は数多く存在している。そういった企業のサイトには、セキュリティ対策が施されておらず、簡単にgoogle や yahoo などの検索エンジンに引っかかるケースがある。こういった情報をもとに、効率良く情報を取得する方法も有る。

大量の個人情報を集めたら、それを、適切なフォーマットに並び替え、CD-RやUSBメモリなどに入れて、顧客に渡す。メールを用いても良いのだが、足が付いてしまう危険性があるため、フリーのwebメールで、多段串を経由するか、複数の国外踏み台を経由してのアクセスなど、よほど入念に対策を施した状態でなければ、メールで送信することは無い。

今回は、筆者が複数の関係者から聞いた話をまとめて書いた。個人情報がどのように売買されているのか、少しは興味を持ってくれただろうか。くれぐれも、加害者、被害者ともに、ブラックマーケットに関わることの無いように。といっても、被害者になってることすら、気づかないんだけどな。

最近人気な記事