Mysqlの基本 2


## データ削除更新

#### テーブルを確認

```
mysql>desc table名;
```
### insert 

```
mysql> insert room values(1,2,'test');
Query OK, 1 row affected (0.00 sec)

mysql> select * from room;
+---------+---------+-------------+
| room_id | bill_id | description |
+---------+---------+-------------+
|       0 |       0 | NULL        |
|       1 |       2 | test        |
+---------+---------+-------------+
```

### update
table を a_tableだとして、
column_aがtestなものを
column_aをupdate testに変更する

```
mysql> update a_table set column_a='update test' where column_a = 'test  data';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0
```

where句がないと全てのレコードが対象になり、すべてのレコードがupdateされてします。


### delete

a_tableのa_table_idがX01のものを削除

```
mysql> delete from a_table where a_table_id='X01';
Query OK, 1 row affected (0.00 sec)
```

ここもupdateと同様にwhereがないと全てのレコードが対象になる。

**updateとdeleteはwhere句が必須。**

###Truncate構文
テーブルを削除する構文

ロールバックできない。
mysqlでは高速に動く

```
mysql> truncate table table名;
Query OK, 0 rows affected (0.00 sec)
```

## 変更、削除を制限する
UPDATE, DELETE 文を実行するときにwhere句がないとエラーがるようになる。
`$ mysql -safe-update`


## ロック
複数人が同時にデータ操作を行った際の矛盾を避けるための仕組みをロックという。

- MyiIamのロックはテーブル全体にかかる。
- InnoDBは列単位でロックがかかる


### Read Lock

対象のテーブルにwrite lockがかかってない場合、リクエストを実行

### write Lock

```
リクエスト -- ロックなし　-- WRITE LOCK -- 書き込み
　　|
ロックがかかっていたら -- リクエストはキューに入る
```

### QUEUE

キューはwriteロック優先。

イメージだと

| 順番 | ロック方法 | 
|:-----------|------------:|
| 1       |        read |
| 2     |      read |
| 3       |        **write** |

上のような キューがあるとすると

| 順番 | ロック方法 | 
|:-----------|------------:|
| 1       |        **write** |
| 2     |      read |
| 3       |        read |

writeの優先順位が上がって
このようになる。

### 楽観ロック	

同じデータの更新画面を同時に複数の利用者が開くことができます。

###悲観ロック
同じデータの更新画面を開くことができる利用者は一人に限定されます。	

## トランザクション 
連続する複数のデータ操作のまとまりのこと

InnoDBはとトランザクションを使えるが
MyISAMはトランザクションは使えないが、高速で処理が行うことができる

#### テーブルがどのDBを使用しているのかを確認する。

```
mysql>  show table status;
```

#### ROLLBACK

トランザクションでの処理が失敗した時に元に戻す仕組み

### autocommit 

全ての問い合わせが 1 つのトランザクションとして振舞うよう、autocommit オプショ
ンが有効になっている

確認コマンド

```mysql

mysql>  SELECT @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)
```

#### autocommitの無効化
```
mysql> SET autocommit=0;
```
トランザクションの制御を手動で行うことができる

#### トランザクションの図

```
BEGIN(トランザクション開始)
|
処理1
|
処理2
|     
処理確認  -- ROLLBACK
|    			|
commit         |
|				|
次の ---- 処理1,処理２を取り消し
処理

```

#### デッドロック

複数のトランザクションが読み書きすることで起きるのがデッドロック

デッドロックはトランザクションを止めたり、失敗させたりするので
回避する必要がある

トランザクションはcommitするまでロックを外さないのでデッドロックが起きる
よって他の複数のトランザクションが待ちになる


InnoDBは行ごとにロックをできる。

メモ帳にメモ
![20170420_171130.jpeg](https://qiita-image-store.s3.amazonaws.com/0/70960/dd61e07b-d5e2-1653-711e-69d463d1bdfb.jpeg "20170420_171130.jpeg")



#### デッドロック解決策
1. SELECT ... FOR UPDATE
tx1のupdate1,update3で使用する行をロックして、処理を実行し
commit後、tx2を実行する

2. 行の更新順番を統一する

### 日本語を使用した場合

```/etc/mysql.cnf
#サーバー側
[mysqld]
character-set-server=utf8

#mysql コマンド
[mysql]
default-character-set=utf8

#クライアント
[client]
default-character-set=utf8
```

### ロギング


|種類 | ロック方法 | 
|:-----------|:------------|
|クエリーログ      |   クライアントからの接続や発行された SQLクエリ のログ。      |
|スロークエリログ     |   決められた時間以上に処理に時間がかかったり、インデックスを使用しないクエリのログ |

### テーブル

#### CREATE TABLE 



```sql
CREATE TABLE `room` (
  `room_id` int(11) NOT NULL default '0',
  `bill_id` int(11) NOT NULL default '0',
  `description` char(40) character set utf8 collate utf8_general_ci default NULL,
  PRIMARY KEY  (`bill_id`,`room_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
```


```mysql
mysql> CREATE TABLE `room` (
    ->   `room_id` int(11) NOT NULL default '0',
    ->   `bill_id` int(11) NOT NULL default '0',
    ->   `description` char(40) character set utf8 collate utf8_general_ci default NULL,
    ->   PRIMARY KEY  (`bill_id`,`room_id`)
    -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.01 sec)

mysql> desc room;
+-------------+----------+------+-----+---------+-------+
| Field       | Type     | Null | Key | Default | Extra |
+-------------+----------+------+-----+---------+-------+
| room_id     | int(11)  | NO   | PRI | 0       |       |
| bill_id     | int(11)  | NO   | PRI | 0       |       |
| description | char(40) | YES  |     | NULL    |       |
+-------------+----------+------+-----+---------+-------+

```


Mysql


#### DROP TABLE


```
mysql> drop table room;
Query OK, 0 rows affected (0.00 sec)

```

#### ALTER TABLE 

alter table テーブル名 add　カラム名 型;

```
mysql> alter table room add address varchar(20);
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
```