okinawa

IT勉強メモ

DB・SQLの基本

 

参考図書

・スッキリわかるSQL入門
スッキリシリーズは本当に素晴らしい。
いつおもお世話になっております。
 

select

検索
select 列名 from table名;
 

select文全部入り

select文に全構文を入れるとこうなる。
select 列名
from table
where 条件式
group by 列名
having 条件式
order by 列名
 

insert

挿入・新しい行の作成
insert into teble名 (列名, 列名, 列名) values('値', '値', '値');
 
全列追加なら列名省略できる
insert into teble名 values('値', '値', '値');
 

update

更新・すでにある行の修正
update table名 set 列名 = '値' where 列名 = '値';
where句なしだと全行更新になる。
 

delete

削除・行の削除
delete from table名 where 列名 = '値';
where句なしだと全行更新になる。
 

演算子

比較演算子

=, <, >, <=, >=, <>

<>は左右の値が等しくない

!=と同じ
select * from 家計簿 where 出金額 <> 1000;
 

Null判定

=で判定できない。
式 is nll;
式 is not null;
select * from 家計簿 where 出金額 is null;
select * from 家計簿 where 出金額 is not null;
 

LIKE

select * from table where A LIKE '%abc%';
 

BETWEEN

ある範囲内に値がおさまっているかを判定。
式 BETWEEN 値1 AND 値2;
select * from table where 出金額 between 100 and 300;
 

IN/NOT IN

値がカッコ内の複数の値のいずれかに合致するかを判定する。
式 IN (値1, 値2, 値3)
select * from table where 出金額 in (100, 299, 300);
select * from table where 出金額 not in (100, 299, 300);
 

ANY/ALL

ANYは値リストと比較して、いずれかが真なら真
ALLは値リストと比較して、全てが真なら真
式 比較演算子 ANY  (値1, 値2, 値3)
式 比較演算子 ALL  (値1, 値2, 値3)
select * from table where 出金額 < ANY (100, 200, 300);
select * from table where 出金額 > ALL (100, 200, 300);
 

AND/OR

条件式 AND 条件式
条件式 OR 条件式
select * from table 出金額 < 100 AND 出金額 > 50;
select * from table 出金額 = 100 OR 出金額 = 50;
 

論理演算子の優先順位

NOT>AND>ORの優先順位
 
例:下記は、条件式2 AND 条件式3をまず評価
→その結果と条件式1 OR 条件式4を評価する。
SELECT * FROM 湊くんの買い物リスト
WHERE 販売店 = 'A' /* 条件式1 */
OR 販売店 = 'B' /* 条件式2 */
AND カテゴリ = 'ゲーム' /* 条件式3 */
OR カテゴリ = 'DVD' /* 条件式4 */
多分こうなってる→(販売店B AND ゲーム)OR 販売店A OR DVD
 
カッコで括ると優先順位を変えれる
SELECT * FROM 湊くんの買い物リスト
WHERE ( 販売店 = 'A' OR 販売店 = 'B')
AND ( カテゴリ = 'ゲーム' OR カテゴリ = 'DVD');
 

主キー

必ず何らかのデータが格納される。NOT NULL
他の行と重複しない。
 

複数列を主キーにする

例:氏名と生年月日を主キーにする
氏名だけだと重複するが、生年月日も含めれば重複しない。
 

検索結果を加工する

DISTINCT

重複行を除外する。
複数列指定の場合は全ての列の値が重複している場合のみ除外。
select distinct 列名 from table;
select distinct 列名1, 列名2 from table;//全ての列の値が重複している場合のみ。
 

ORDER BY

並び替え
ASC昇順
DESC降順
select column FROM table ORDER BY 出金額 DESC;
 
複数行指定での並び替え
最初に指定された列でまず並び替え、同じ値があれば次の指定で並び替え。
select column from table ORDER BY 入金額 DESC, 出金額 ASC;
※注意
並べ替えはDBに結構な負荷がかかる。
インデックスの併用を推奨。
DISTINCTとUNIONも並べ替えを行っていることがある。
 

LIMIT/OFFSET

先頭から数行だけ取得する。
LIMIT 取得行数 (OFFSET 先頭から除外する行数)
select * from table LIMIT 10;
select * from table OFFSET 20;
select * from table LIMIT 10 OFFSET 20; // 先頭20行を除き、21行目から30行目までを取得。
 

集合演算子

集合演算子が使える条件:
列数とデータ型が一致している事。
上記が一致していれば違うテーブルや列でもOK。

UNION

和集合

2つの検索結果を足し合わせたもの。
select 文1
UNION (ALL)
select 文2
デフォルトだとUNIONは重複行をまとめる。
UNION ALLにすると重複行も全てそのまま返す。
ちなみに列の数が同じテーブル同士じゃないとUNIONできない。

UNIONとJOINの違い

UNIONは行を足す。テーブルが下に伸びる。

JOINは列を足す。下にも横にも伸びる。

列は、tableA + tableB
行は、tableA × tableB

になる。

詳しくは下記を参考に。

テーブル結合ってなんなの?

 

EXCEPT/MINUS

参考:SQL EXCEPTのサンプル(差分を抽出する)↓
 
差集合。ある集合と別の集合の差。

あるセレクト文の検索結果に存在する行から、別のセレクト文の検索結果に存在する行を差し引いた集合。
select 文1
EXCEPT(ALL)
SELECT 文2
 
下記はテーブルAで取得した行とテーブルBで取得した行を全ての列の値で比較し、列の値がすべて一致する行は抽出しません。
→テーブルAのみにある行を抽出します。
select * from テーブルA
EXCEPT
select * from テーブルB
 
順番にも注意。
下記はテーブルBのみにある行を抽出します。
select * from テーブルB
EXCEPT
select * from テーブルA
 
※注意
OracleではEXCEPT使えず、MINUSを使う。
MySQLはどっちも使えない。
 

INTERSECT

積集合を求める。

2つのセレクト文に共通する行を集めた集合です。
select 文1
INTERSECT
select 文2
 

式と関数

式の種類

足し算
数値+数値・日付+数値
引き算
数値ー数値・日付ー日付
掛け算
数値*数値
/
割り算
数値/数値
|| or +
文字列の連結
文字列||文字列
 

select文で存在しない列を表示する

出金額, 出金額+200, 固定値という3つの列が表示される。
select 出金額, 出金額+200, '固定値'
from 家計簿;
 
出金額、200円増しの2つの列が表示。中身は200円増しの値。
select 出金額, 出金額+200 as 200円増し
from 家計簿;
 

CASE演算子

if文と同じ。
CASE 列や式 WHEN 値 THEN 値
WHEN 値 THEN 値 //elseif
ELSE 値 // else
END AS 列名
 
単純case式
=判定しかできない。
CASE gender
WHEN '男' THEN 1
WHEN '女' THEN 2
ELSE 99
END
 
検索case式
CASEの後にすぐWHENを書く。
=以外の比較演算子も使える。
CASE WHEN 入金額 < 5000 THEN 'お小遣い'
WHEN 入金額 < 100000 THEN '一時収入'
WHEN 入金額 < 300000 THEN '給料出たー!'
ELSE '想定外の収入です!'
END AS 収入の分類
 

関数

例:length関数
文字列の長さを表す。
LENGTH(引数)
SELECT メモ, LENGTH(メモ) AS メモの長さ
FROM 家計簿
 

ストアドプロシージャ

データベース世界における戻り値のない関数。

ストアドファンクション

データベース世界における戻り値のある関数。
 
参考:わかりそうでわからないストアドプロシージャ
 

よくある関数

length/len 文字列の長さ
trim/Ltrim/Rtrim 前後/左/右の空白除去
replace 指定文字置換
substring/substr 文字列の一部抽出
round 指定ケタで四捨五入
power べき乗
current_date/current_time 現在の日付/時刻
cast データ型変換
coalesce 最初に登場するNULLでない値を返す
 

関数の小技

「select 関数」で関数の動作を確認。
select length('あああ');// 表示結果は3
 

集計関数とグループ化

SELECT文でしか使えない
  • select文の選択列リスト部分○
  • having句の中○
  • where句の中×
集計関数の結果は必ず1行になる。
結果表がデコボコになる形はダメ(各列の行数が同じじゃないとダメ)
 

集計関数の種類

SUM

全行の値を足す。
数値。
NULLは無視。

max

各行の最大値を求める。
数値・文字列・日付。
NULLは無視。

min

最小値。
数値・文字列・日付。
NULLは無視。

avg

平均値。
数値。
NULLは無視。

count

行数をカウントする。
count(*)// NULLを含めて行数をカウント
count(列) // NULLを無視してカウント
count(distinct 列名) // 重複行を除いたカウント
 

グループ化

GROUP BY

GROUP BY 列名
 
SELECT 費目, SUM(出金額) AS 費目別の出金額合計
FROM 家計簿
GROUP BY 費目 --費目列でグループ化する
 

GROUP BYを増やすと分割されていく

SELECT 費目, 性別, SUM(出金額) AS 費目別の出金額合計
FROM 家計簿
GROUP BY 費目, 性別 --費目列でグループ化する
 
SUM(出金額)
↓費目列を追加
 
SUM(出金額)→ 費目1のSUM(出金額)
       → 費目2のSUM(出金額)
↓ 性別列を追加
 
SUM(出金額)→ 費目1のSUM(出金額)→費目1の性別:女のSUM(出金額)
                    →費目1の性別:男のSUM(出金額)
 
       → 費目2のSUM(出金額)→費目1の性別:女のSUM(出金額)
                    →費目1の性別:男のSUM(出金額)
 
こんな感じでどんどん枝分かれしていくイメージ。  
1本の枝が2本、4本、8本と2の2乗で枝分かれしていく。
 

HAVING

集計後・グループ化後に絞り込む。
SELECT 費目, SUM(出金額) AS 費目別の出金額の合計
FROM 家計簿
GROUP BY 費目
HAVING SUM(出金額) > 0 --合計値が0 より大きいグループを抽出
whereとやってることは同じ。
whereは集計・グループ化前に絞り込み。
havingは集計・グループ化後に絞り込み。
 

副問い合わせ

ほかのSQL文の一部分として登場するSELECT文。
SELECT 列名 FROM table
WHERE 列名 = (SELECT MAX(金額) FROM table2)
 

副問い合わせ処理のしくみ

副問い合わせ⇒主問い合わせの順に処理される。
副問い合わせの中に副問い合わせも書ける。
 

副問い合わせのパターン

得られる結果はこの3つ。

単一の値(スカラー

単一の値として扱う。
where 列 = (副問い合わせ)

n行1列(ベクター)

複数の値として扱う。
where 列 any < (副問い合わせ)
where 列 all < (副問い合わせ)
where 列 in(副問い合わせ)

n行n列(マトリックス)

テーブルとして扱う。
select * from (副問い合わせ)
insert into (副問い合わせ) values ~
update (副問い合わせ) set ~
 
特殊な例
insert文の特殊構文。
INSERT INTO 家計簿集計テーブル(費目, 合計, 平均, 回数)
-----ここから先がVALUES以降の記述に相当する。------
SELECT
FROM 家計簿テーブル
SELECT 費目, SUM(出金額), AVG(出金額), 0
WHERE 出金額 > 0
GROUP BY 費目
----------------------------------------------
 

副問い合わせからNULLを除外する

SELECT * FROM 家計簿アーカイブ
WHERE 費目 IN (SELECT 費目 FROM 家計簿
WHERE 費目 IS NOT NULL)
 
SELECT * FROM 家計簿アーカイブ
WHERE 費目 IN (SELECT COALESCE(費目, 'ぬるぽ') FROM 家計簿) // NULLをぬるぽにする
 

テーブルの結合

いくつでもテーブル結合可能。
select 列
from tableA
join tabaleB
on 結合条件
join tableC
on 結合条件
join ~
 
SELECT 日付, 費目名
FROM 家計簿
JOIN 費目 -- 結合する他の表を指定
ON 家計簿.費目ID = 費目.ID -- 結合条件を指定
 

結合の処理イメージ

tableAの1行目に結合すべきtableBの行はどれかな?
というのを1行ずつ順番に処理するイメージ。
select *
from tableA //テーブルAに対して
join tableB //テーブルBを結合
on tableA.ID = tableB.ID //テーブルA.ID=テーブルB.IDになるように1行ずつ。
 

結合相手が複数の場合

行数が増える。
ID
名前
1
山田
2
佐藤
⇕結合
会員ID
ランク
1
ゴールド
2
シルバー
1
ブロンズ
上記2テーブルを結合
select ID, 名前, ランク
from tableA
join tableB
on tableA.ID = tableB.会員ID
山田さんが二人に増殖してしまう。
ID
名前
ランク
1
山田
ゴールド
1
山田
ブロンズ
2
佐藤
シルバー
 

結合相手の行がない場合

行数が減る。
ID
名前
1
山田
2
佐藤
⇕結合
会員ID
ランク
1
ゴールド
上記2テーブルを結合
select ID, 名前, ランク
from tableA
join tableB
on tableA.ID = tableB.会員ID
佐藤氏の消失。
ID
名前
ランク
1
山田
ゴールド
 

行数が減ると困る時は?

左部外部結合(left outer join)

左表の行数が減らない。
結合相手がない時はNULLが入る。
select 列
from 左テーブル
left outer join 右テーブル
on 結合条件
 
ID
名前
1
山田
2
佐藤
⇕左部外部結合
会員ID
ランク
1
ゴールド
佐藤氏無事。
ID
名前
ランク
1
山田
ゴールド
2
佐藤
NULL
 

右部外部結合(RIGHT OUTER JOIN)

右表の行数が減らない。

完全外部結合(FULL OUTER JOIN)

左右表の全行出力。

外部結合と内部結合の違い

結合すべき行が見つからない時に
外部結合は行が消滅しない、内部結合は行が消滅する。

複数条件で結合

select 列
from tableA
join tabaleB
on 結合条件 and 結合条件2

3つ以上のテーブル結合の処理順

select 列
from tableA
join tabaleB //まずAにBを結合
on 結合条件
join tableC //その後にCを結合
on 結合条件

副問い合わせテーブルと結合

n行m列の副問い合わせと結合できる。
slect *
form tableA
join (select * form tableB)
on A = B;
 

外部キーと主キー

基本的にはtableAの外部キーとtableBの主キーを指定して結合することが多い。
主キーは
  • 主キーはタプル(行)の一意識別能力を持つ(重複しない).
  • 主キーは空値(NULL)を含まない
外部キーとは
  • 外部キーの値は,参照先のリレーションの主キーの値から選ばれる.
  • 外部キーは空値(NULL)を含むことが許される.
 
外部キーと主キーの例↓
tableA
ID(主キー)
会員ID(外部キー)
名前
1
1
山田
2
2
佐藤
⇕結合(ON tableA.会員ID = tableB.会員ID)
tableB
会員ID(主キー)
ランク
1
ゴールド
2
シルバー
ID
名前
ランク
1
山田
ゴールド
2
佐藤
シルバー

トランザクション

トランザクションとは一塊の処理。
トランザクションは仮の書き換えで、コミットするまで確定しない。
 
もし停電してDBが止まっても、電源入れ直すとロールバック処理が走るんだって。すげー。
 

テーブルの作成(CREATE TABLE)

create table テーブル名 (列名, 列名の型名)
create table ABC (ID INTEGER, 日付 DATE)
 

テーブルの削除(DROP TABLE)

drop table テーブル名
 

テーブル定義の変更(ALTER TABLE)

列の追加

alter table テーブル名 add 列名 型 制約

列の削除

alter table テーブル名 drop 列名 型 制約
 

代表的な制約

NOT NULL

NULLは許されない!

UNIQUE

一意。
重複は許されない!

CHECK

ある列の値が妥当かをチェックする。
check(ID >= 0) // IDが0以上かをチェック

主キー(primary key)

  • 主キーの値を指定すれば、どの1行かを完全に特定できる。(重複不可)
  • NOT NULL。

外部キー(foreign key)

  • 外部キーの値は,参照先のリレーションの主キーの値から選ばれる.
  • 外部キーは空値(NULL)を含むことが許される.
書き方1
create table テーブル名(
列名 型 REFERENCES 参照先テーブル名(参照先列名))
書き方2
create table テーブル名(
foreign key (参照元列名) references 参照先テーブル名(参照先列名)
 

権限の付与・はく奪(GRANT/REVOKE)

grant 権限名 to ユーザー名// 権限の付与
reboke 権限名 from ユーザー名 //権限のはく奪
 

データベースの知識を深めよう

インデックス(CREATE INDEX)

インデックスとはDBの索引情報。 インデックスをつけると検索が高速になる。  
 
create index インデックス名 ON テーブル名(列名)
drop index インデックス名
drop index インデックス名 on テーブル名 (mysqlの場合)
 

インデックスのデメリット

インデックス作成のため、ディスク容量を消費する。
データ変更するときにインデックスも同時に書き換える必要が出る。
そのためINSERT・UPDATE・DELETEの処理が増える。  
 

ビュー

SQL分を短縮するのが目的。
何度も呼び出すテーブルをビューとして登録する。  
create view ビュー名 as select文
drop view ビュー名
 

採番

追加する行に独自の番号を振る。

AUTO_INCREMENT

いつも使ってるやつ。
1から順に自動連番。

SEQUENCE

シーケンスではデフォルト値や、1回の採番で増やす値、最大値などのオプションが使用可能。
create sequence シーケンス名;
drop sequence シーケンス名;
 

バックアップ

ACID特性

原子性:処理が中断しても中途半端な状態にならない。
一貫性:データの内容が矛盾しない。
分離性:複数の処理をどう実行しても副作用がない。
永続性:記録した情報は消滅せず保持され続ける。  
 

2つのファイルをバックアップ

データベースの内容そのもの:処理が重い。低頻度。
ログファイルの内容:処理軽い。高頻度。 DBのログファイルには実行した全てのSQL文が載っている。  
 

ロールフォワード

ログファイルを使って、障害発生の直前までデータ更新を進めること。
更新をキャンセルするロールバックの逆。  
 

DB設計

DB設計の流れ

概念設計

管理すべき情報がどのようなものかを整理。
RDBを意識せずに洗い出し。
情報同士の関連も整理。

論理設計

概念設計で明らかになった各情報について、RDBを使う前提で構造を整理し具体化。
どんなテーブルでどんな列を作るかまでを明らかにする。
ER図を作る。
型や成約などはまだ。

物理設計

特定のDBMS製品を使う前提で具体化する。
すべての列について型、インデックス、制約、デフォルト値など全ての要素を確定させる。
どんなSQL文を書くかまで落とし込む。
正規化もここでやる。
 

正規化

正規化の手順

非正規形→第1正規形→第2→第3

非正規形から第1正規形

・第1正規形の達成条件
テーブルのすべての行のすべての列に1つずつ値が入っている。
よって、繰り返しの列やセルの結合が現れてはならない。
 
下記の社員テーブルを第1正規形にしよう。
 
社員テーブル
部署番号
部署名
社員番号
社員名
役職コード
役職名
年齢
D1
開発1部
107
L
主任
31
121
R
一般
22
122
浅香あゆみ
R
一般
24
D2
開発2部
107
L
主任
31
112
C
副主任
29
 
1,繰り返し列を切り出す(行結合してない列のこと)
社員テーブルから繰り返し列を切り出し、社員番号テーブルを作る。
 
社員番号テーブル
社員番号
社員名
役職コード
役職名
年齢
107
L
主任
31
121
R
一般
22
122
浅香あゆみ
R
一般
24
107
L
主任
31
112
C
副主任
29
 
2,切り出し列の先から仮の主キーを選ぶ
社員番号列を主キーとする。
 
社員番号テーブル
社員番号
社員名
役職コード
役職名
年齢
107
L
主任
31
121
R
一般
22
122
浅香あゆみ
R
一般
24
107
L
主任
31
112
C
副主任
29
 
3,切り出し元の主キーをコピーし、切り出し先の複合主キーとする。
社員テーブルの部署番号をもってくる。
部署番号と社員番号の複合主キーとなる。
 
社員番号テーブル
社員番号
部署番号
社員名
役職コード
役職名
年齢
107
D1
L
主任
31
121
D1
R
一般
22
122
D1
浅香あゆみ
R
一般
24
107
D2
L
主任
31
112
D2
C
副主任
29
 
部署テーブル
社員テーブルから切り残された部分。
部署番号
部署名
D1
開発1部
D2
開発2部
これが非正規系から第1正規形への変形。
 
 

第1から第2正規形

・第2正規形の達成条件
複合主キーを保つテーブルの場合、非主キー列は複合主キーの全体に関数従属する。
よって、複合主キーの一部の列に対してのみ関数従属する列が含まれてはならない。
 

関数従属性

ある列Aの値が決まれば、自ずと列Bの値も決まるという関係。
このとき列Bは列Aに関数従属しているという。
 
例:金額が複合主キー(入出金ID+費目ID)に関数従属。
入出金ID+費目IDが確定すると金額が確定する。
入出金ID
費目ID
費目名
金額
41001
H01
住居費
65000
41001
H07
手数料
525
 

部分関数従属

穢らわしい関数従属のことw
複合主キーの一部の列にしか関数従属しないこと。
 
例:費目名が費目IDだけに関数従属。
費目IDだけが決まれば費目名が確定する。
入出金ID
費目ID
費目名
金額
41001
H01
住居費
65000
41001
H17
手数料
525
 
社員番号テーブルを第2正規形に変形しよう。
 
社員番号テーブル
社員番号
部署番号
社員名
役職コード
役職名
年齢
107
D1
L
主任
31
121
D1
R
一般
22
122
D1
浅香あゆみ
R
一般
24
107
D2
L
主任
31
112
D2
C
副主任
29
 
1,部分関数従属している列を切り出す。
 
社員テーブル
社員名
役職コード
役職名
年齢
L
主任
31
R
一般
22
浅香あゆみ
R
一般
24
L
主任
31
C
副主任
29
 
2,部分関数従属先の列をコピーし、主キーとする。
 
社員テーブル
社員番号
社員名
役職コード
役職名
年齢
107
L
主任
31
121
R
一般
22
122
浅香あゆみ
R
一般
24
107
L
主任
31
112
C
副主任
29
 
社員番号テーブル(切り残された部分)
社員番号
部署番号
107
D1
121
D1
122
D1
107
D2
112
D2
 
部署テーブル(ここはそのまま)
部署番号
部署名
D1
開発1部
D2
開発2部
これで第2正規形になった。
 

第2から第3正規形へ

第3正規形の達成条件
テーブルの非キー列は、主キーに直接関数従属すべきである。
よって、主キーに関数従属する列にさらに関数従属する列は存在してはならない。
 

推移関数従属

穢らわしい関数従属2w
主キーに対する間接的な関数従属。
 
例:きれいな関数従属
利用者IDが主キー入出金IDに関数従属。
入出金IDが決まれば利用者IDが決まる。
入出金ID
費目ID
利用者ID
利用者名
41001
2021/4/16
1
41001
2021/4/10
2
橘工事
 
例:推移関数従属
利用者名が利用者IDに関数従属。
そして利用者IDは入出金IDに関数従属。
つまり利用者名が入出金IDに間接的な関数従属。
入出金ID
費目ID
利用者ID
利用者名
41001
2021/4/16
1
41001
2021/4/10
2
橘工事
 
1,間接的に主キーに関数従属する列を切り出す。
社員テーブルから役職名列を切り出す。
 
役職テーブル
役職名
主任
一般
一般
主任
副主任
 
2,直接関数従属先だった列をコピーする。
 
役職テーブル
役職コード
役職名
L
主任
R
一般
R
一般
L
主任
C
副主任
 
社員テーブル
社員番号
社員名
役職コード(FK)
年齢
107
L
31
121
R
22
122
浅香あゆみ
R
24
107
L
31
112
C
29
 
部署テーブル
部署番号
部署名
D1
開発1部
D2
開発2部
 
部員テーブル
部署番号(FK)
社員番号(FK)
D1
107
D1
121
D1
122
D2
107
D2
112
 

最終的なER図

 

 

AWSメモ

 

料金アラート

無料枠があるからといって安心してはいけない。
枠内のはずなのになんか課金された。
 
・アラート設定方法
AWSマネジメントコンソール右上のアカウント名→
→マイ請求ダッシュボード
→Budgetsで予算を作成しよう。
予算超えたらメール来る。

 

参考動画

とにかくAWS公式動画が素晴らしいのでそれを見よう。
AWS公式の動画リンクは貼るとまずいのでEvernoteに貼った。
上から順にみると良い↓
 
AWS初心者向け】AWS学習方法まとめ【15時間で達成できる】
 
AWSハンズオンはじめの一歩:AWSアカウントの作り方&IAM基本のキ
 
AWS初心者向け Webinar 料金編 
 
AWSご利用開始時に押さえておきたい10のこと
 
AWS設計のベストプラクティスで最低限知っておきたい10のこと(上級者向け)
 
スケーラブルウェブサイト構築編(ハンズオン)
 

用語

  • SLA service lebe agreement サービス品質に関する取り決めのこと。提供社と受取社で決める。
  • SLA99.9%とは SLAを満たす状態=稼働状態 稼働状態を99.9%維持できますよということ。
  •  telnet コンピュータの遠隔操作
  •  SSH telnetの強化版。通信の暗号化。
  •  SSHクライアント teratermとかのこと。
  •  VPN virtual private network。仮想専用線。以前は物理的な専用線を用意して2点間をつないでいた。これを仮想的にインターネット上に作る仕組みのこと。例えば自社と取引先の専用線など。
  • VPC  AWSの仮想ネットワークの事。EC2とかRDSの入れ物。
  • VPCからネット接続はinternet gateway 
  • EC2 サーバ
  • RDS RDBサーバ
  • サブネット IPアドレス
  • クライアントからVPCへの接続はVPNゲートウェイ 
  • NAT 外部からのネット接続不可にする。内部からのネット接続は可。グローバルIPとプライベートIPの変換。
  • インスタンス。仮想サーバの単位。
  • AMI。インスタンス起動に必要な情報の塊。
  • AMIの作成→登録をしたら それを利用して新しいインスタンスを利用できる。
  • EBS。仮想外付けHDD。EC2は停止するとデータ消えるのでバックアップに。
  • S3。ストレージ。EBSとどう違うの?simple strage service
  • EBS と S3 の違い  EBSはEC2インスタンスへ直接接続。高速。容量少ない。
  • S3ではEC2インスタンスにアタッチすることはできません。低速。容量制限なし。
  • IAM AWSのユーザアカウント。細かく権限管理できる。 
  • ELB。ロードバランサ。トラフィックの負荷を自動的に分散。EC2が1つなら基本はいらない。
  • Iaas infrastructure as a service サーバ、コンピュータ、ストレージをクラウドで提供。
  • Paas platform as a service ハードウェアとOSをクラウドで提供。 
  • SaaS software as a service 普通のウェブアプリのこと。 

情報学へのとびら

放送大学情報コースの科目、情報学のとびらで学んだことのまとめ。

基本情報試験の範囲と近い。

教科書がわかりやすくてよかった。

授業はこれから見る予定。

1、情報化する社会を生きる

本科目の目的
  1. 情報リテラシー・ICTリテラシーの知識の習得
  2. 情報学の包括的な理解
 

2、情報デジタル表現とマルチメディア

デジタル情報処理の流れ

物理量→符号化→数値(列)→計算→数値(列)復号→物理量
 
デジカメに当てはめるとこんな感じ?
写真撮る(物理量)→符号化→数値(列)としてデータ保存→撮った写真を見る→計算→復号→画像表示(物理量)
 

符号化とは

符号化は情報の一面のみに着目した抽象化が行われる。
たとえば、文字は固有の番号(文字コード)に置き換えられる。
現実には文字情報には大きさや色、書体なども含まれているが、符号化ではこれらの情報は省かれる。
 
・標本化
電気信号を一定の時間間隔(周期)で計測すること。
計測の瞬間以外の情報はすべて捨てている。
例:音声の標本化
1秒間で100回音圧を計測。
 
標本化した値を一定の精度に丸めること。
例:標本化した値が36.944とする。
有効桁数3桁なら、四捨五入して36.9とする。
 

アナログ情報は劣化しやすい

例:写真の複製
撮った写真を現像して、またその写真を撮って現像を繰り返すと劣化していく
 

デジタル情報は劣化しにくい

誤り検出符号や誤り訂正符号でデータの誤りを防ぐ

誤り検出符号

誤りを検出する。
検出したらデータの再送依頼をして正確な情報を得る。
 
一定のビット数毎に1の数が奇数か偶数になるようにもう1ビットを加える方式。
例:1の数を偶数に
101100→1011001 1を加えて1の数を偶数にする。
110110→1101100 0を加えるので1の数は偶数のまま。
 
問題点:2つのビットが同時に誤っていた場合に誤りを検出できない。
例:110011→000011 どっちも1が偶数。
 

誤り訂正符号

検出するのではなく、訂正する。
例:元のビットを3つ連結する→1ビットごとに多数決で値を確定する。
1011→1011 1011 1011→1011で確定 全部正解
1011→0011 1011 1011→1011で確定 1桁目は0が1票 1が2票なので多数決で1になる
 
問題点:符号が3倍の長さになるので効率悪い。
たまたま同じ桁が誤っていたら訂正できない。
 

疑問:アナログとデジタルの境界とは?

例:音声のデジタル化の場合。
音をマイクで拾い、マイクの振動版を震わせ、その振動が電気信号に変換されて出力される。
その結果、音の波形と電気信号の波形が相似形になる。
ここまではアナログらしい。
電気信号に変換=デジタルだと思ってたけどそうじゃないみたい。
さらに標本化をするとデジタルになるようだ。
標本化によって捨てられる情報がある。
情報を削ぎ落すのがデジタル化?
アナログ:連続的
デジタル:離散的
離散的とは連続的ではないさま。数学で、値や数量がとびとびになっているさま。
 

3、コンピュータの構成要素とその機能

PCの構成要素

主記憶装置(メモリ)
中央演算装置(CPU)
入出力制御装置:周辺機器とのデータのやり取りの仲介
画像処理装置(GPU
その他の処理装置:音声処理装置やLANなど
バス:上記の装置間のデータのやり取りを行う通信経路
周辺機器:キーボード・マウスとか
チップセット:周辺素子をまとめたもの?
マザーボード:CPU・メモリ等の各装置を装着する基盤
I/O:CPUと周辺機器を接続し、データを入出力する。キーボード、マウス、HDD、ネットワーク、スピーカーなどとの接続。

コンピュータにおける計算の原理

否定(NOT)、論理積(AND)、論理和(OR)をいい感じに組み合わせると四則演算ができるらしいぞ。

2の補数

2進数で負の値を表現するためのもの。
10進数は数字の先頭に「-」を付けることでマイナスを管理(表して)いますが、2進数先頭1ビットが「1」の場合にマイナスであることを表します↓
2進数(4ビット)表現
2の補数
普通の2進数
0000
0
0
0001
1
1
0010
2
2
0011
3
3
0100
4
4
0101
5
5
0110
6
6
0111
7
7
↓ここから先が重要
先頭ビットが1のものは負とする↓
ここからも1ずつ増えていく↓
1000
-8
8
1001
-7
9
1010
-6
10
1011
-5
11
1100
-4
12
1101
-3
13
1110
-2
14
1111
-1
15
2の補数は2進数の符号を逆転する場合に使用する計算方法です。
・2の補数の出し方:ビットを反転して1を足す。
 10進数のー12=1100→0011+0001→0100
・2の補数と2進数の計算
例:4+(-2)
 0100 + 1110 =1 0010
 →溢れた1は取り除くと0010
 →答えは0010=2
・原理
 2の補数と元の2進数を足すと必ず0になる。
 N(元の2進数) + N2(2の補数)=0
 なので「N2=-N」ということになる。
 
 例:3
 0011+1101=1 0000 = 0
 こんな感じで必ず桁あふれで0になる。 
 

4、インターネットの歴史と仕組み

回線接続からパケット交換へ

昔の電話は2地点を電線で繋いで、アナログで音声を送っていた。
全ての家庭を直接電線で接続するのは不可能なので、電話局に交換盤を置いた。
交換盤を手動で繋ぎ変えて電話を繋いでいたらしい。
おもしろー。
 
交換盤にも限界があったので、1つの回線で異なる相手と通信できる方法が必要になった。
それがパケット通信方式。
送りたいデータを細かく分割し、データ自体に宛先情報を持たせた。
この1つの細かいデータをパケットという。
 

インターネットのパケット配送方式

パケットが持つ宛先とはIPアドレスのこと。
パケットがルータに送られるとバケツリレー方式で宛先に届く。

ルータの働き

パケットがルータに届く
→宛先が自分のネットワーク内ならそこに届ける
→他のネットワークなら経路表を元に隣接ルータに投げる
→経路表にもなかったらデフォルトゲートウェイに投げる

経路表(ルーティングテーブル)とは

IPアドレスの対照表とデフォルトゲートウェイが記入されたもの。
経路表は常に更新されていて、通信障害があっても迂回路を選択できる。
具体的には、
  1. 代表ルータに向けて各ルータが接続状態などの情報を送る。
  2. 代表ルータがその情報を元にネットワーク全体の地図を作り、各ルータに送る。
これを常にやっているらしい。すごすぎない?

ルータのさらに先は?

ルータ→中小プロバイダ→上位プロバイダ→インターネットエクスチェンジ(高速通信施設)
→再び上位プロバイダ→海底ケーブル!→海外へ
 

DNS(Domain Name System)による名前解決

DNSとはインターネットの住所録。
IPアドレスは数字の羅列でわかりづらいから、URLに変換する。
DNSドメインの階層構造に基づいて、1つのDNSサーバが1つの階層を受け持つ。
例えばwww.ouj.ac.jpなら下記の通り。
www.ouj.ac.jpへの問い合わせはキャッシュサーバ→ルートサーバ→jpサーバ→acサーバ→oujサーバと辿っていく。
 

インターネットの応用

さまざまなプロトコル

OSI参照モデル

番号が若いほど下位層。物理が最下位。アプリが最上位。
  1. 物理層:電圧や電波の周波数など物理的なプロトコル
  2. データリンク層:同一ネットワーク内で接続された通信機器とのデータ通信に関わるプロトコル
  3. ネットワーク層:ネットワークをまたがったデータ通信に関わるプロトコル。IPはココ。
  4. トランスポート層:データの信頼背の確保に関わるプロトコルTCPはココ。
  5. セッション層:通信相手との論理的な通信路の確立に関わるプロトコル
  6. プレゼンテーション層:データの表現形式の変換に関わるプロトコル。テキストや画像等の変換・逆変換。
  7. アプリケーション層:メールやうぇぶなどの特定の高度なデータ通信サービスに係るプロトコル。HTTP/SMTP/POP/IMAPはココ。
このような階層化を行い、上層及び下層とのデータ受け渡し方法を厳密化しておくことで、他の層に影響を与えずにプロトコル交換が可能になっている。
 

データのカプセル化

下位層→上位層
各層では、上位層より受け取ったデータに何も手を加えず、ヘッダと呼ばれるデータを付加し、それを下位層にわたす。
ヘッダにはその層で必要となる情報が入っている。
上位層から来た荷物を開けずに、その上からその層独自の梱包をかぶせて下位層に送るイメージ。
 
上位層→下位層
各層が下位層から受け取ったデータのヘッダ部を解析してからヘッダ部を除去して、適切な上位層のプロトコルに渡す。
これは下位層から来た荷物を開梱して中身だけを上位層に送るイメージ。
ある階層のプロトコルにとってみれば、それより下位層のプロトコルに関する情報は除去されているので、下位層のことを気にしなくてよい。
そのため各階層のプロトコルが交換可能になっている。
 
TCP: transmission control protocol。パケットの順番をそろえ、必要に応じて再送要求を行って完全なデータを復元する。
誤り検出や誤り訂正を行っているのかな?
 
UDP: user datagram protocol。パケットの誤り検出はするが訂正せずに破棄する。パケットの順番も気にしない。
データの正確性は低いが高速通信が可能。
 
ポート番号:パケットにポート番号という16ビットの数値を付けて、どのプログラムによって送受信されたか識別する。
例えば、IPアドレスだとPCまでは届く。
しかし、どのプログラムに届ければいいかわからないのでポート番号を使う。
 

情報セキュリティ技術

情報セキュリティ

機密性:許可されたものだけが情報にアクセスできること。
完全性:情報が正確で完全である事。
可用性:必要な時に情報にアクセスできること。
 

脆弱性

バッファオーバーフロー:プログラムが想定して否大きなデータが入力された時、データ用に確保していたメモリ領域を超えてデータが格納され、プログラムに書きかえが生じる恐れがある。
インジェクション:XSSSQLインジェクション。タグやSQL文の埋め込み。
DNSキャッシュポイズニング:DNSIPアドレスDNSキャッシュサーバに一時記憶する。キャッシしてあるホスト名とIPアドレスの対応情報を書きかえる。
マルウェア:コンピュータウイルス、ワーム、スパイウェア等の不正な行為を行うソフトウェアの総称。
  • ウイルスはプログラムやファイルに寄生して不正行為を行う。自己伝染・潜伏・発病機能の内1つ以上を持つもの。
  • ワームは寄生せずに単独実行可能なプログラム。
  • ボットは本来検索エンジンの情報収集を行うソフトウェア。DDoS攻撃を行うこともある。
  • トロイの木馬:正常な機能を持ったソフトウェアを装い、その裏で不正を働く。
  • スニファ:ネットワーク上のパケットをモニタする機器あるいはソフトウェアで、本来はネットワークの管理や研究開発用。盗聴に使用されることがある。
 

暗号

共通鍵暗号方式

暗号化のためのカギと復号化のためのカギが同一の暗号方式のこと。
例:アルファベットの暗号化
アルファベットを1文字ずらして暗号化する。
復号化するときも同じ。
japan→kbqbm
kbqbm→japan
 

公開鍵暗号方式

暗号化用と復号化用のペアになる鍵が生成される。
一方のカギで暗号化した暗号文はもう一方のカギでしか復号化できない。
暗号化した鍵では復号化できない。
また、一方のカギからもう一方のカギを生成、推測もできない。
つまり秘密鍵は復号化のみ。公開鍵は暗号化のみ。
例:Aさんが鍵のペアを生成。
→一方は秘密鍵として自分で保管
→一方は公開鍵としてBさんに渡す
→Bさんは公開鍵で文書を暗号化
→Aさんは秘密鍵で文書を復号化
→公開鍵が盗まれても、復号化できないから問題なし。
秘密鍵だけが盗まれなければ良い。
 

電子署名

公開鍵暗号方式電子署名にも利用される。
電子署名は、署名が本人のもので、メッセージに改ざんがないことを証明する。
電子署名はあくまでも本人確認が目的で、盗聴防止などはできないっぽい。(平文を送信するから)
例:Aさんの電子署名
Aさんはメッセージをハッシュ化する
→ハッシュ化されたメッセージ(メッセージダイジェスト)を秘密鍵で暗号化する
→この暗号化されたメッセージダイジェストが電子署名になる
秘密鍵で暗号化されているから、これを作成できるのはAさんのみという証明になる
→Bさんに電子署名とハッシュ化前の平文を渡す
→Bさんは平文をハッシュ化しメッセージダイジェスト生成
→さらにAさんの電子署名を復号化しメッセージダイジェストを得る
→2つのメッセージダイジェストが一致すれば改ざんがないことを確認できる
 

公開鍵基盤

公開鍵のなりすましを防ぐ仕組み。
Aさんから受け取った公開鍵が本当にAさんの物かを証明するもの。
認証局が本物であるという証明書を発行する。
HTTPSで使われている。
例:認証局がAの公開鍵を証明する
→BさんからAさんにデータを送りたい
→Aさんは認証局から証明書を受け取りBさんに送る
→Bさんは認証局の公開鍵で証明書の電子署名を検証
→その後にBさんはAさんの公開鍵でデータを暗号化しAさんに送信
 

プログラミング

プログラミング言語の変換方式

コンパイラ方式:プログラムを実行する前にソースコード全体を一度に機械語に変換する。
インタプリタ方式:ソースコードを逐次解釈し実行する。
中間言語方式:実行前にソースコードをCPUに依存しない中間言語コンパイルする。
実行時には仮想機械により解釈、実行される。
 
参考:5分で分かる教養としての低レイヤ -どうしてプログラムは動くのか(アセンブリ言語インタプリタJITコンパイラ)
 

OSによるハードウェアの抽象化

OS様々なハードウェアを抽象化している。
ユーザーにGUI操作を提供しているだけやないんやで。

CPUの抽象化

OSは短い間隔で実行するプログラムを切替えて、同時実行しているように見せている。
 

メモリの抽象化

物理的なメモリが細切れになっていると都合が悪い。
そこで仮想的なメモリアドレスを作り、細切れのメモリを繋ぎ合わせて仮想メモリとする。
 

補助記憶装置(HDD/SSD/DVD等)の抽象化

ファイル・ディレクトリ。
データをファイルとして統一的に扱えるように抽象化する。
ディレクトリ・フォルダによる階層化も抽象化である。
 

周辺機器の抽象化

周辺機器との接続はI/Oを通じて行われる。
例えば、プリンタなどは多くの製品があるが、プリンタなら製品に関わらずプリンタとして扱えるようにする。
 

APIとライブラリ

ハードウェアや他プログラムの隠ぺい。
プログラミングに置いてOSの機能を利用するにはOSが提供するアプリケーションプログラミングインタフェースAPI)を利用する。
APIを利用することによりハードウェアの詳細や同時に実行するほかのプログラムを意識せずプログラミンすることができる。
 

BIOS

ハードウェアの操作。
Basic Input /Output System
周辺機器の操作、I/Oの操作はOSではなくBIOS
BIOSはOSを含めた他のプログラムにI/Oを介したハードウェアの基本操作機能を提供している。
BIOSの機能はUFEIに移行してきている。
 

抽象化まとめ

プログラム
ライブラリ:OSによるAPIの差異を隠蔽
API:OSの機能を提供
OS:ハードウェアを抽象化
BIOS:直接I/Oを操作
 

ユーザインタフェース

インタフェースとは

interfaceとはもともと界面という意味を持つ。
界面とは液体と気体、液体と固体と言った質の異なるものの境界面の事。

ハードウェアインタフェース

ハード⇔ハード
複数のハードウェアのあいだでデータを転送するときに互いをつなげるケーブルのコネクタ形状、データのフォーマット、送受信の約束事(プロトコル)といったもののことです。
USB・HDMIwi-fiなど。
例:入出力制御装置I/OはCPUと周辺機器をつなぐ。

ソフトウェアインタフェース

ソフト⇔ソフト
プログラム間のデータやり取りの手順や方式を決めたもの。
OSが提供するAPIはソフトウェアがOSの機能を利用するインタフェース。

ユーザインタフェース

ユーザ⇔機械
ユーザと機械の間で情報をやり取りする仕組み。
入力インタフェース:キーボード、マウス、タッチパッドなど。
出力インタフェース:ディスプレイ、プリンタなど。
 

データベース

リレーショナルモデル

リレーショナルモデルでは、データをいくつかのデータ項目の組み合わせで表現する。

リレーションスキーマ

リレーションの構造を規定している情報。

リレーション

表のこと?

タプル

行のこと?

属性

列のこと?

リレーションの演算

射影

特定の列のみを抜きだす。
値が重複する行は除かれる。
※普通のRDBでは重複も表示される。

選択

特定の行のみを抜きだす。

結合

テーブル同士の結合。

直積(CROSS JOIN)

何の条件も付けずに2つのテーブルを結合すること。
対象となる2つのテーブルから行を1つずつ取り出し、合わせたものを新しい行とする演算。
新しいテーブルの行数=Aテーブルの行数×Bテーブルの行数、となる。
 
参考:直積結合とは
 
例:2行と2行のテーブルで直積すると4行
山田
10歳
田中
15歳
⇕直積
東京都
神奈川
結果↓
山田
10歳
東京都
山田
10歳
神奈川
田中
15歳
東京都
田中
15歳
神奈川

正規化

情報の損失が怒らないようにデータの重複を排除する手法。
 

ソフトウェアの開発

開発手法

ウォーターフォールモデル

要求分析・定義
外部設計
内部設計
実装
テスト
 

要件定義

目的:お客さんの要望を聞き、どんな機能が必要かユーザーと合意すること。
ユーザ向けに説明するための物。
ユーザとの話し合いで必要機能を洗い出す。

外部設計(基本設計)

目的:ユーザ向けの仕様設計。
画面設計・操作方法・ハード/ネットワーク構成・DB設計・セキュリティ。
開発するソフトと外部とのインタフェースの設計。
外部とはソフトの利用者や他のソフトなどのこと。
ユーザの目に触れる部分・ハード/ネットワーク構成・DB・既存ソフトの選定。
  • ソフトウェアの実現方法:ハードウェアやネットワークの構成、使用する既存のソフトの選定。
  • ソフトウェアの構成・構造:サブシステムへの分割方法、サブシステムの機能。
  • ユーザインタフェース:利用者が使うための画面設計。
  • データベース:DB設計。ER図を用いることが多い。

内部設計(詳細設計)

目的:実装者向けの設計。
外部設計で定めた仕様の実装方法を設計する。
仕様をどうコードに落とし込むかってところ。
外部設計はプログラミングを意識しない、内部設計は意識する。

実装

実装するw

単体テスト

目的:各機能の不具合検出。
各機能を1個ずつテスト。
例:検索機能のテスト。

結合テスト

目的:システム全体での不具合の検出。
各機能を組み合わせてテスト。
ここまでは開発環境で行うテスト。
例:登録機能+検索機能のテスト。
アカウント登録して検索でちゃんと出るか等。

総合テスト

目的:開発環境では見つからない不具合の検出。
本番に近い環境で行うテスト。
負荷テストとか。

受入テスト

目的:ユーザによる本番環境での不具合検出。
使用感の確認も目的の1つ。
ユーザが行うテスト。

リリース

納品すること。
ソフトウェアを1つのパッケージにまとめる。
バージョン番号を記載する。

アジャイル開発

アジャイル開発は特定の開発モデルではなく、様々な開発手法の総称!
知らなかった。
 

アドホックネットワーク

サーバーやアクセスポイント利用しないネットワークを指す。
アドホックad hoc)はラテン語で「一時的な、その場限り」の意。
「自立分散型無線ネットワーク」とも呼ばれる。
パソコン、携帯電話、タブレットなど、無線でネその場その場で動的に形成されるネットワークの事。
例:P2P無線LAN子機同士の接続。
 

ER図(実態関連図)の見方

 

 

PHPの基本

特徴

HTMLの中に記述できる

<body>
<?php $i = 10 ?>
</body>

インポート

基本的にはrequire_onceでよさそう。

require('test.php');
require_once('test.php');
include('test.php');
include_once('test.php');

PHPファイルのインポート↓ https://it.becrazy.jp/article/php-import

変数

変数名の前に$をつける。

$i = 10;

定数

const $j = 20;

関数

function hoge(hikisuu) {
// 何か処理
return ~ ;
}

引数と戻り値には型指定ができる 引数:string 戻り値:int

function hoge(string hikisuu): int { 
// 何か処理 
return ~ ; 
}

配列

$hoge = array(1, 2, 3); //配列宣言
$hoge[0]; // 配列の取り出し

配列の末尾に要素追加

$hoge = array(1, 2, 3); //配列宣言
$hoge[] = 4; 

配列の上書き

$hoge = array(1, 2, 3); //配列宣言
$hoge[2] = 4; 

連想配列

Javaでいう所のMapみたいなの。

$array = array('apple'=>'りんご', 'peach'=>'もも', 'pear'=>'なし');

appleがキーでりんごが値。

取出し

$array[apple]; // りんご

条件文

if,for,whileはJavaと全部同じ。

foreach文

普通の配列

$hoge = array(1, 2, 3); //配列宣言
foreach($hoge as $num) {
    echo $num;
}

連想配列

$array = array('apple'=>'りんご', 'peach'=>'もも', 'pear'=>'なし');
foreach($hoge as $key => $num) { echo $num;}
foreach($hoge as $num) { echo $num;} //省略バージョン。結果は同じ。

文字列

文字列の結合

ドット「.」でつなぐ

"あういうえお"."かきくけこ";

シングルクォートとダブルクォートの違い

ダブルは変数が展開される  シングルは変数が展開されない

$data1 = "サポートサイト\t「{$title}」へ<br />"; 
$data2 = 'サポートサイト\t「{$title}」へ<br />'; 
print $data1; //サポートサイト 「サーバサイド技術の学び舎 - WINGS」へ
print $data2; //サポートサイト\t「{$title}」へ

var_dump

エラー出た時、変数の中身を見るのに重宝する。

$x = ['a','b','c']; 
var_dump($x);

日付

$today = new DateTime(); 
print($today->format('Y年 m月 d日 (D) G時 i分 s秒')); // 2021年 03月 29日 (Mon) 11時 11分 17秒

クラス

class SampleClass 
{ 
    public function publicFnction() 
    { 
        print('public呼び出し'); 
    } 
} 
$sample_class = new SampleClass();  // newでインスタンス化
$sample_class->publicFnction();// インスタンスメソッド呼び出し

例外処理

Javaと同じ

try { 

} catch (Exception $e) { 

} finally { 

}

DB連携

PDO(PHP Data Object)

DB抽象化レイヤのこと。 これのおかげでどのDBにも似たような記述で接続できる。 PHPに標準装備されている。

DB接続

function getDb() { 
  $dsn = 'mysql:dbname=selfphp; host=127.0.0.1; charset=utf8'; 
  $usr = 'root'; 
  $password = 'password'; 
  
  //DB接続
  $db = new PDO($dsn, $usr, $password); 

  // 例外処理を有効化
  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  return $db;
  }

DB検索処理

function getDb() { 
  $dsn = 'mysql:dbname=selfphp; host=127.0.0.1; charset=utf8'; 
  $usr = 'root'; 
  $password = 'password'; 
   
  //DB接続 
  $db = new PDO($dsn, $usr, $password);  
  // 例外処理を有効化 
  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
  return $db; 
  } 
try { 
  //上記DB接続のgetDbメソッドでDB接続 
  $db = getDb(); 
  // 例外処理を有効化 
  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
  // 検索SQLプレースホルダで準備 
  $stt = $db->prepare("SELECT * FROM book WHERE title LIKE \'%?%\'"); 
  
  // 1個目の?のところにtitleが入る
  $stt->bindValue(1, $_POST['title']); 
  // SELECT命令を実行
  $stt->execute(); 

 //検索結果の取得 PDO::FETCH_ASSOCは連想配列で取得
  while($row = $stt->fetch(PDO::FETCH_ASSOC)) {
    $isbn = $row['isbn']
    $title = $row['title']
    $price = $row['price']
  }
  // 例外が発生したら、エラー表示 
} catch(PDOException $e) { 
  print "エラーメッセージ:{$e->getMessage()}"; 
} finally { 
  $stt = null; 
  $db = null; 
}

DB更新処理

function getDb() { 
  $dsn = 'mysql:dbname=selfphp; host=127.0.0.1; charset=utf8'; 
  $usr = 'root'; 
  $password = 'password'; 
   
  //DB接続 
  $db = new PDO($dsn, $usr, $password);  
  // 例外処理を有効化 
  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
  return $db; 
  }
try { 
  //上記DB接続のgetDbメソッドでDB接続 
  $db = getDb(); 
  // 例外処理を有効化 
  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
   
  // ドランザクションを開始 
  $db->beginTransaction(); 
  // 更新SQLプレースホルダで準備 
  $stt = $db->prepare('INSERT INTO book(isbn, title, price, publish, published) VALUES(:isbn, :title, :price, :publish, :published)'); 
  $stt->bindValue(':isbn', $_POST['isbn']); 
  $stt->bindValue(':title', $_POST['title']); 
  $stt->bindValue(':price', $_POST['price']); 
  $stt->bindValue(':publish', $_POST['publish']); 
  $stt->bindValue(':published', $_POST['published']); 
  // insert命令を実行 
  $stt->execute(); 
  // 全ての処理が完了したらトランザクションをコミット 
  $db->commit(); 
  // 例外発生したら、エラー表示&トランザクションをロールバック 
} catch(PDOException $e) { 
  $db->rollBack(); 
  print "エラーメッセージ:{$e->getMessage()}"; 
} finally { 
  $stt = null; 
  $db = null; 
}

HTML内での色々

phpタグ内でHTML文をつくる

echo or printするとHTML扱いになぜかなる。

<body>
<?php
for($i = 1; $i < 10; $i++) {
echo $i."
";
}
?>
</body>

phpタグ内でHTMLと変数を扱う

'{$変数}'

<?php
$i = abc
echo "<select name='{$i}'></select>";
?>

GET POSTをHTML内で受け取れる

$GET・$POST

//post送信
<form method="post" action="sent.php">
        <input type="text" name="name">
        <input type="submit" value="送信">
</form>
<body>
//post受け取り
<?php echo $_POST['name']; ?>
</body>

セキュリティ

XSS対策

基本的にGETやPOSTで受け取った値には、htmlspecialchars関数を使ってエスケープ処理をする。

例:XSS防止用のeメソッドを定義。

encode.php

<?php 
/** 
 * クロスサイトスクリプティング(XSS)防止用。 
 * ユーザー入力値をHTML表示する時に呼び出す。 
 * $str:エンコード対象の文字列 
 * #charset:エンコードタイプ 
 * ENT_QUOTES | ENT_HTML5:シングル/ダブルクォートを双方エスケープし、HTML5文書として処理。原則はこれ。 
 */  
function e(string $str, string $charset = "UTF-8"): string { 
  return htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, $charset); 
} 

eメソッドを使う

<?php
require_once("./encode.php");

print (e($_GET['name']);
print e($_GET['password']);

セッションID盗聴対策

ログイン後に新しいセッションIDを生成する。

// 新しいセッションIDを生成。セッション情報は保持される。
session_regenerate_id();

IPA安全なウェブサイトの作り方のP17を参照↓ https://www.ipa.go.jp/security/vuln/websecurity.html

パスワードの暗号化・ハッシュ化

1、ハッシュの生成

$password = "1234";
$hash = password_hash($password, PASSWORD_DEFAULT); //ハッシュパスワードの生成

2、ハッシュとパスワードの照合

$password = "1234"; 
$hash = password_hash($password, PASSWORD_DEFAULT);

// password_verifyで照合
if(password_verify($password, $hash)){ 
        print "照合成功"
      }

全角カタカナでLIKE検索すると半角カタカナの濁点・半濁点がヒットしない問題

utf8_unicode_ci

utf8_unicode_ciを指定すると半角カナ、全角カナ、ひらがな、カタカナを区別せず、かなり広範囲にわたってマッチするようになる。

濁点・半濁点が付いていても無視する。

SELECT * FROM hoge WHERE bigName collate utf8_unicode_ci LIKE '%keyword%'

ただし、全角半角カタカナの濁点、半濁点付きのLIKE検索はマッチしない。

例:全角カタカナ「プ」「ゲ」でLIKE検索すると半角カタカナ「プ」「ゲ」がヒットしない。逆もダメ。

じゃあどうするの?

REPLACEで濁点半濁点を消す。

SELECT * FROM skill WHERE(REPLACE(REPLACE(bigName, '゙', ''), '゚', '') collate utf8_unicode_ci LIKE REPLACE(REPLACE(?0, '゙', ''), '゚', ''))

REPLACEで2回くくって濁点と半濁点を消している。

できればやりたくない。

ちなみにイコール検索なら大丈夫。

MySQLのCollation

MySQLのCollationは下記が無難かと。

  • utf8mb4_general_ci
  • utf8mb4_bin

は ぱ ば を区別してくれます。

参考

qiita.com

tmge.hatenablog.com

qiita.com

結論

DBに半角カタカナを登録するのやめよう!

どうしてもって言うなら半角全角カタカナを混在させるのやめよう!!!

すごいめんどくさかった!!!!!!

もしくはutf8mb4_general_ciかutf8mb4_binを使おう。

【JavaScript】非同期処理の基本

非同期処理のイメージ

処理スタート

→非同期処理もスタート、でも完了は後回し

→先に同期処理が完了

→非同期処理が終わった順に完了

必ず、同期処理が先に完了する!

非同期処理の大前提!

非同期処理を実装するには、非同期的な処理をする関数を使うこと。

例えば

  • setTimeout()
  • fs.readFile()
  • Promise()
  • async function()
  • XMLHttpRequest.onreadystatechange

などのこと。

ネットで調べるとコールバック関数=非同期みたいに見えてしまうが、全然そんなことはないので要注意。

誤解を恐れずに言えば、コールバック関数・Promise・async/awaitは非同期処理を同期処理にする時に使う。

非同期でバラバラに完了すると困るから同期処理にしちゃいましょうねーという感じ。

・参考

JavaScript中級者への道【4. 非同期関数】

https://qiita.com/matsuby/items/3dd9cfca8c7b0685e474

JavaScript中級者への道【5. コールバック関数】

https://qiita.com/matsuby/items/3f635943f25e520b7c20

JavaScriptの非同期処理を理解する その1 〜コールバック編〜

https://knowledge.sakura.ad.jp/24888/

非同期処理の書き方4つ

とりあえず書き方だけ。それぞれの詳しいことは後述。

・普通に書く これ非同期処理なんです。

なぜならsetTimeout関数が非同期で動く関数だから。

同時に3つのsetTimeoutが動き始める。

function before(string) {
  console.log(string);
}

function sample() {
  setTimeout(before, 3000, 1);
  setTimeout(before, 2000, 2);
  setTimeout(before, 1000, 3);
}
sample();

・コールバック関数

setTimeout(function one() {
  console.log(2000)
  setTimeout(function two(){
    console.log(4000)
    setTimeout(function three() {
      console.log(6000);
    }, 6000);
  },4000);
},2000);

・Promise

function async(param){
  return new Promise(function(resolve, reject) {
  setTimeout(function(){
    resolve(param);
  }, 2000);
});
}

async(2000)
  .then(function(param){
    console.log(param);
    return async(4000);
  })
  .then(function(param){
    console.log(param);
    return async(6000);
  })
  .then(function(param){
    console.log(param);
  })
  .catch(function(error){
    console.log(error);
  });
  
  function foo() {
  return new Promise((resolve, reject) => {
    setTimeout(function(){
    resolve('A');
    }, 5000);
  });
}

・async/await

function test() {
  // 非同期処理
  return new Promise(function(resolve, reject){
    resolve(); // 成功。thenが呼ばれる
    reject(); // 失敗。catchが呼ばれる
  });
}

async function test2() {
  // 非同期処理の呼び出し。同期的に上から順に終わってから次の処理へ行く。
  await test();
  await test();
  return '成功';
}

test2().then(function() {
  // 成功時の処理
})
 .catch(function() {
   // 失敗時の処理
 });

非同期処理の不思議な所

必ず同期処理が終わった後に、非同期処理が完了するみたいだぞ。 ただし、非同期処理も裏では動いていて、同期処理が終わった瞬間、すでに完了済みの非同期処理も完了する。(意味不明な日本語だけどそんな感じなんだよ。)  下記コードを動かしてみるとよくわかる。  「8秒後に8000ミリ秒経過しました!と1と2」が同時に表示→その2秒後に3が表示

// 非同期処理
function sample() {
  setTimeout(before, 1000, 1);
  setTimeout(before,2000, 2);
  setTimeout(before, 10000, 3);
}

// 同期処理
function sleep(wait) {
  var start = new Date();
  // 指定ミリ秒間だけループさせる
  while (new Date() - start < wait);
  console.log(`${wait}ミリ秒経過しました!`);
}

function before(string) {
  console.log(string);
}

sample();
sleep(8000);
--------------------
(出力結果)
8000ミリ秒経過しました! 
1 
2
3

なぜコールバック関数で非同期処理を書くのか?

処理に順番をつけたいから。

  • 例1(順番を付けない)

下記コードはundeifinedが表示される。

なぜなら、必ず同期処理が終わってから非同期処理が完了するから。

つまり、同期処理であるconsole.log(hoge)が終わってから

→非同期処理のsetTimeout(function() {  hoge = 'hoge';}, 0);が完了するから。

let hoge; 
// 0秒後にhogeに文字列を代入する 
setTimeout(function() { 
  hoge = 'hoge'; 
}, 0); 
console.log(hoge);  // => undefined

非同期処理にコールバック関数で順番を付ける

  • 順番付けない例 1秒後に1→2秒後に2→3秒後に3が表示。合計3秒。 全てのsetTimeoutがほぼ同時に開始する。
function sample() { 
  setTimeout(before, 1000, 1); 
  setTimeout(before,2000, 2); 
  setTimeout(before, 3000, 3); 
}
  • 順番を付けた例 コールバックをネストする。 1秒後に1→その2秒後に2→その3秒後に3が表示。合計6秒。
setTimeout(function one() {
  console.log(1)
  setTimeout(function two(){
    console.log(2)
    setTimeout(function three() {
      console.log(3);
    }, 3000);
  },2000);
},1000);

つまり非同期処理を非同期じゃなくしてる感じ。 1が終わってから2、終わってから3。

非同期処理の何がうれしいのか?

重たい処理を非同期で裏でやってもろて、同期処理は先に進めとく。

setTimeout(function one() {
  console.log(1)
  setTimeout(function two(){
    console.log(2)
    setTimeout(function three() {
      console.log(3);
    }, 3000);
  },2000);
},1000);
console.log(4) //ここだけ同期処理
-----------------------
4
1
2
3

コールバック関数の引数の値ってどこからとってきてるの?

https://qiita.com/matsuby/items/3f635943f25e520b7c20#%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%AA%E3%81%84%E3%81%A8%E6%84%9F%E3%81%98%E3%82%8B%E6%B0%97%E6%8C%81%E3%81%A1%E6%82%AA%E3%81%95

例 fs.readFile() err,dataの値はいったどこからやってくるのか・・・。

fs.readFile('/etc/passwd', function(err, data) {
  if (err) throw err;
  console.log(data);
});

答え:高階関数(呼び出し元の関数)がとってくる

// showHogeに呼び出される高階関数 
// ここで引数に値を代入
function call(callback){ 
  let string = 'コールバック関数の引数に入る値'; 
  let string2 = ':2個目'; 
  callback(string, string2); 
} 
//ここだけ見ると、引数stringに何が入っているか謎。 
function showHoge() { 
  call(function(string , string2){ 
    console.log(string+string2); 
  }); 
} 
showHoge();  // => コールバック関数の引数に入る値:2個目

Promise

・参考 JavaScriptの非同期処理を理解する その2 〜Promise編〜

https://knowledge.sakura.ad.jp/24890/

JavaScript Promise の基本的な使い方

http://javascript.keicode.com/lang/promise-basics.php

・基本的な書き方

const promise = new Promise(function(resolve, reject) {
    //ここに非同期の重い処理を書く
    resolve('成功'); // 非同期処理成功時の処理
        reject('失敗'); // 非同期処理失敗時の処理
}

Promise の状態は以下のいずれかとなります。

  • 待機pending: 初期状態。成功も失敗もしていません。
  • 満足fulfilled: 処理が成功して完了したことを意味します。
  • 拒絶rejected: 処理が失敗したことを意味します。

満足するとthen()が実行され 拒絶されるとcatch()が実行される。

function async(param){
  return new Promise(function(resolve, reject) {
  setTimeout(function(){
    param += 500;
    
    if(param >= 2000) {
      resolve(param);
    } else {
      reject('failed.')
    }
  }, 2000);
});
}

async(2000)
  .then(function(param){
    console.log(param);
    return async(4000);
  })
  .then(function(param){
    console.log(param);
    return async(6000);
  })
  .then(function(param){
    console.log(param);
  })
  .catch(function(error){
    console.log(error);
  });

・流れ Promise内の処理が実行

→処理の結果をparamに渡す

 →(満足)then内の処理が実行

 →(拒否)catch内の処理が実行

thenはその時って意味だから、async().then()はasync関数が完了したその時ってことだね。

・Promiseはコールバックの入れ子構造

resolve/rejectにも関数が入る。

Promise(function(resolve, reject)

Promise(コールバック関数1(コールバック関数1-1, コールバック関数1-2)という入れ子構造。

  • コールバック関数1にはthen/catchが入る
  • コールバック関数1-1にはthenの中のコールバック関数が入る。
  • コールバック関数1-2にはcatchの中のコールバック関数が入る。

Promiseの理解が深まるかもしれないちょっと不思議な奴

return foo(B)ではなく、return 'B';なとこごポイント。 これはプロミスは1回しか呼んでないので、returnの値がそのまま次のthenに入ってるんだと思う。

function foo() { 
  return new Promise((resolve, reject) => { 
    resolve('A') 
  }) 
} 
foo() 
  .then((value) => { 
    console.log(`1st: ${value}`) 
    return 'B' 
  }) 
  .then((value) => { 
    console.log(`2nd: ${value}`) 
    return 'C' 
  }) 
  .then((value) => { 
    console.log(`3rd: ${value}`) 
  }) 
  .catch((reason) => { 
    console.log('catch!') 
    console.log(reason) 
  }) 
// 1st: A 
// 2nd: B 
// 3rd: C

Promise のチェインニング https://javascript.keicode.com/lang/promise-basics.php#4

・疑問 thenのreturn値が次のthenの引数に入っている。 これはthenに限らず、普通のメソッドチェーンでもそういうものなの? たとえばJavaではこんな風に書くけど引数は普通に指定してるもんね。

String str1 = "abc123abc123"; 
boolean str2 = str1.replace("abc", "0").contains("0");
System.out.println(str2); // true

Promiseの理解が深まるかもしれないちょっと不思議な奴2

下記は一見すると、thenのどこかで3未満になったらFailedを返すように見える。 しかし、実はそうではない。 getNumberが呼ばれているのが最初の1回だけなのがポイント。 つまり、Promiseが呼ばれているのも最初の1回だけ。 だから、最初の1回だけ if (num >= 3) の判定をしている。 だから最初が3以上なら、その後3未満になってもrejectにならない。

function getNumber(num) {
    return new Promise(function(resolve, reject) {
        // numが3以上ならnumを返し、3未満なら"Falied!"のメッセージを返す
        if (num >= 3) {
            setTimeout(function() {
                resolve(num);
            }, 1000);
        } else {
            reject("Falied!");    
        }
    });  
}

// 今回は3を渡しているので、resolveから3が返ってくる
getNumber(3).then(function(result) {
    console.log(result);
    //numに3を加算して、getNumberに返している
    return result + 3;
}).then(function(result) {
    //上と同じ処理の繰り返し。これがチェイン
    console.log(result);
    return result - 6;
}).then(function(result) {
    // 最終結果として、numに6を加算した数を表示
    console.log(result);
})
  .catch(function(error){
    // 3未満の場合はrejectが呼び出され、"Falied!"のメッセージが表示される
    console.log(error);
  });
-----------
3
6
0

もし、上記を修正してthenの途中でもエラー判定をするなら。 return result +3; →return getNumber(result + 3); に変更する。

getNumber(3).then(function(result) {
    console.log(result);
    //変更箇所。getNumberを呼び出している。
    return getNumber(result + 3);
}).then(function(result) {
    console.log(result);
    //変更箇所。getNumberを呼び出している。ここでエラー。
    return getNumber(result - 6);
}).then(function(result) {
    console.log(result);
})
  .catch(function(error){
    // 3未満の場合はrejectが呼び出され、"Falied!"のメッセージが表示される
    console.log(error);
  });
--------------
3
6
Failed!

Prmiseの例外処理

・catch/finallyをつけられる。

function async(param){ 
  return new Promise(function(resolve, reject) { 
  setTimeout(function(){ 
    param += 500; 
     
    if(param >= 2000) { 
      resolve(param); 
    } else { 
      reject('failed.') 
    } 
  }, 2000); 
}); 
} 
async(2000) 
  .then(function(param){ 
    console.log(param); 
    return async(4000); 
  }) 
  .then(function(param){ 
    console.log(param); 
    return async(6000); 
  }) 
  .then(function(param){ 
    console.log(param); 
  }) 
  .catch(function(error){ 
    console.log(error); 
  })
  .finally(function() {
   console.log('ファイナリー');
 })

Promiseの関数

・参考 Primiseの静的メソッド https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise#static_methods

Promise.all 全てのPromiseがresolveする、または1つでもrejectするとPromiseが返ってくる。 戻り値は配列。

unction one(){
  return new Promise(function(resolve, reject){
    setTimeout(() => {
    resolve(1000);
  }, 1000);
  });
}

function two(){
  return new Promise(function(resolve, reject){
    setTimeout(() => {
    resolve(2000);
  }, 2000);
  });
}

function three(){
  return new Promise(function(resolve, reject){
    setTimeout(() => {
    reject(3000);
  }, 3000);
  });
}

Promise.all([one(), two(), three()])
 .then(function(values){
   console.log(values);
 })
 .catch(function() {
   console.log('rejectだよ。');
 })
---------
1000, 2000, 3000

Promise.race Primise1つでもresolve/rejectするとPromiseを返す。

function one(){
  return new Promise(function(resolve, reject){
    setTimeout(() => {
    reject(1000);
  }, 1000);
  });
}

function two(){
  return new Promise(function(resolve, reject){
    setTimeout(() => {
    resolve(2000);
  }, 2000);
  });
}

function three(){
  return new Promise(function(resolve, reject){
    setTimeout(() => {
    resolve(3000);
  }, 3000);
  });
}

const promises = [one(), two(), three()];

Promise.race([one(), two(), three()])
 .then(function(values){
     console.log(values);
 });
 .catch(function() {
   console.log('rejectだよ。');
 });
------------
rejectだよ。

Promise.any Promiseが1つでもresolveする、または全てrejectするとPromiseを返す。 まだ実験段階で、対応ブラウザ少ない。

function one(){
  return new Promise(function(resolve, reject){
    setTimeout(() => {
    reject(1000);
  }, 1000);
  });
}

function two(){
  return new Promise(function(resolve, reject){
    setTimeout(() => {
    resolve(2000);
  }, 2000);
  });
}

function three(){
  return new Promise(function(resolve, reject){
    setTimeout(() => {
    resolve(3000);
  }, 3000);
  });
}

const promises = [one(), two(), three()];

Promise.any([one(), two(), three()])
 .then(function(values){
     console.log(values);
 })
 .catch(function() {
   console.log('rejectだよ。');
 });
----------------
2000

Promise.reject Promiseが成功か失敗か関係なく、即rejectを返すっぽい。テスト用?

function one(){
  return new Promise(function(resolve, reject){
    setTimeout(() => {
    resolve(1000);
  }, 1000);
  });
}

function two(){
  return new Promise(function(resolve, reject){
    setTimeout(() => {
    resolve(2000);
  }, 2000);
  });
}

function three(){
  return new Promise(function(resolve, reject){
    setTimeout(() => {
    resolve(3000);
  }, 3000);
  });
}

const promises = [one(), two(), three()];

Promise.reject([one(), two(), three()])
 .then(function(values){
     console.log(values);
 })
 .catch(function() {
   console.log('rejectだよ。');
 });

Promiseのよくわからないところ

function wait(time){
  const start = Date.now();
  while(Date.now() - start < time){
    }
  console.log(time + ' wait');
  }
  
  function waitAsync(time){
    return new Promise(function(resolve, reject) {
        const start = Date.now();
  while(Date.now() - start < time){
    }
  resolve(time);
    });
  }
  
   function waitAsync2(time){
    return new Promise(function(resolve, reject) {
        const start = Date.now();
  while(Date.now() - start < time){
    }
  resolve(time);
    });
  }

 waitAsync(1500)
  .then((time) => {
    console.log(time +' waitAsync')
  })

 waitAsync2(1000)
  .then((time) => {
    console.log(time + ' waitAsync2')
  })

wait(2000);
--------------
2000 wait 
1500 waitAsync 
1000 waitAsync2

なんでこんな順番になるんや・・・。 waitAsyncの処理で1.5秒経過(イベントキューに入る)→waitAsync2の処理で1秒経過(イベントキューに入る)→waitの処理で2秒経過、完了→waitAsync完了→waitAsync2完了ということ? イベントキューはイベントの待ち行列のこと。

https://knowledge.sakura.ad.jp/24888/

async/await

・参考 async/await 入門(JavaScripthttps://qiita.com/soarflat/items/1a9613e023200bbebcb3

・基本的な書き方

function test() {
  // 非同期処理
  return new Promise(function(resolve, reject){
    resolve(); // 成功。thenが呼ばれる
    reject(); // 失敗。catchが呼ばれる
  });
}

async function test2() {
  // 非同期処理の呼び出し。同期的に上から順に終わってから次の処理へ行く。
  await test();
  await test();
  return '成功';
}

test2().then(function() {
  // 成功時の処理
})
 .catch(function() {
   // 失敗時の処理
 });

・中身解説

// resolve1!!をreturnしているため、この値がresolveされる 
async function resolveSample() { 
    return 'resolve!!'; 
} 
// resolveSampleがPromiseを返し、resolve!!がresolveされるため 
// then()が実行されコンソールにresolve!!が表示される 
resolveSample().then(value => { 
    console.log(value); // => resolve!! 
}); 
// reject!!をthrowしているため、この値がrejectされる 
async function rejectSample() { 
    throw new Error('reject!!'); 
} 
// rejectSampleがPromiseを返し、reject!!がrejectされるため 
// catch()が実行されコンソールにreject!!が表示される 
rejectSample().catch(err => { 
    console.log(err); // => reject!! 
});

awaitとは

async function内でPromiseの結果(resolve、reject)が返されるまで待機する(処理を一時停止する)演算子のこと。 以下のように、関数の前にawaitを指定すると、その関数のPromiseの結果が返されるまで待機する。

async function sample(){
    const result = await sampleResolve();
    
    // sampleResolve()のPromiseの結果が返ってくるまで以下は実行されない
    console.log(result);}

awaitは何をするのか

  • awaitを指定した関数のPromiseの結果が返されるまで、async function内の処理を一時停止する。
  • 結果が返されたらasync function内の処理を再開する。

async/awaitのメリット

メリット1、thenを繋げないで済む。

・Promiseの例 thenが長い。

function async(param){ 
  return new Promise(function(resolve, reject) { 
  setTimeout(function(){ 
    resolve(param);
  }, 2000); 
}); 
} 
async(2000) 
  .then(function(param){ 
    console.log(param); 
    return async(4000); 
  }) 
  .then(function(param){ 
    console.log(param); 
    return async(6000); 
  }) 
  .then(function(param){ 
    console.log(param); 
  }) 
  .catch(function(error){ 
    console.log(error); 
  });

・async/awaitの例 then内で関数を呼ばず、awaitで関数を繰り返し呼ぶ。

function aaa(value) {
   return new Promise((resolve, reject) => {
     setTimeout(() => {
       resolve(value);
   }, 1000);
   });
 }
 async function bbb() {
   await aaa(1000);
   console.log(1000);
   
   await aaa(2000);
   console.log(2000);
   
   await aaa(3000);
   return 3000;
 }

bbb().then((value) => {
  console.log(value);
})
 .catch((value) => {
   console.log('fail');
 });

メリット2、ループ文で繰り返し実行できる

function sampleResolve(value) { 
    return new Promise(resolve => { 
        setTimeout(() => { 
            resolve(value); 
        }, 1000); 
    }) 
} 
async function sample() { 
    for (let i = 0; i < 5; i += 1) { 
        const result = await sampleResolve(i); 
        console.log(result); 
    } 
    return 'ループ終わった。' 
} 
sample().then((v) => { 
    console.log(v); // => 0 
                    // => 1 
                    // => 2 
                    // => 3 
                    // => 4 
                    // => ループ終わった。 
});

async/awaitの間違えやすそうなところ

同期処理が先に完了するので、let d = bbb(); はからっぽ。 thenしてあげよう。

function aaa(value) {
   return new Promise((resolve, reject) => {
       resolve(value);
   });
 }
 async function bbb() {
   const a = await aaa(1000);
   const b = await aaa(2000);
   const c =  await aaa(3000);
   return a + b + c;
 }
let d = bbb();
 console.log(d); // からっぽ
 bbb().then((value) => {
  console.log(value);
}); // こっちは6000

Promiseの戻り値には何が入ってるの?

resolve()の引数の値が入るみたい。

function aaa() {
   return new Promise((resolve, reject) => {
       resolve('abc');
   });
 }
 async function bbb() {
  const a = await aaa();
  console.log(a); // abc
 }
bbb();

なぜAjaxは画面更新せずに画面変更できるのか

よく考えたらイベントも画面更新してないよね・・・。 というかJavaScriptって基本画面更新しないよね。

btn.onclick = function() { 要素.style.color = 'red'; }

Ajaxもこれと同じだね。 Ajaxの場合はサーバーとの通信が入っているってだけだね。 なおかつ非同期なので、ユーザーは通信を待たずに済むね。 普通の通信はHTMLを丸ごと入れ替えてるから画面更新が入るね。ね。 ・初心者目線でAjaxの説明 https://qiita.com/hisamura333/items/e3ea6ae549eb09b7efb9

JavaScriptの基本

・参考 JavaScript の基本 https://developer.mozilla.org/ja/docs/Learn/Getting_started_with_the_web/JavaScript_basics

変数

変数宣言 let

JavaScriptは動的型付け言語。

let number = 9;
let string = 'あいうえお';
let boolean = true;
let boolean = false;
let boolean = 5 > 3;

String/int/booleanも全部let booleanはtrue falseのみを持つ。

定数宣言 const

const number = 10;

配列宣言

let myNameArray = ['Chris', 'Bob', 'Jim'];
let myNumberArray = [10, 15, 40];

オブジェクトの宣言

let dog = { name : 'ポチ', breed : 'ダルメシアン' };
dog.name // ポチ

テンプレートリテラル

文字列と変数をまとめて の中に書ける。 バッククオートで囲む。

const name = "あああ";
window.alert("こんにちは、" + name + "さん");//普通
window.alert(`こんにちは、'${name}さん`);// テンプレートリテラル

関数

関数宣言

戻り値の型指定いらない。

const function multiply(num1,num2) {
  let result = num1 * num2;
  return result;
}

関数呼び出し

multiply(4,7);
multiply(20,20);
multiply(0.5,3);

匿名関数

よくイベントハンドラで使われている。

function() {
  alert('hello');
}

コールバック関数

関数の引数に渡される関数のこと。 JavaScriptって引数に関数を渡せるんやで。 ここではcall()がコールバック関数。

function call() { 
  window.alert("コールバック"); 
}

//引数名()で渡されたメソッドを呼び出せる。
function abc(hikisuu) { 
  window.alert("イベントリスナー"); 
  hikisuu(); 
} 

abc(call);

※大事な事 コールバック関数ってのは別に非同期と全然関係ないんだ! 単純に関数の引数に渡される関数のことなんだぜ!!!

・参考 JavaScript中級者への道【5. コールバック関数】 https://qiita.com/matsuby/items/3f635943f25e520b7c20

コールバック関数を呼び出す側の関数は高階関数という。

条件文

演算子

イコール ===

ナットイコール !==

if

let iceCream = 'チョコレート';
if(iceCream === 'チョコレート') {
  alert('やった、チョコレートアイス大好き!');
} else {
  alert('あれれ、でもチョコレートは私のお気に入り......');
}

while

while(条件式){
}

for

for(変数の定義; 条件式; 変数の更新){}

for(let number i; i <100; i++){
}

イベント

let myHTML = document.querySelector('html');
myHTML.onclick = function() {
    alert('痛っ! つつくのはやめて!');
};

上記を略して書くとこう。

document.querySelector('html').onclick = function() {
    alert('痛っ! つつくのはやめて!');
}

イベントリスナーの種類

イベントハンドラーとイベントリスナーの違い

イベントハンドラー:  イベントに対して処理を定義したメソッド。

イベントリスナー:   イベントに対して処理を結びつける仕組み。

であり、概念としては異なるものです。

1 普通のイベント登録

const btn = document.querySelector('button'); 
btn.onclick = function() { 
  const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; 
  document.body.style.backgroundColor = rndCol; 
}

2 addEventListenerで登録

const btn = document.querySelector('button'); 
function bgChange() { 
  const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; 
  document.body.style.backgroundColor = rndCol; 
} 
btn.addEventListener('click', bgChange);
btn.addEventListener('click', function() { 
  const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; 
  document.body.style.backgroundColor = rndCol; 
});

・イベントリスナーの削除

btn.removeEventListener('click', bgChange);

・addEventListenerの利点 削除できる。 一つのイベントに複数の関数をセットできる。

myElement.addEventListener('click', functionA);
myElement.addEventListener('click', functionB);

3 イベントハンドラーHTML属性(インラインイベントハンドラー)で登録

リスナーじゃなくてハンドラーだけど一応紹介。 onXXXのこと。 HTMLにJavaScriptが混在するので非推奨。

<button onclick="alert('Hello);">Press me</button>

・onChange属性 →input要素で何かしら変更があったときにイベントが発生する。  例えば、セレクトボックス選択時、テキスト入力後のENTER押下時。

・onClick属性 onClick="function()" クリック時にJavaScriptの関数を呼び出す。

イベントオブジェクト

https://developer.mozilla.org/ja/docs/Learn/JavaScript/Building_blocks/Events ときどきイベントハンドラー関数内で event、evt、単に e などと名付けられた引数を見かけるかもしれません。 これらはイベントオブジェクトと呼ばれ、イベントの追加機能や情報を提供する目的でイベントハンドラーに自動的に渡されます。 例えば、またランダム色の例をちょっと書き換えてみましょう。

function bgChange(e) {
  const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
  e.target.style.backgroundColor = rndCol;
  console.log(e);
}

btn.addEventListener('click', bgChange);

イベントオブジェクト e が関数に含まれていて、関数内で e.target — これはボタンそのもの — の背景色スタイルを設定しているのがわかるでしょう。 イベントオブジェクトの target プロパティは、常にイベントが生じた要素への参照となっています。 ですからこの例ではページではなくボタンの背景色がランダムに変わります。

・イベントのバブリングとキャプチャリング 親子要素に同じイベント(btn.onClick()とか)をつけると順番に 発火しちゃって大変という話。