DB入門 ~MySQL~

##program: 入力→処理→出力
D + A = P
Data + Algorithm = Program

+ relational database
#正確だからって伝わるとは限らない．誤解を生むかもしれないけど便宜的に変えて説明するほうが有効
Open Source is not Free Ware
Freeware cannot open the source code

##MySQL
 old time, fast but lots of unavailable things
##PostgreSL
 old time,  available lots of things, but slow, for academic use
Nowadays, not so different

__「銀の弾丸は存在しない」「銀の弾丸」__
万能薬は存在しない
one technique can not solve anything.
with Hammer, she sees everything as peg

##KVS(Key Value Store)
 store as pair key and value
  e.g)memchached/ repchached(distributed memchached)
      Cassandra
     
###NoSQL
 Everything except RDB, So Attention

###DOCUMENT ORIENTED
 a program must be modified.
 better one is one which can be modified
 
 e.g)MongoDB, CouchDB

###Hadoop
 - Hadoop Distributed File System
    HDD is so slow, 1000 times slower than memory
 - map/reduce Engine
    Functional Programing
    テラバイトくらすのログデータを高速処理したい時に使えます
    指定した関数では入れトォ並列処理するmap
      cf)Java: has state. Functional one does not have state.
              とにかく入ってきた値で計算
        たくさんのデータをとにかくこの関数で処理してください的な

    指定した関するに従って配列をまとめるreduce
        条件分岐させて，処理関数を変えていくのをreduce
       

#####業務だとphpMyAdminをよく使う
 But this cannot permit Transaction
  transaction: 関連する複数の処理を一つの処理単位としてまとめたもの。

***
========HOW TO MAKE PROGRAMING========
プログラムはまず日本語(英語)で考える
シェルもそう
↓
段階訳をしていく
↓
要素を洗い出していく
↓
図にする
↓
プログラム言語に置き換えて
↓
実際のコマンド・言語に帰る
========HOW TO MAKE PROGRAMING========
***

#認証(2 types: authentication, authorization)
1. authentication is verifing the person

 - 生体認証
 - IDとパスワード
 - 総当り法(BruteForceでクラックできる)
 - 公開鍵暗号(pair key)
     engineer use this
     secret key
      - 暗号とは「グチャグチャにしたものを元に戻せるもの」「平文を暗号化して複合する」
      - pair key
          - public key
                みんなに見せていい
              平文に公開鍵をぶつけると暗号化する
              set in Server
      - secret key
                平文にsecret keyをぶつけると複合する
              秘密鍵ファイルからIDとパスフレーズをぶつけて秘密鍵を生成する
              秘密鍵ファイルとパスフレーズが隠すべき情報
              なしにもできるが，セキュリティが弱くなる
              秘密鍵をセキュアに渡す方法
                メールでやるやつPGP
                CDRとかに焼いて渡す奴
                でパスフレーズは印刷して渡す
                どちらかがクラックされても大丈夫なように
               ワンタイムパッド暗号
                やぶれないことはないとされる暗号の定義を唯一破った暗号
                平文と同じ長さの暗号を用意する
                それをXORでぶつける
[http://ja.wikipedia.org/wiki/%E3%83%AF%E3%83%B3%E3%82%BF%E3%82%A4%E3%83%A0%E3%83%91%E3%83%83%E3%83%89](http://ja.wikipedia.org/wiki/%E3%83%AF%E3%83%B3%E3%82%BF%E3%82%A4%E3%83%A0%E3%83%91%E3%83%83%E3%83%89 "wikipedia")
                in government, in ssh too.

           modを利用して，数学的に作られているようだ
              set in Client

     暗号の世界では，
          昔はどう暗号化するかがわかられたらダメだったけど
          今は，どう暗号化するかわかった上で，破られないものが認められる

  Facebook
   httpを見ていくと，一往復の紙芝居だから，すべてが連続しているわけでない
   Basic認証はそれを裏側で保持してい・・・・・・・
        http://ja.wikipedia.org/wiki/Basic%E8%AA%8D%E8%A8%BC

##authorization
   あるアクセスとほかのアクセスが同一人物だとわかるもの
   いくつかのアクセスを同じものとみなすもの


Normally, in MySQL port num is 3306.

#sshのやり方
```よくあるやり方
ssh [hostname]@domain
```

#MySQLの入り方
```よくあるやり方
mysql -u -[loginname] -p [databasename];
```
1. -p means Need password
2. -h means Need hostname
3. -P port number

```終わり方
exit or ctl+d
```

- いつもログインしているはずのサーバーで，
初めて来ましたねって言われたら要注意


#SQL文例
- sql文の書き方
- /* コメント */コメントアウトはこれ
- 一応 //で行末までいけるけど，トラブル感じになるからこれはやめよう

##考え方
```ex.1
1. 商品番号１の商品のな前をください
2. ください 名前 商品 商品番号１
3. SELECT 名前 FROM 商品 WHERE 商品番号が１
-> SELECT item_name FROM items WHERE item_id = 1;
```
```ex.2
1. 新規登録 商品(商品番号，商品名，商品値段)値は(9991, 技術饅頭, 4096円)
-> INSERT INTO items (item_id, item_name, item_price) VALUES (9991, '技術饅頭', 4096);
```
```ex.3
1. 編集 商品 商品値段を8000円に 商品番号が9991のやーつ
-> update imtes set item_price=8192 where iyrm_id=9991;
```
  !!updateの時はwhereを必ず使う!!
  DBってそんなに手でいじるものではない
  deleteも，，，，，'`,､('∀`) '`,､

```ex.4
1. 削除 商品 商品番号9991
2. delete from 商品 where 商品番号9991
-> delete from items where item_id = 9991;
```


ORDER BY 並び順の指定
RDBには順番の概念は存在しない
だからRDBを表だと認識すると誤差が生じてしまう
order by item_price desc;
descendent = 昇順

######横にバーって伸びるのを防ぐには\Gで表示を変えられる
######けどなんかあれ

```表示数を制限できる0番目から10個表示って意味
-> select item_id, item_name, item_price, from items order by item_price order by desc limit 0,10;
```

```
-> select item_id, item_price, item_name from items_truth where category_id = 1 or category_id = 2 order by item_price desc limit 0,10;

これを書き換えて

-> select item_id, item_price, item_name from items_truth where category_id IN (1,2) order by item_price desc limit 0,10;
IN is faster than OR.
```


```SQLCommnad
decs [table名] テーブルの中身一覧
show tabel テーブル一覧
```


```where文のなかにbetweenを書いてnからmまで表示
mysql> select order_slip_id, order_date, user_id from order_slips where order_date between '2012-01-01 00:00:00' and '2012-01-03 00:00:00';
```

秒まで書きましょう


```asを使って名前を別名にすることができsumで金額の合計ができる
mysql> SELECT OS.order_slip_id      , OS.user_id      , OS.order_date      , OSDETAIL.item_id      , OSDETAIL.item_num      , OSDETAIL.item_unit_price      , (OSDETAIL.item_num * OSDETAIL.item_unit_price) as subtotal   FROM order_slips OS        LEFT JOIN order_slips_detail OSDETAIL          ON OS.order_slip_id = OSDETAIL.order_slip_id;
```



```結果をグルーピングすることができる
SELECT OS.order_slip_id /* どの伝票で */
     , OS.user_id /* 誰が */
     , sum(OSDETAIL.item_num * OSDETAIL.item_unit_price) as total /*  いくら買ったか ＝「商品単価＊売り上げ個数」のsum(集計)を取得 */
  FROM order_slips OS
       LEFT JOIN order_slips_detail OSDETAIL
         ON OS.order_slip_id = OSDETAIL.order_slip_id
 GROUP by OS.order_slip_id; /* 伝票別に全件取得 */
```

                      
```order_slipsってテーブルをOSに置き換えました
from order_slips OS
```

```ここはasがいる
select sum(----) as ----
```

- order by, group byは別名登録がそもそも無理

```
//
BD baundle = db connecting function(id, pass, ....);


//エスケープ処理が一番大事だよ!
//これは大事なんですよー
id = db escape(id);
sql = 'select * from items where id = {id};';


//ちょっと良くわからないけど処理
sql = 'select * from items where id = 0;';
db hundle->sql original one();
db hundle->send data(array[id => {id}]) };

//
sqlresult = db hundle->query(sql);

sql = 'select * from items where id = {id};';
sql = 'select' * from items where id = 0; insert sukinadata;';
```


###Javaのオブジェクトごとdbに保存したい時は，serializeして文字列化してdbに入れ込む
###→出してunserializeして再度使う



#Transaction取引，相互作用
##ACID
     1. Atomicity 全部実行か全部なし
     2. Consistency おかしな値は入らない整合性      
     3. Isolation transaction中は干渉されない
     4. Durability transactionが終了したら結果は失われない
###CAP定理
     1. Consistency すべてのノードで同じ情報が帰ってくること
     2. Availability システムが使えなくなる時間がないこと
     3. Partition-tolerance ノードをネットワーク的に分断できること
          - Scale-out サーバー数を増やして並列処理のスケールを上げる
          - Scaoe-up サーバー単体の性能を増強する cpu, memory, hd, access speed
         
     - CAP定理は2つしか満たすことができない
       - C+A ネットワーク分断に弱いから拡張性に乏しい ->real money service, core data
       - A+P データの更新性で遅延がある可能性 -> ordianry servieces,
       - A+P 単一障害点がある，またデータの同期などで時々システムが使えなくなる -> only bank, basically unuseful.

     3つやろうとすると論理的に破綻する
         

###BASEというゆるい発想
 1. Basically Available 基本的に可用性はいいよー
 2. Soft-state 状態はゆっくり変わっていくよ
 3. Eventual consistency 最終的には一貫性あるよ

 - TCP
  同一回線でコリジョンが起きたら，乱数を発生させて再送信ーーー>もっかい適当に投げてみりゃなんとかなるんじゃね？って感じ

##Network & Hardware
通信回線とかNICの品質が悪いとやるとりが多発して海鮮を圧迫します
  よいNICやBooringを書いとかね
- NIC: network information center
- NIC: network interface card
- HDD: データを長期的に保存しておくパーツ
- SSD: Solid State Drive フラッシュメモリという長期的にデータを保存できるメモリにデータを保存
[http://homepage2.nifty.com/kamurai/HDD.htm#ssd](http://homepage2.nifty.com/kamurai/HDD.htm#ssd "ssdについて") 

  メモリの設定が出来ます


##人口キーと自然キー
  キーはユニークであることが絶対条件
  Primary key(PK)
  一行ごとに固有の値＝ユニーク
  2つ以上のカラムをあわせて複合キー

  自然キー:データの中に一意にあるものがあればそれをPKに使う
  人口キー:人工的に割り振る．AUTO_INCREMENTを使うことがありますMySQLには

  データベースに入っているものの中から，かぶらないものをキーにできる
  代名詞として使えるものを選択するような感覚です．

#インフラ系作業の基本
- テキストファイルに作業手順(コマンド/SQL)を書く
- 誰かに確認してもらう
- 当日はそのファイルをコピペして使う
 - やっちまってから慌てて取り返そうとすると更に凄いことになる

##rollback;で戻せるからもちつけ(・∀・)
- phpMyAdminはこれができないからいやだ
- 徹夜明けはマジパニックになるから，躊躇なくコンソールを落としませう',､('∀') '`,､
- 作業中のミスはrollbackでなんとか巻き戻せる
- 一応安心しれ

#Indexを切る


#DBのNullは３つ
1. データがある
2. そもそもカラムが存在しない
3. そのカラムには値が存在しない


- nullの論理演算をカマスとすべてNULL.
- nullが絡む演算子はすべてNULLになる

```
前提a=3, b=4, c=NULL

NOT(a=c): NULL
a>b OR b>c: NULL
a>b AND b>c: false
a<b OR b<c: true
```

####- DBにおけるNULLの存在は，可能な限り避けましょう
####- 絡むに not nullって書いておくとnullが入らないからいいよ
####- sqlのnullってめっさこわいお(:.;ﾟ;Д;ﾟ;.:)ﾊｧﾊｧ
##- でもカラムに何も入っていないことを入れたい時があるからその時は，文字列なら空文字''，数字なら0か-1をいれるとよい

#Code Table
コードテーブルを切るときは気をつけ無なくてはならない

ecサイトなんかでは商品単価なんかは書いておく
有効期限startと有効期限endの日付を入れておく
でもこの場合コードIDがプライマリーキーが合わなくなる
そのため，コードIDと有効期限の2カラムを複合キーにする

この期間だけ30%offみたいな使い方を良くする
この場合テーブル設計はなかなか難しい
ecのプログラムはまじめにやるとめんどくさいよ



##できると思った瞬間から無能になるのが技術者
##追加修正運用がしやすいプログラムは素晴らしいプログラム
###【隙間があって好きがない実装】
1. DRY = 同じ事は二度書くな(Don't Repeat Yourself)
2. 共通化 = 一箇所を修正したら，ほかのすべてが修正されるような感じ
3. コピペは論外

##粒度やレイヤー
- ファクトリーと呼ばれるデザインパターンはいいよー
- 大きなレイヤーから小さなレイヤーへって感じでミシミシ書いていくべき
- 丁寧にレイヤーを細かく切っていって，それに対して自然にモノを作っていく
- YAGNI = 必要になってからしかものはつくってはいけない．レイヤーを細かく切って丁寧に作っていけ.ヤマカンだけは絶対にだめ
[https://www.google.co.jp/search?sourceid=chrome&ie=UTF-8&q=yagni](https://www.google.co.jp/search?sourceid=chrome&ie=UTF-8&q=yagni, "必要になってからものをつくれ")
- 計測して問題点を洗い出しましょう




- コメントは書きなさい．言い訳も書きなさい．苦しいとか悲しいとか，こういう意思と状況でこう書いたと，「こう」もちゃんと表現して書きなさい

###「コメントには何をしたいのか，なぜこうしたいのか」を書く
###「そのための処理をプログラムを書く」

***
#初めはコメントでマイルストーンを敷く（日本語プログラミング）
- こうすると何を書くといいのかわかる．いいねこれ．

```買い物カゴに商品を入れる
// CGIを受け取る

// 商品IDをチェック

// かごオブジェクトに突っ込む

// かごを保存

```

***
#DBチューニングとは
- サーバー設定とSQL

1. まずはSQLから

```
slow_query
```
で重たい子を発見する

```
EXPLAIN
```
も使えるよ

```
slow_query time = 0
```

で全SQLを把握してざっくり集計
小さいけど群れなSQLを発見db


2. サーバー設定

```
/etc/my/cnf
```
が対象

- プロセス
- OSが使うメモリ
- OS寄りのハードウェアアーキテクチャ

3. 接続コネクションの数
- その瞬間のアクセスの数
- MySQLがプログラムから呼ばれてデータのやりとりをするあれ
- 1SQLで大量のデータを扱うか，たくさんのSQLでちょっとずつデータをあつかうか

***
#SQL Injection
webセキュリティは結構やるのが大事
***
#大量データを捌くために
DBはwriteよりもreadのほうが100倍以上多い
replicationで対応
マスターとスレーブを用意する
書き込みはマスターに，読み込みはスレーブに均等に分散
[http://thinkit.co.jp/free/trend/10/4/](http://thinkit.co.jp/free/trend/10/4/, "Replication")

##マスターの処理能力を超えるアクセスがあった際には
###シャーディング
おもいっきりDBを分断する方法
MySQLSpiderエンジンを使ってもいい
水平展開するといい
[http://d.hatena.ne.jp/abcb2/20111010/1318224266](http://d.hatena.ne.jp/abcb2/20111010/1318224266, シャーディング)
こうしていくともうNoSQLとかわんなくね？

###cf)パーティショニング
[http://www.atmarkit.co.jp/fdb/rensai/ora_partition01/ora_partition01_01.html](http://www.atmarkit.co.jp/fdb/rensai/ora_partition01/ora_partition01_01.html, "Partitioning")

###クラスタリング
[http://itpro.nikkeibp.co.jp/article/COLUMN/20060715/243478/](http://itpro.nikkeibp.co.jp/article/COLUMN/20060715/243478/, "clustering")

[MySQL Cluster](http://dev.mysql.com/doc/refman/5.1/ja/mysql-cluster.html, "cluster")


SQLの結果をキャッシュしてメモリにおいておいたら早いじゃんって発想から，memcachedを始めとするKVS(Key Value Store)という発想が生まれた
だがしかしキャッシュはトラブルメーカーでもある
DB情報を更新したのにキャッシュが有効なままだから古い情報が出っぱなし
write, read, insert, delete, uptateのタイミングで随時キャッシュを消す

###関所を作る
write, read, insert, delete, uptateのところどころでキャッシュを消す
先にキャッシュを読みに行って，該当するのがあったらそれを取ってくればいいし，なければキャッシュまるごと消せばいい

##データにアクセスするっていうもやっとしたレイヤを作っておくと，．．
1ランク高い抽象度でやり取りすることができる

***
#Hadoop
- 関数プログラミングのmapとreduce
- mapは配列の値を並列に計算
- reduceは配列をひとつに集計
  - 実際はmap->shuffle->reduce
- 分散可能な処理を並列で処理できます
- ログ解析，一部のゲーム処理，バッチ処理などで非常に強力な武器になる


***
#BOOK
- データベース実践講義(O'Reilly)

半年や一年後に見なおしてニヤニヤできるといい
でも業務とはあまりに乖離している

- ミックのページ
[秀逸なRDBサイト](http://www.geocities.jp/mick/index,"ミック")

- 達人に学ぶ SQL徹底指南書 (CodeZine BOOKS) [単行本（ソフトカバー


***
#キャリア
- 50~60% 興味ある内容
- 20~30% エンジニアと関係のない内容
- 10~20% 興味はなくともやるべき内容

***
#とにかく一度はやっておくべき言語
まずはC
  - ポインターのポインターのポインターが使えるようになること
  - メモリーリークせずに自由に使える様になること
     - ガーベージコレクションは便利だけどそれは置いとけ
     - 何をやったらメモリを食うのかわかるようになるといい
  - Linuxのカーネルドライバを自作できること
  - httpdが自作でき，一ヶ月継続運用できるようになること
   - smtpでもいい
  - ウェブサーバーを自作すること

次にオブジェクト系
次にPHPもしくはPerl
そして関数型言語
って感じで行きなさい

***
#やり方
一ヶ月に少し成長することを思いましょう
一ヶ月に1トピックな感じで
技術本を月に一冊
技術本じゃないものを月に一冊
 - 会計や経営にまつわる本
 - メンタルケア
 - ホスピタリティにまつわる本
薄い本を選ぶといい
あとは実務ですね

わかんないことはおいちゃんさんに聞けばいい