mysqlで遊ぼう2

テーブルの作り方

mysql> create table users (
    ->  id int,
    ->  name varchar(255),
    ->  email varchar(255),
    ->  password char(32)
    -> );
Query OK, 0 rows affected (0.33 sec)

テーブルの確認

mysql> show tables;
+--------------------+
| Tables_in_blog_app |
+--------------------+
| users              |
+--------------------+
1 row in set (0.00 sec)

削除する際は、drop table users とします。
mysqlでは扱えるデータ型は複数あります。
-数値
int
double
-文字列
char(固定長)
varchar(可変長)
text
-日付
date
datetime
それ以外
enum

また、フィールドにオプションをつけることが可能です。
入力必須:not null
デフォルト値: default ”
自動連番 auto_increment
索引(インデックス) 主キー(primary key)、キー(key)、ユニークキー(unique)

では、createして、descでテーブルの構造を見てみましょう。

mysql> create table users (
    ->  id int not null auto_increment primary key,
    ->  name varchar(255),
    ->  email varchar(255) unique,
    ->  password char(32),
    ->  score double,
    ->  sex enum('male', 'female') default 'male',
    ->  memo text,
    ->  created datetime,
    ->  key score(score)
    -> );
Query OK, 0 rows affected (0.05 sec)

mysql> desc users;
+----------+-----------------------+------+-----+---------+----------------+
| Field    | Type                  | Null | Key | Default | Extra          |
+----------+-----------------------+------+-----+---------+----------------+
| id       | int(11)               | NO   | PRI | NULL    | auto_increment |
| name     | varchar(255)          | YES  |     | NULL    |                |
| email    | varchar(255)          | YES  | UNI | NULL    |                |
| password | char(32)              | YES  |     | NULL    |                |
| score    | double                | YES  | MUL | NULL    |                |
| sex      | enum('male','female') | YES  |     | male    |                |
| memo     | text                  | YES  |     | NULL    |                |
| created  | datetime              | YES  |     | NULL    |                |
+----------+-----------------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)

挿入はinsert int tablename() values();、入力後は、select * from users;で確認できます。

mysql> insert into users (name,email,password,score,memo,created) values('name','test@gmail.com','xxx','5.5','memomemomemo','2016-11-04 12:00:00');
Query OK, 1 row affected (0.01 sec)

mysql> select * from users;
+----+------+----------------+----------+-------+------+--------------+---------------------+
| id | name | email          | password | score | sex  | memo         | created             |
+----+------+----------------+----------+-------+------+--------------+---------------------+
|  1 | name | test@gmail.com | xxx      |   5.5 | male | memomemomemo | 2016-11-04 12:00:00 |
+----+------+----------------+----------+-------+------+--------------+---------------------+
1 row in set (0.00 sec)

select * from users \G で縦に表示することも可能です。
select * from users where score >= 5.0; など条件付きの検索はwhereを使います。

mysql> select * from users where score >= 5.0;
+----+----------+--------------------+----------+--------+-------+---------------------+
| id | name     | email              | password | team   | score | created             |
+----+----------+--------------------+----------+--------+-------+---------------------+
|  1 | yamada   | yamada@gmail.com   | NULL     | blue   |   5.5 | 2016-11-03 11:00:00 |
|  2 | sasaki   | sasaki@gmail.com   | NULL     | yellow |   8.2 | 2016-11-02 10:00:00 |
|  5 | yamamoto | yamamoto@gmail.com | NULL     |        |   7.4 | 2016-10-30 07:00:00 |
+----+----------+--------------------+----------+--------+-------+---------------------+
3 rows in set (0.00 sec)

一部一致の検索は、likeを使います。

mysql> select * from users where email like '%@gmail.com';
+----+----------+--------------------+----------+--------+-------+---------------------+
| id | name     | email              | password | team   | score | created             |
+----+----------+--------------------+----------+--------+-------+---------------------+
|  1 | yamada   | yamada@gmail.com   | NULL     | blue   |   5.5 | 2016-11-03 11:00:00 |
|  2 | sasaki   | sasaki@gmail.com   | NULL     | yellow |   8.2 | 2016-11-02 10:00:00 |
|  3 | kimura   | kimura@gmail.com   | NULL     | red    |   2.3 | 2016-11-01 09:00:00 |
|  4 | tanaka   | tanaka@gmail.com   | NULL     | blue   |   4.5 | 2016-10-31 08:00:00 |
|  5 | yamamoto | yamamoto@gmail.com | NULL     |        |   7.4 | 2016-10-30 07:00:00 |
|  6 | yoshida  | yoshida@gmail.com  | NULL     | yellow |   4.2 | 2016-10-29 06:00:00 |
+----+----------+--------------------+----------+--------+-------+---------------------+
6 rows in set (0.00 sec)

その他の以下のようにコマンドです。
mysql> select * from users where score between 5.0 and 8.0;
mysql> select * from users where team in (‘red’, ‘yellow’);
mysql> select * from users where score <= 4.5 and team 'blue'; 並び替えはorder byを指定します。descは並び順が逆になります。 select * from users order by score; select * from users order by score desc; 制限を加えることもできます。 select * from users limit 3; select * from users limit 2, 2; select * from users order by score limit 3;

MySQLで遊ぼう

mysqlの開発者用サイトです。
MySQL
データベースには、テーブル、フィールド(列)、レコード(行)の概念があります。Excelのスプレッドシートのように考えると分かり易いです。

mysqlの起動では、ユーザー名を入れて起動します。

[vagrant@localhost ~]$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.6.34 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

パスワードの設定は以下の通りです。

set password for root@localhost=password(”)

データベースの作り方は、create databaseで作れます。

mysql> create database blog_app;
Query OK, 1 row affected (0.12 sec)

一覧表示

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| blog_app           |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.14 sec)

データベースの削除

mysql> drop database blog_app;
Query OK, 0 rows affected (0.21 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)

データベースの利用

mysql> use test;
Database changed

作業ユーザーの設定方法

mysql> create database blog_app;
Query OK, 1 row affected (0.06 sec)

mysql> grant all on blog_app.* to dbuser@localhost identified by 'xxxx';
Query OK, 0 rows affected (0.16 sec)

作業ユーザーでのログイン

[vagrant@localhost ~]$ mysql -u dbuser -p blog_app
Enter password:

AWS DBの起動

AWSのDBはRDSにありますので、そこからインスタンスを起動します。
%e7%84%a1%e9%a1%8c

Multi-AZ Deploymentの設定は通常「はい」にして、セキュリティを高めます。

DBインスタンスを作成したら、エンドポイントを確認します。
%e7%84%a1%e9%a1%8c

そして、mysqlに接続します。

[ec2-user@ip-172-31-21-202 ~]$ mysql -h mydbinstance.c7fqvxerxxxx.ap-northeast-1.rds.amazonaws.com -u                 name -p

AWS IMAGESの作成

IMAGESはインスタンスのテンプレートのようなものです。
%e7%84%a1%e9%a1%8c

イメージは、サーバーがシャットダウンされて、snapshots、AMIsが作られます。
インスタンスがシャットダウンされると、パブリックDNSが使用できなくなるので、Elastic IPsでIPアドレスを作成します。

そして、作成済みのインスタンスと関連付けを行います。
%e7%84%a1%e9%a1%8c

すると、インスタンスに割り当てられていることがわかります。
%e7%84%a1%e9%a1%8c

バックアップはElastic block storeのvolumesでクリップスナップショットをつくれば、その時点のバックアップをとります。
%e7%84%a1%e9%a1%8c

インスタンスのスペック変更は、一旦インスタンスを停止し、インスタンスタイプの変更で簡単に変更することができます。
%e7%84%a1%e9%a1%8c

t2.nanoでウェブサーバーを立ち上げよう

AWSに接続したら、サーバーにhttpd、php、mysqlをインストールします。

[ec2-user@ip-172-31-21-202 ~]$ sudo yum -y install httpd php mysql

インストールが完了したら、httpdの立ち上げを行います。

[ec2-user@ip-172-31-21-202 ~]$ sudo service httpd start
Starting httpd:                                            [  OK  ]
[ec2-user@ip-172-31-21-202 ~]$ sudo chkconfig httpd on

そうしたら、index.htmlファイルを作成し、ウェブサーバーが稼働しているか確認してみます。

[ec2-user@ip-172-31-21-202 ~]$ sudo vim /var/www/html/index.html

すると、反映されていることが確認できます。
%e7%84%a1%e9%a1%8c

t2.nano

AWSの設定ですが、アプリケーションの規模やアクセス数に応じてスペックを決めるのが通常ですが、昨今では最小構成から始めて、必要に応じてスペックを上げていくのがトレンドのようです。
AWSの費用は、さくらインターネット・GMOクラウド社等の他のクラウドサーバに比べて高いですが、オートスケール(Amazon EC2)・インターネットストレージ(Amazon S3)・メール配信(Amazon SES)・データベース(Amazon RDS)等のサービスが充実してます。

t2.nanoですと、東京リージョンで$0.01/1時間あたりくらいです。

インスタンスをつくっていきましょう。
セキュリティグループ(ファイヤーウォール)はデフォルトでSSHの設定がありますが、web用のHTTP、ポート80を追加しましょう。
aws

インスタンスのDescriptionでパブリックDNSがアクセスする際のアドレスになります。
%e7%84%a1%e9%a1%8c

なお、インスタンスを立ち上げると、ELASTIC BLOCK STOREのVolumuesが自動的に作成されます。

インスタンスへの接続は、ターミナルから行います。
%e7%84%a1%e9%a1%8c

秘密鍵のパーミッションを設定して、ssh接続すると、t2.nanoへの接続が確認できます。

[vagrant@localhost aws]$ chmod 600 test.pem
[vagrant@localhost aws]$ ssh -i "test.pem" ec2-user@ec2-54-199-174-180.ap-northeast-1.compute.amazonaws.com
The authenticity of host 'ec2-54-199-174-180.ap-northeast-1.compute.amazonaws.com (54.199.174.180)' can't be established.
RSA key fingerprint is 62:7f:e2:a3:17:ed:52:6b:c7:65:65:fc:05:38:e1:d3.
Are you sure you want to continue connecting (yes/no)? y
Please type 'yes' or 'no': yes
Warning: Permanently added 'ec2-54-199-174-180.ap-northeast-1.compute.amazonaws.com,54.199.174.180' (RSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2016.09-release-notes/

code-bird php

code-bird phpはtwitter APIにphpでアクセスする際のライブラリです。

Git Hub Codebird-php

git hubのページに解説があるように、以下のように記載していきます。

require_once ('codebird.php');
\Codebird\Codebird::setConsumerKey('YOURKEY', 'YOURSECRET'); // static, see README

$cb = \Codebird\Codebird::getInstance();
You may either set the OAuth token and secret, if you already have them:
$cb->setToken('YOURTOKEN', 'YOURTOKENSECRET');

twitter-devでmyappを作成し、アクセスキー、トークンを取得してphpに実装していきましょう。

<?php

require_once('codebird.php');
require_once('config.php');

Codebird::setConsumerKey(CONSUMER_KEY, CONSUMER_SECRET);
$cb = Codebird::getInstance();
$cb->setToken(ACCESS_TOKEN, ACCESS_TOKEN_SECRET);

$params = array(
  'screen_name' => 'name',
  'include_rts' => true
);

$tweets = (array) $cb->statuses_userTimeline($params);

var_dump($tweets);

youtube api

<!DOCTYPE html>
<html lang="ja" ng-app>
<head>
    <meta charset="UTF-8">
    <title>Angular js</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js"></script>
    <script src="myscript.js"></script>
<body>
<h1>YouTube Search</h1>
<div ng-controller="mainCtrl">
  <form ng-submit="doSearch()" name="myForm">
  <input type="text" ng-model="query" required>
  <input type="submit" value="search" ng-disabled="myForm.$invalid">
</form>
  <h2>Results</h2>
  <ul ng-show="results.length" style="list-style:none;padding:0">
    <li ng-repeat="result in results">
        <img ng-src="{{result.media$group.media$thumbnail&#91;0&#93;.url}}">
        {{result.title.$t}}
    </li>
  </ul>
  <p ng-hide="results.length">↑から検索してください。</p>
</div>
</body>
</html>
var mainCtrl = function($scope, $http){
 	$scope.doSearch = function(){
 			var url = 'https://gdata.youtube.com/feeds/api/videos?'
 			+ [
 				'q=' + encodeURIComponent($scope.query),
 				'alt=json',
 				'max-results=10',
 				'v=2',
 				'callback=JSON_CALLBACK'
 			].join('&');
 			$http.jsonp(url).success(function(data){
 				// console.dir(data);
 				$scope.results = data.feed.entry;
 			});
 	}

}

php簡易掲示板

投稿内容はdatファイルに格納します。

<?php

$dataFile = 'bbs.dat';

// csrf
session_start();

function setToken(){
  $token = sha1(uniqid(mt_rand(), true));
  $_SESSION&#91;'token'&#93; = $token;
}
function checkToken(){
  if (empty($_SESSION&#91;'token'&#93;) || ($_SESSION&#91;'token'&#93; !=$_POST&#91;'token'&#93;)){
    echo "不正なpostが行われました!";
    exit;
  }
}

function h($s){
  return htmlspecialchars($s, ENT_QUOTES, 'utf-8');
}

if($_SERVER&#91;'REQUEST_METHOD'&#93; == 'POST' &&
  isset($_POST&#91;'message'&#93;) &&
  isset($_POST&#91;'user'&#93;)){
    checkToken();

  $message =trim($_POST&#91;'message'&#93;);
  $user = trim($_POST&#91;'user'&#93;);

 if($message !== ''){

   $user = ($user === '') ? 'ななしさん' : $user;

   $message = str_replace("\t", '', $message);
   $user = str_replace("\t", '', $user);
   $postedAt = date('Y-m-d H:i:s');

  $newData = $message . "\t" . $user . "\t" . $postedAt. "\n";

  $fp = fopen($dataFile, 'a');
  fwrite($fp, $newData);
  fclose($fp);
   }
} else {
  setToken();
}

$posts = file($dataFile, FILE_IGNORE_NEW_LINES);

$posts = array_reverse($posts);
?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>簡易掲示板</title>
</head>
<body>
  <h1>簡易掲示板</h1>
  <form action="" method="post">
    message: <input type="text" name="message">
    user: <input type="text" name="user">
    <input type="submit" value="投稿">
    <input type="hidden" name="token" value="<?php echo h($_SESSION&#91;'token'&#93;); ?>">
  </form>
  <h2>投稿一覧(<?php echo count($posts); ?>件)</h2>
  <ul>
    <?php if (count($posts)) : ?>
      <?php foreach ($posts as $post) : ?>
        <?php list($message, $user, $postedAt) =  explode("\t", $post); ?>
        <li><?php echo h($message); ?>(<?php echo h($user); ?>)-<?php echo h($postedAt); ?></li>
      <?php endforeach; ?>
       <li></li>
    <?php else : ?>
    <li>まだ投稿はありません。</li>
  <?php endif; ?>
  </ul>
</body>
</html>

%e7%84%a1%e9%a1%8c