非エンジニアのエンジニア道

非エンジニアからエンジニアに転向!その勉強の軌跡を載せていきます。

windowsのファイルをCentOSへmount

ずっとlinux(ゲスト)側で作業をしてたんだが、もろもろ困ったことになったので、
ソースコードをwindows(ホスト)側に移動して、mountした。

インストール

linux側で行う。
二つ目をインストールし損ねていて、エラーでかなり時間をくってしまった…。

# yum install samba-client
# yum install cifs-utils

windows側の設定

該当のフォルダを共有設定に変更。

windowsユーザー作成

パスワードが必要なので、新しくユーザーを作っておく。

マウントする

IPアドレスは、linux側から見たwindowsのIPで、/etc/resolve.conf 参照。

# mount -t cifs //192.168.XXX.XXX/windows該当ディレクトリ/ /マウント先ディレクトリ/ -o username=ユーザ名,password=パスワード


無事マウントできました。
これからwindows側で作業。

本を読む データベース技術[実践]入門

時間が空いてしまった!
いろいろやったけど、まとめてなかっただけなのだっ!

というわけで、本読んだことをいろいろまとめよう

感想

何となく使ってたもの、少しだけわかった気がする!
なるほどねっ!といった感じ。

直接これを見て、何かしたわけじゃないから、
具体的にできるようになったわけじゃないけど、活かせればなぁと思う。

一部ちょっと半分くらいしかわかってないところもあるので、まとめながら復習。

ざっくりメモ

ランダムアクセス

遅い

正規化

テーブル設計では正規化する

データベースが重い

だいたい効率の悪いSELECT文のせい
複数回SQL文を発行するより、joinしたほうが高速

障害の主な原因

  1. ソフトウェアの障害
  2. OSの障害
  3. ハードウェアの障害
  4. 操作ミス

ロックによる排他制御

InnoDBの場合は、ロックの範囲がレコードだが、MyISAMではテーブル単位になるため、InnoDBの方が並列性の向上に大きく貢献している。

ストレージ技術の進化

ボトルネックが、ディスクからCPUやネットワークに移ってきている。
また、並列性能の高いデータベースが求められる

ストレージエンジン

mysqlの特徴で、さまざまなレコード処理の実装方法が用意されている。

リストア

バックアップしたデータを使ってリカバリ処理をする際、MySQLから読み書きできる状態にすること

インデックス

検索を劇的に高速化できる。
ただし、インデックスを別途更新する必要があるので、更新コストは増える。
そのため、必要なものだけにつけること。

ハッスインデックス

ハッシュ値とキーのペアを持つ構造。
ハッシュ値は同じサイズになるので、固定長フォーマットに持ち込める。
ハッシュ値が衝突しないような機能はデータベースに実装されている。
ただし、範囲検索等、向かない検索処理がある。

B+Treeインデックス

効率よく、目的のデータを取得できる。範囲検索も効率的に行える。
ルートブロックを頂上にもち、ブランチブロック、最下位のリーフブロックがならぶ木構造。
ルート、ブランチでは、下位の対象のブロックがどこにあるのかという情報をもち、リーフでは、実際の格納位置の情報をもつ。

その他

インデックスを一意性の保証としても使える(一意性を保証したい列にインデックスをつけることが必須となっている。)。
低コストで重複チェックが可能。
また、AND条件で、インデックスを作ることも可能。
インデックスマージ(2個以上のインデックスを同時に使える)機能も存在する。

冗長化

最も広く用いられているのがレプリケーション

片方向レプリケーション

マスタに更新した結果が、スレーブに非同期で、伝播する。
スレーブでは、バイナリログの受信と実行の2ステップが存在する。


マスタ障害時、スレーブに結果が反映されてない状況は、2パターン存在。
バイナリログが最後まで、受信できてない、バイナリ実行ログが最後まで終わってない。


前者は非同期のため起こり、後者はSQLスレッドが遅延しているため起こる。

2ステップをそれぞれ同期方式にもすることはできる。ただし、レスポンスタイムは悪くなる。

双方向レプリケーション

マスタを複数もたせて、それぞれのマスタを更新できるようにする。
ただし、不整合が発生しないようにするため、分散型排他制御のしくみが必要。

トランザクション

データが中途半端な状態で更新を確定せず、ロールバックしたり、耐障害性を向上できる。
更新時のロックは、トランザクションの終了まで保持される。
ACID特性を持つ

  1. Atomicity:原子性  複数のSQL文をまとめて、1つの処理単位にできる
  2. Consistency:一貫性 複数デーブルにまたがる更新でも、片方だけ更新されるような矛盾した状態にならない
  3. Isolaction:独立性  参照、更新が競合しても、矛盾した状態にならないように排他制御が可能
  4. Durability:耐久性  コミットした結果は確実に保存され、復旧が可能

MySQLのログファイルの種類

エラーログファイル

MySQL本体のプロセスの起動/停止の情報、エラー情報を出力する。

スロークエリログファイル

実行に一定時間以上を要したクエリを出力する。

一般ログファイル

実行されたSQL文のすべてを出力する。

バイナリログファイル

アプリケーションからはこうされた更新系のSQL文が記録される。上記3つは解析用だが、これはリカバリやレプリケーションなどに利用されるクリティカルなファイル。

NoSQL

SQL文のような複雑な命令はなく、またテーブルのオープンクローズのコストを皆無にし、競合を減らし性能をあげている。

欠点として、トランザクションをサポートしていない、スキーマがない、主キー以外のインデックスを使えない。

最も使われる用途は、キャッシュとして使うこと。また、セッションデータでも使われる。

Zend Framerorkを使う その3

データベースを使う

mysqlを組み込む。mysql自体はインストール済。

Zend_Db_Table_Abstract

これを使うために、index.phpに追記

<?php
require_once 'Zend/Db.php';
$params = array(
        'host'     => '127.0.0.1',
        'username' => 'fuga',
        'password' => 'hoge',
        'dbname'   => 'dbname',
        'charset'  => 'UTF8'
);
$db = Zend_Db::factory('PDO_MYSQL', $params);
Zend_Db_Table_Abstract::setDefaultAdapter($db);

modelで実際に使う

insertを取り急ぎ作る

<?php

class ShioriMain extends Zend_Db_Table_Abstract
{
    protected $_name = 'shiori_main';
}

class MainEdit
{
    public function addData($title, $thema, $startDate, $endDate, $member)
    {
        $shiori = new ShioriMain();
        $data = array(
            self::COLUMN_TITLE => $title,
            self::COLUMN_THEMA => $thema,
            self::COLUMN_START_DATE => $startDate,
            self::COLUMN_END_DATE => $endDate,
            self::COLUMN_MEMBER => $member,
            self::COLUMN_CREATE_AT => new Zend_Db_Expr('NOW()'),
            self::COLUMN_UPDATE_AT => new Zend_Db_Expr('NOW()')
        );
        $shiori->insert($data);
    }
}

エラー

The mysql driver is not currently installed

実際に動かそうとしたら、エラー
あらま!というわけでなおす

拡張モジュールのインストール

# pecl install pdo_mysql

phpize: コマンドが見つかりません

動きません。

ビルドツールインストール

phpizeは、phpの拡張モジュールのためのビルドツール
それがないので、インストール

# yum -y install php-devel

# pecl install pdo_mysql
configure: error: mysql_query missing!?

再度、peclを実行したが、エラー・・・


開発用モジュールインストール

mysql開発用モジュールがインストールされていないので、インストール

# yum -y install php-mysql-devel
# yum -y install mysql-devel

# pecl install pdo_mysql

今度は成功!

php.iniに追記

extension=pdo.so
extension=pdo_mysql.so

apache再起動で、上記insertが動きました!

modelでselectもついでに試す

<?php
    public function getShioriData($id)
    {
        $shiori = new ShioriMain();
        $select = $shiori->select()
                ->where('`' . self::COLUMN_ID . '` = ?', $id);
        $result = $shiori->fetchRow($select);

        if(empty($result) === false) {
            $result = $result->toArray();
        }

        return $result;
    }

動いた動いた。おめでたい。

本を読む Webを支える技術

本を読むのがすごく苦手なので、なかなか読めなかった本をやっと読み終わった。
通勤を利用して何とか読んだ。


買ったのは大分前だったけど、何やらわからない用語が多すぎて一旦放置してた。
通勤時間が伸びたのを利用して、がーっと読んだら、意外と読めた。


というわけで、まとめてみる。

感想

webすげー!


その一言につきました。
とても本を読んだ感想っぽくないw


知らないと知らないままの、技術。
既存のものをさくっと何も気にせず使えているのは、実はこんな数々のことに支えられていたのか!
ということで、すげー!という感想でした。


用語

アーキテクチャスタイル

複数のアークテクチャに共通する性質、様式、作法あるいは流儀を指す言葉
例:MVC、パイプ&フィルタ、イベントシステム

アーキテクチャ

ハードウェア、OS、ネットワーク、アプリケーションソフトなどの基本設計や設計思想のこと。

リソース

web上の情報で、URIで一意の名前を持ち、URIによって、リソースが表現する情報にアクセスできる

URI

URLとURNの総称。
URLは、何らかの障害でアクセスできなくなる問題があるが、URNは、ドメイン名とは別に恒久的なIDをもつ。
リソースの名前であり、寿命が長く、アドレス欄に表示するため、この点意識して設計する必要がある。

RESTとは

web全体のアークテクチャスタイル。
下記6つを組み合わせている。


  1. クライアント/サーバ:ユーザインタフェースと処理を分離する
  2. ステートレスサーバ:サーバ側でアプリケーションの状態を持たない
  3. キャッシュ:クライアントとサーバの通信回数と量を減らす
  4. 統一インタフェース:インタフェースを固定する
  5. 階層化システム:システムを階層に分離する
  6. コードオンデマンド:プログラムをクライアントにダウンロードして実行する

HTTP

TCP/IPをベースにしたプロトコル
TCP/IPはネットワークプロトコルで、階層化されている。


  1. ネットワークインタフェース層:物理的なケーブルやネットワークアダプタ
  2. インターネット層:ネットワークでデータを実際にやりとりする(IP)
  3. トランスポード層:データの転送を保証する(TCP)
  4. アプリケーション層:具体的なインターネットアプリケーションを実装する

IP

パケット単位でデータをやりとりする
データを送り出すことだけ保証している

TCP

接続先の相手に対してコネクショnをはり、データ抜け漏れをチェックし、データの到達を保証する
転送するデータがどのアプリケーションに渡るかをけっているするのがポート番号

8つのメソッド

  1. GET:リソースの取得
  2. POST:子リソースの作成、リソースへのデータ追加など
  3. PUT:リソースの更新、リソースの作成
  4. DELETE:リソースの削除
  5. HEAD:リソースのヘッダの取得
  6. OPTIONS:リソースがサポートしているメソッドの取得
  7. TRACE:自分宛にリクエストメッセージを返す試験
  8. CONNECT:プロキシ動作のトンネル接続への変更

ステータスコードの分類

  1. 1xx:処理中
  2. 2xx:リクエストが成功
  3. 3xx:リダイレクト
  4. 4xx:クライアントエラー
  5. 5xx:サーバエラー

ハイパーメティアフォーマット

HTML

タグで文書の構造を表現するコンピュータ言語

microformats

HTMLの中でさらに意味のあるデータを表現する

Atom

汎用XMLフォーマット
最小リソース単位が、メンバリソースで、メンバリソースは、エントリリソースとメディアリソースに分かれる
複数のメンバリソースを含むリソースはコレクションリソース

Atom Publishing Protocol

Atomを利用したリソース編集プロトコルの規定
ブラウザ以外のWebクライアントとのシステム連携が容易にできるようになる

JSON

プログラミング言語から扱いやすいデータ構造
データ記述言語で、Javascriptの記法でデータを記述できる

正規表現

なんとなく使ってたので、改めて。

正規表現とは

文字列のパターンを表現する表記法で、文字列の検索や置換を行うときに利用される。
通常の文字と、特別な意味を持った記号(メタ文字)を組み合わせて表記する。

メタ文字

記号 意味
任意の文字にマッチ
直前の文字の0回以上マッチ
+ 直前の文字の1回以上にマッチ
? 直前の文字の0回または1回にマッチ
{n} 直前の文字がn回にマッチ
{n,} 直前の文字がn回以上にマッチ
{n,m} 直前の文字がn回以上m以下にマッチ
^ 行頭にマッチ
$ 文末にマッチ
[] []内に含まれる一文字にマッチ
[^ ] []内に含まれないものにマッチ
区切られたいずれかの文字にマッチ
() グループ化する
\1、\n 後方参照。()にマッチした文字列にマッチ

キャプチャ

文字列の中から正規表現に一致する部分文字列を抜き出す

文法の種類について

sedgrepをオプションなしで使おうとすると、下記で\が必要となる
「+」「?」「{」「}」「(」「)」「|」

POSIX

Portable Operating System Interface
sed -r」「grep -E」とオプションをつけると、上記\が不要となり、すっきりする

Perl

文法がさらに追加。最長マッチを行うかも指定できる
代表的なものは下記

記号 意味
\d 数字にマッチ = [0-9]
\D 数字以外の文字にマッチ = [^\d]
\w アルファベット、数字またはアンダーバーにマッチ = [a-zA-Z_0-9]
\W アルファベット、数字やアンダーバー以外の文字にマッチ = [^\w]
\s 空白文字、\f、\n、\r、\t や \vにマッチ
\S 空白文字以外の文字にマッチ = [^\s]

grepコマンド

ファイルに対してパターンマッチングを行い、マッチする行を出力する。

grep option searchword targetfile

オプション -n で行番号も表示する

grep -n え test.txt

sedコマンド

文字列の置換,行の削除を行う

sed option targetfile

オプション -e で置換処理
オプション -f でファイルを指定して、そのファイル内に記載されている処理を行う

sed -e "s/だめ/いいよ/g" test.txt

Zend Framerorkを使う その2

コマンドで骨組みを作ってくれるそうなので。

zfコマンド設定

もちろんそのままでは使えないので、設定

# cd /usr/local/bin
# cp /usr/share/php/ZendFramework/bin/zf* ./
# mv zf.sh zf
# zf show version

エラー対策

バージョン表示しようとしたら、何やらおっしゃってる。

Warning: Directive 'magic_quotes_gpc' is deprecated in PHP 5.3 and greater in Unknown on line 0


どうやらPHP 5.3以降では、推奨されてない機能が。


#/etc/php.ini

magic_quotes_gpc = Off


マジッククオートは、PHPスクリプトに入力されるデータを 自動的にエスケープする機能。
というわけで、オフ!

エラー消えました。

project作成

$ zf create project test_zend

エラー対策

作成しようとしたら、怒られた

Fatal error: Class 'DOMDocument' not found in /usr/share/php/ZendFramework/library/Zend/Tool/Project/Profile/FileParser/Xml.php on line 82


今度はDOMDocumentがないって怒られた


# yum install php-xml


入れてあげた。


再度作成したら成功。
さらに、親切なことにvhost設定しなさいねーって教えてくれた。
あと、どうやらPHPUnit入ってないけどー!とおっしゃっている

PHPUnitインストール

というわけで、入れておく。
pearコマンドも入ってないので、入れる

# yum -y install php-pear
# pear upgrade
# pear channel-discover pear.phpunit.de
# pear install phpunit/PHPUnit

準備できました。

ディレクトリ構成

こんな感じで作ってくれました。

├── application
│   ├── Bootstrap.php
│   ├── configs
│   │   └── application.ini
│   ├── controllers
│   │   ├── ErrorController.php
│   │   └── IndexController.php
│   ├── models
│   └── views
│       ├── helpers
│       └── scripts
│           ├── error
│           │   └── error.phtml
│           └── index
│               └── index.phtml
├── docs
│   └── README.txt
├── library
├── public
│   └── index.php
└── tests
    ├── application
    │   └── controllers
    │       └── IndexControllerTest.php
    ├── bootstrap.php
    ├── library
    └── phpunit.xml

その他

他にもこんなコマンドありました。

$ zf create controller controller-name
$ zf create action name controller-name



というわけで、すごーく簡単なものを作ろう。

Zend Framerorkを使う その1

さて、だいぶ前にいれたままのZendについて、続きをば。

Zend FrameworkMVCについて

用語について

フロントコントローラ MVCのCに値する部分で、すべてのリクエストを最初に受けつける
アクションコントローラ リクエストに対する必要な処理を、実際に実行する
アクション リクエストに対して、アクションコントローラが行う処理のこと
ルーティング リクエストの内容を判断して、受け渡し先を決定する処理のこと
ディスパッチ アクションコントローラに、以後の処理を受け渡すこと

フォルダ基本構成

application/       アプリケーションを配置する
  ┠ models/       Modelに対応するファイルを配置する
  ┠ views/scripts/  Viewに対応するファイルを配置する
  ┗ controllers/  Controllerに対応するファイルを配置する

public/               フロントコントローラを配置する公開フォルダ
  ┠index.php
  ┗.htaccess

コントローラーについて

ためしに、indexでHello world的なものを作る。

application/controllers/IndexController.php

<?php
require_once 'Zend/Controller/Action.php';

class IndexController extends Zend_Controller_Action
{
    public function indexAction()
    {
    }

    public function helloAction()
    {
      $req = $this->getRequest();
      $this->view->assign('name', $req->getPost('name'));
    }
}

application/views/scripts/index/index.phtml

<html>
<head>
<title>Hello World!</title>
</head>
<body>
どちら様ですか?<br />

<form action="Index/hello" method="post">
    <?php echo $this->formText('name', '')?>
    <?php echo $this->formSubmit('', 'OK')?>
</form>

</body>
</html>

application/views/scripts/index/hello.phtml

<html>
<head>
<title>Hello World!</title>
</head>
<body>

こんにちは、<?php echo $this->escape($this->name);?>さん!<br />

</body>
</html>

エラー表示について

そのままエラーがどわっと出てたので、ちゃんと表示してあげる

application/controllers/ErrorController.php

<?php

require_once 'Zend/Controller/Action.php';
require_once 'Zend/Controller/Plugin/ErrorHandler.php';

class ErrorController extends Zend_controller_Action
{
    public function errorAction()
    {
        $errors = $this->_getParam('error_handler');

        switch ($errors->type) {
            case Zend_controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
                $this->getResponse()->setHttpResponseCode(404);
                $this->view->assign('errorMessage', 'Controller Not Found');
                break;
            case Zend_controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
                $this->getResponse()->setHttpResponseCode(404);
                $this->view->assign('errorMessage', 'Action Not Found');
                break;
            default:
                $this->getResponse()->setHttpResponseCode(500);
                $this->view->assign('errorMessage', 'Application error');
                break;
        }

        $this->view->assign('errorDescription', $errors->exception);
        $this->view->assign('errorRequest', $errors->request->getParams());

    }
}

application/views/scripts/error/error.phtml

<html>
<head>
    <title>エラー</title>
</head>
<body>

<h1>An error occurred</h1>

<h2><?php echo $this->escape($this->errorMessage)?></h2>

<h3>stack trace:</h3>
<pre><?php echo $this->escape($this->errorDescription); ?></pre>

<h3>Request Parameters:</h3>
<pre><?php echo $this->escape(var_export($this->errorRequest, true)); ?></pre>

</body>
</html>

バーチャルホストについて

ちょっとディレクトリの位置を変更したので、手を入れる

Linux側設定

# vi /etc/httpd/conf/httpd.conf

<VirtualHost *:80>
    DocumentRoot /var/www/html/zend/public
    ServerName http://zend.test.jp/
    <Directory "/var/www/html/zend/public">
        DirectoryIndex index.php
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

# /etc/init.d/httpd restart

hostsファイル編集

windowsからアクセスするので、hostsファイルにも書いておく

  1. C:\Windows\System32\drivers\etc\hosts を開く
  2. 192.168.XXX.XXX test.zend.jp
  3. ブラウザでtest.zend.jpにアクセス




というわけで簡単なものを作った。
次は、zfのコマンドを使用してからやる。