学習日記

学習記録

プログラムのパフォーマンスを考える

前書き

Rubyに置けるコードの効率性を考えてみました

現段階では小規模なコードを書いているので問題になりませんが、将来的に大規模なコードを書くときに思わぬところでボトルネックを生み出さないように訓練する一環です。

またこの記事はフィヨルドブートキャンプ内でdocsとして共有されていた題材を元にしています。

パフォーマンスの悪いコード

以下のようなプログラムを書きました

  • 1から30までの整数を30個ランダムに生成し、配列として保持します
  • 配列を順に出力していき、配列内の最小値、最大値の場合にそれを明示します
#!/usr/bin/env ruby

def main
  numbers = Array.new(30) {rand (1..30) }
  numbers.each do |n|
    puts "#{n}#{":最小値です" if min_calc(numbers) == n }#{":最大値です" if max_calc(numbers) == n }"
  end
end

def min_calc(numbers)
  sleep 0.5
  numbers.min
end

def max_calc(numbers)
  sleep 0.5
  numbers.max
end

main

sleepを入れているのは実行される度に処理が走っていることを実感するためです。 つまり処理の度に何回も関数を呼び出すのは、必要がなければやめたほうがいいということです。

実際このプログラムを起動してみると、かなりじれったい動作をすることが分かります

パフォーマンスの良いコード

これを変数に格納してしまい、以下のようなコードにすれば

#!/usr/bin/env ruby

def main
  numbers = Array.new(30) {rand (1..30) }
  min_number = min_calc(numbers)
  max_number = max_calc(numbers)
  numbers.each do |n|
    puts "#{n}#{":最小値です" if min_number == n }#{":最大値です" if max_number == n }"
  end
end

def min_calc(numbers)
  sleep 0.5
  numbers.min
end

def max_calc(numbers)
  sleep 0.5
  numbers.max
end

main

前のコードに比べて随分実行速度が速くなるはずです。

このコードの場合はそもそもメソッドに分割する意味はないですが、分かりやすいようにメソッドはそのままにしてあります。

ループ内で重い処理はできるだけ行わないように気を付けたいですね!

読書録:達人に学ぶDB設計徹底指南書

対象本

タイトル : 達人に学ぶDB設計徹底指南書

著者:ミック

前書き

筆者が達人に学ぶDB設計徹底指南書を読み、特に参考になった・記録に残しておきたい部分を自分なりにまとめた読書録になります。

第1章 データベースを制する者はシステムを制す

システムとデータベース

データ処理としてのシステム

  • 全てのシステムがデータを取り扱っている

    • メッセージアプリのメッセージや、ECサイトの顧客情報etc...
  • データを整合的に保持し、いつでも手軽に利用できるようにするのがデータベース

    • そのデータベースを管理するためのシステムがDBMS
    • ユーザーにはデータベースを意識させないよう隠蔽されている
    • 全てのシステムはデータを取り扱っている = 全てのシステムはデータベースを利用している

データベースあれこれ

データベースの代表的なモデル

  • リレーショナルデータベース(Relational Database : RDB)

    • 関連データベースとも呼ばれる
    • 現在最も広く利用されるDB
  • オブジェクト指向型データベース(Object Oriented Database : OODB)

    • データと操作をまとめてオブジェクトと呼ぶ
    • そのオブジェクトを保存するためのデータベース
  • XMLデータベース(XML Database : XMLDB)

    • XML形式のデータを扱うデータベース
    • 階層構造のデータを扱うのが得意
  • キー・バリュー型ストア(Key-Value Store : KVS)

    • 識別値(Key)と値(Value)を組み合わせた単純なデータを保存するデータベース
  • 階層型データベース(Hierarchical Database)

    • データを階層構造(木構造)で表現するデータベース
    • 現在あまり使われていない
  • データベースが変わるとデータのフォーマットも変わる

  • DBMSが異なっても基本的に設計の方針は影響を受けない

設計工程とデータベース

DOAPOA

  • 近年ソフトウェア開発で主流なのはデータ中心アプローチ(Data Oriented Approach : DOA)

  • かつての主流はプロセス中心アプローチ(Process Oriented Approach)

3層スキーマ
  • 外部スキーマとはユーザーから見たデータベース
    • 実際のデータベースはユーザーから隠す、ここでいうユーザーから見たデータベースとはデータベースを用いたデータが実際に表示される見た目の部分
  • 概念スキーマとは開発者から見たデータベース
    • テーブルを定義する、データの要素やデータ同士の関係
  • 内部スキーマとはDBMSから見たデータベース
    • どこにどのようなファイルを置くのか

概念スキーマ

  • 概念スキーマとは変更に対する柔軟性のために存在する
    • データの独立性を保証するためにある

第2章 論理設計と物理設計

概念スキーマと論理設計

  • 概念スキーマを定義する設計を、論理設計と呼ぶ
    • データベース設計の最初に行われ、物理層の制約は考慮されない
    • データベース設計は概念スキーマ、内部スキーマの順に行われる

論理設計のステップ

  1. エンティティの抽出
  2. エンティティの定義
  3. 正規化
  4. ER図の作成

エンティティの抽出

  • エンティティと言っても、物理的実体を伴う必要はない

  • システムのためにどのようなエンティティ(データ)が必要になるかを抽出する

エンティティの定義

  • 各エンティティがどのようなデータ(属性)を保持するか決める

  • 重要なのはkey列を定義すること

正規化

  • エンティティのフォーマットを整える

    • 更新が整合的に行えるように
  • 正規化を行う必要があるということは、エンティティを抽出し、属性を定義しただけではデータベースとして運用できないということ

ER図の作成

  • 中小規模のシステムでもエンティティは数十個、大規模だと数百個になる

  • こうした大量のエンティティ同士の関係を書いた、エンティティの見取り図をER図と呼ぶ

内部スキーマと物理設計

物理設計のステップ

  1. テーブル定義
  2. インデックス定義
  3. ハードウェアのサイジング
  4. ストレージの冗長構成決定
  5. ファイルの物理配置決定

テーブル定義

  • 論理設計で定義された概念スキーマをもとに、テーブルを作成する

インデックス定義

  • 機能的になくても問題ないが、インデックスが作られることでパフォーマンスが上がる

  • 本の索引のイメージで、ある単語を探す際に直接該当ページに飛んでくれるので、探す手間を省略してくれるので、パフォーマンスの向上に繋がる

ハードウェアのサイジング

  • サイジングはキャパシティとパフォーマンスの2つの観点から行う

  • データベースの性能問題の8割はディスクI/Oによって起きる

  • 実施時には安全率をかける

  • スケーラビリティの高い構成を組む

ストレージの冗長構成

  • データベースに保管されるデータは、業務の基幹データなので、失うことは許されない

  • 可能な限り高い耐久性を持たせるために[RAID]というシステムを使う

    • RAIDには組み方によって性能向上も狙える側面がある
  • RAID0はI/O性能は向上するが、冗長性は無い

  • RAID1は2本のディスクにまったく同じ内容を書き込む、冗長性は高まるが、性能は変わらない

  • RAID5は最低3本のディスクにデータとパリティを分散して書き込む。 冗長性と読み出し性能が高い

    • パリティを書き込む分、書き込み性能は良くないがデータベースでは読み出し性能のほうが重視されるケースが多い
  • RAID10はRAID1のシステムを2個作り、その2個でRAID0を作る

  • 財布が許すのであればRAID10が第一候補、少なくともRAID5が望ましい。

ファイルの物理配置

  • データファイル、インデックスファイル、システムファイル、一時ファイル、ログファイルがある

  • このうち開発者が意識するのはデータファイル,インデックスファイル

    • 他はデータベース管理者が基本的に管理する
  • データファイルは一番I/O量が多いので、独立した配置にすることが望ましい

バックアップ設計

完全/差分/増分

主要なバックアップ方式は以下の通り

  1. フルバックアップ(完全バックアップ)
  2. 差分バックアップ
  3. 増分バックアップ

どんなバックアップ方式を採用すべきか?

以下の条件を考慮して決める

  • いつの時点に復旧させるか、そもそも復旧の必要性はあるか?
  • バックアップに使用できる時間
  • リカバリに使用できる時間
  • 何世代分残すか

選択肢としては以下

基本的にはフルバックアップ+差分フルバックアップ+増分が選択されることが多い

リカバリ設計

リカバリとリストア

第3章 論理設計と正規化 ~なぜテーブルは分割する必要があるのか?

テーブルとは何か?

二次元表≠テーブル
  • テーブルとは共通点を持ったレコードの集合

    • でたらめなデータを表に押し込んでもテーブルではない
  • テーブルは英語ならば複数形/複数名詞で書ける

テーブルの構成要素

行と列

  • 列をカラム、行をレコードとも言う

キー

  • 主キーと外部キーがある

  • 主キーはプライマリーキーともいい、必ず存在しなければならず、かつ一つしか存在してはいけない。

  • 主キーとはその値を指定すれば必ず1行のレコードを指定できる列の組み合わせ

  • 外部キーは2つのテーブル間の列同士で設定する

  • 外部キーの役割は、親テーブルに存在しないデータが、間違って子テーブルに登録されないように防止すること

制約

  • 列の値がNULLのデータを受け付けないのがNOT NULL制約

    • 可能な限りNOT NULL制約を適用する
  • 列の値に一意性を求めるのが一意制約

  • 列の値のとりうる範囲を制限するのがCHECK制約

正規化とは何か?

  • データベースで保持するデータの冗長性を排除し、一貫性と効率性を保持するためのデータ形式

  • 正規形は第5レベルまであるが、通常は第3まで覚えればよい

第一正規形

第一正規形の定義~スカラ値の原則

  • 第一正規形の定義は[一つのセルの中には一つの値しか含まない]

第2正規形~部分関数従属

  • 主キーの一部の列に対して従属する列がある場合、この関係を部分関数従属と呼ぶ

  • 主キーの全てに対して従属する列がある場合完全関数従属と呼ぶ

  • 第2正規形とは、部分関数従属を解消し、完全関数従属のテーブルを作ること

第3正規形~推移的関数従属

推移的関数従属

  • Aが分かればBが分かる Bが分かればCが分かるというように2段階の関数従属があるのが推移的関数従属

  • これを解消させ、別テーブルに分離するのが第3正規刑

正規化についてのまとめ

正規化は常にするべきか?

  • 第3正規形までは原則行う

  • 関連エンティティが存在する場合は関連とエンティティが1対1になるよう注意する

  • 正規化を行うとテーブル数が増えるため結合を多用することになり、パフォーマンスが悪化する

第4章 ER図~複数のテーブルの関係を表現する

テーブル同士の関連を見抜く

1対1, 1対多, 多対多

同じ意味の列を持っているテーブル同士の間では、次の3パターンの関連がありえる

  • 1対1

    • 通常は見かけない
  • 1対多

    • 正規化によって生まれる関連はこのカテゴリに属す、もっともよく見かける。
  • 多対多

    • RDBでは作ってはいけない

多対多と関連実体

  • 多対多の関連を持ったエンティティを作る時、関連実体を用いて解消する
    • いわゆる中間テーブルを作成して1対多の関係を作る

第5章 論理設計とパフォーマンス~正規化の欠点と非正規化

正規化の功罪

  • 正規化はある意味で、情報を複数のテーブルに分散させる行為である

  • SQLにおける結合は非常にコストの高い操作であり、結合するテーブル数、及びテーブルのレコード数が増えるほど処理時間がかかる

    • 正規化することでパフォーマンスが悪化する原因の多くが、このSQLの結合操作にある
  • 一方で更新処理では細かくテーブルが分割されている正規化されたテーブルのほうが有利

    • しかしデータベースは読み出し処理のパフォーマンスが優先される傾向にある

正規化と非正規化、どちらが正解なのか?

  • 正規化と検索SQLのパフォーマンスは強いトレードオフの関係にある

  • 非正規化はあくまでも最後の手段

    • 設計という観点からはやはり高次の正規形が望ましい

第6章 データベースとパフォーマンス

データベースのパフォーマンスを決める要因

インデックス
  • SQLチューニングの手段として非常にポピュラーで、これを利用しないシステムはない、というぐらいよく使う

統計情報

  • SQLのアクセスパスを決める最大の要因

  • 最近はアクセスパスをDBMSに一任するアーキテキチャが主流

インデックス設計

インデックス設計がポピュラーな理由は

  1. アプリケーションのコードに影響を与えない
  2. テーブルのデータに影響を与えない
  3. 性能改善の効果が大きい

まずはB-treeインデックスから

インデックスにはいくつか種類があるが、B-treeインデックスが主である

  • B-treeインデックスは出来ることが多く、平均点が高い秀才型

B-treeインデックスの設計方針

B-treeインデックスはどの列に作ればいいか

  1. 大規模なテーブル
  2. カーディナリティの高い列
  3. SQL文でWHERE句の選択条件、または結合条件に使用されている列

B-treeインデックスとテーブルの情報

  • データ量が少ない場合フルスキャンのほうが早い場合もある

  • 目安としてはレコード数が1万件以下の場合は、ほぼ効果がないと考えて良い

    • 悪魔でも目安

B-treeインデックスとカーディナリティ

  • カーディナリティの高い列に作成することが基本

  • 特定のキー値を指定したときに、全体のレコード数の5%程度に絞り込めるのが目安

統計情報

オプティマイザと実行計画

  • SQLの実行計画は、DBMSがお任せで選ぶ

統計情報の設計指針

  • 統計情報収集のタイミングと対象を選ぶ

  • タイミングはデータが大きく更新された後、なるべく早く

    • 原則夜間
  • 対象は大きな更新のあったテーブル

第7章 論理設計のバッドノウハウ

非スカラ値

配列型による非スカラ値

  • 配列型を使った非スカラ値を含むテーブルは作らないほうが良い

  • 第一正規形を守る

  • 配列型はそれほど普及していない

ダブルミーニング

この列の意味は何でしょう?

  • 列の意味を途中で変えてはいけない

テーブルの列は「変数」ではない

  • エンティティは静的で固定的な存在

  • 列は変数ではない、一度意味を決めたら変更不可

単一参照テーブル

  • 同じ構造を持っているからといって、一つのテーブルにまとめてはいけない

  • これをまとめてしまったものを、単一参照テーブルと呼ぶ

単一参照テーブルの功罪

  • 単一参照テーブルはテーブル自体がその時々で意味を変えてしまう

  • テーブルにポリモルフィズムはいらない

テーブル分割

  • 水平分割と垂直分割がある

水平分割

  • レコード単位でテーブルを分割するのが水平分割

  • 水平分割はレコード数を物理的に減らせるが、分割する意味的な理由がない

  • DBMSによってはテーブルを分割することなく、格納領域を物理的に分割する手段がある

垂直分割

  • 垂直分割は列単位でテーブルを分割する

  • 垂直分割も、意味的な理由を持たないという欠点があるため原則使用してはいけない

  • 垂直分割の場合は集約という代替手段がある

集約

  • 細かくわけると列の絞り込みサマリテーブルの2種類がある

  • 列の絞り込みは良く利用される列だけで作った小規模なテーブルを保持する(データマート、マート)

  • サマリテーブルは集約関数を使って集約した状態のテーブルを保持する

不適切なキー

  • 主キーと外部キーには可変長文字列(VARCHAR型)を使ってはいけない

キーは永遠に不変です!

  • 可変長文字列は不変性がないためキーには不向き

同じデータを意味するキーは同じデータ型にすべし

  • 一方のテーブルが固定長文字列で宣言、他方のテーブルが可変長文字列で宣言されていると、列同士を比較した際アンマッチになる

  • キーには固定長文字列の「コード」列が望ましい

第8章 論理設計のグレーノウハウ

違法すれすれのライン上に存在する設計

  • 無神経に使うと開発や運用に支障をきたすような設計をグレーノウハウと呼ぶ

オートナンバリングの是非

  • オートナンバリングを実装する時はデータベース側で実装すべき

多段ビュー

  • ビューにアクセスする際は、結局オリジナルのテーブルにSELECT文を通じてアクセスしている

  • 多段ビューをすればそれだけアクセス回数が増える

感想

実際にデータベースを設計したことがないので、実感がわかない部分も多々ありましたが初学者にも分かりやすく、体系的にまとめられている本でした。 まとめていない部分にも、実務になれば役立ちそうな内容が沢山ありますので将来的に辞書的な使い方もできる良書であると思います。 また第9章においては理解が追い付いていない部分が大きいのでまとめませんでしたが、SQL木構造を扱うという1歩進んだ内容を紹介されています。

他にも演習問題がついていたり、学ぶ部分が非常に多い本ですので、データベースに興味がある方は是非手に取ってみてください。

SQL書き方ドリル付属のSQUATがwindowsで動かなかったので何とかした話

SQL書き方ドリルの付録が動かなかったが何とかした

前書き

学習に使おうと、すらすらと手が動くようになるSQL書き方ドリルを購入して、付属のCDからSQUATをインストールしようとしたが、startup.batが反応しなかった。

付属のpdfのインストール方法がとてもわかりずらく、同じように詰まる人が多いと思うので手順書(というには簡単すぎる)を残しておこうと思います

注意点としてWindows 10 64bit版の環境でインストールしているので、それ以外の方は参考にならないと思います。

手順

付属のPDFを見ると 付属のJREOracleの公式から取ってきてくれって書いてあります。

しかし付属の物はverが古く、インストールしてもすぐにアンインストールを促されるため使えない

ということはoracleの公式サイトから取ってこなければいけないので、併記されているoraclejavaダウンロードページへ飛びます

www.oracle.com

ここが最大の罠なんですが、

我々がダウンロードしないといけないのはこのメインっぽい欄にあるJDKではなく右上に赤で囲ったJREなのです

どう違うのかっていうとJDKjavaで開発するために必要なもので、JREjavaを利用するのに必要な物です

後はサイト側で勝手にこちらのosを読み込んで必要な物のダウンロードページに飛ばしてくれるので、そのままインストーラーを実行してインストールします。

その後はCDからコピーしてきて解凍したフォルダ内の

をダブルクリックしていただければSQUATのインストールが始まるので、user名を入れてインストールを完了してください。

お疲れ様でした。

データベースの基本を洗い出してみる

データベース基礎

前書き

、データベースの基礎を書き連ねていこうと思います

そもそもデータベースとは

  • コンピューターから素早くアクセスできるように加工したデータの集合
    • データベースを管理する専用のシステムのことをDBMS(データベースマネジメントシステム)と呼ぶ
  • 顧客情報、在庫情報等を管理するために使われている
    • 現代ではありとあらゆるものを管理するために使われていて、上記のほかにも実に多様なユースケースがある

DBMSは何をしてくれるのか

  • データベースの操作 作成 管理 をしてくれる
  • 多人数で同時にデータベースを操作できるようにしてくれる
  • データベースを直接インターネット上に置かなくてもよいのでセキュリティを強固にしてくれる

DBMSで使われているデータベースの種類

  • 階層型データベース

    • 階層構造(木構造) で管理されるデータベース
    • 最も古くからあるデータベースの1種
  • リレーショナルデータベース

    • 列と行からなる2次元表の形式で管理されるデータベース(Excelみたいな)
    • 関係データベースとも呼ばれる
    • 現在最も広く利用されるデータベース
    • SQLという専用の言語を用いて捜査する
    • リレーショナルデータベースを扱うDBMSの事をRDBMSと言う(リレーショナルデータベースマネジメントシステム)
  • オブジェクト指向データベース

    • データとそのデータを操作する処理をまとめてオブジェクトとして管理するデータベース
  • XMLデータベース

    • XLM形式のデータを管理するデータベース
  • キー・バリュー型データベース

    • Rubyで言うところのハッシュのような形で管理されるデータベース

データベースの構成(RDBMS)

テーブルの構造

  • 管理している2次元表のことをテーブルと呼ぶ

    • RDBMSが管理しているデータベースの中にテーブルを置いて管理する
    • 1個のデータベースの中には複数のテーブルを置ける
  • SQL文に対する応答で返されるデータも必ずテーブルと同じ構造になる(2次元表)

  • テーブルの列をカラム、行をレコードと呼ぶ -RDBMSではデータの読み書きは行(レコード)単位で行う

  • 列に対応した型のデータ以外は入れられない

    • 数値が入力されることが期待された列には数値しか、文字列が期待された列には文字列しか入れられない
  • 1つの列と行が交わる部分に入れることのできるデータは一つだけ

    • 行と列が交わる部分(Excelでいうセル)にRDBMSでは決まった名称はない
    • Excelで言うところのセルの分割が出来ない

SQL基礎

SQL概要

  • データベースを操作するための専用言語
  • 標準規格がある
    • 実際にはRDBMS毎に若干の違いがあり、方言とも呼ばれる
  • 文章の区切りはセミコロン
  • SQLは3種類に分類できる
    • DDL(データ定義言語)
    • DML(データ操作言語)
    • DCL(データ制御言語)
  • 大文字・小文字は区別されない
    • テーブルに登録されているデータについては区別される
  • 文字列を書くときはシングルコーテーション('こんにちは')
    • ダブルコーテーションが使えるRDBMSもあるが、移行時のエラーに繋がる可能性有
  • 数値を書くときはそのまま(10)
  • 単語間の区切りは半角スペースか改行

NginxでVirtualHostを使ってサイトを立ち上げる。

前書き

題名の通りNginxでVirtualHostの機能を使ってサイトを立ち上げる手順です。

せっかくVirtualHostを使うので、1個のドメインで2個のサイトを立ち上げてみます。

さくらVPSで借りているサーバーにubuntuをインストールし、そのubuntuにnginxをインストールして、そこで立ち上げた時の手順です。

また手順だけ覚えても何をしているか分からないと柔軟性に乏しい知識になってしまうので、適宜補足で理解を促していきます。

本題

ドメインを取得する

一番最初に必要なのはドメインです。

ドメインは、いうなればインターネット上の住所です。 A地区を自分の土地にします!ここに遊びにきてねー!みたいな感じです。

これはお好きな場所で取得して頂いてもいいのですが、今回はお名前.comで取得します。

僕はintensify.siteというドメインを購入しました、40円くらいだったかな?

この後ドメインにネームサーバを登録する作業と、さくらインターネット側にドメインの情報を登録する作業をしなければいけません。

ドメインにネームサーバを登録する作業に関しては、お名前.comを利用していれば購入時にチェックボックスにチェックをいれるだけでやってくれるので、今回は割愛します。

さくらインターネットドメインを登録する

まずはドメインコトロールパネルにアクセスします。

次に登録します。

これが終わったら次にゾーンを設定します

今回は2サイト立ち上げればokとするので

intensify.siteとwww.intensify.siteで2サイトとします。

なのでこれを選びましょう

IPアドレスの欄には貴方が借りたサーバーのIPアドレスを入力してください。

DNSサーバーとドメイン

今やった作業を簡単に説明します。

今貴方はドメインを取得し、DNSサーバーと紐づけるという作業を行いました。

先ほど説明した通りドメインとは住所で、DNSサーバーは案内所みたいなものです。

intensify.siteっていう住所にいきたいけど、世界は広すぎて住所を知っているだけではたどり着けません。

そこでDNSサーバーに住所を登録しておくと、アクセスする際にDNSサーバーにintensify.siteって住所に行きたいんだけどどうやっていくの?と問い合わせてくれるようになります。

結果DNSサーバーが、こっちの道からいけるよー。と案内してくれるので、intensify.siteに辿り着くことができるようになります。

ただしこの状態ではintensify.siteにはたどり着けますが、intensify.siteのどこにいっていいか分からないのでそれをVirtual Hostで設定してあげます。

NginxにVirtual Hostの設定をする

まずはデータを保存しておくディレクトリを作ります。

ここでは好きなディレクトリを自身で選ぶことができますが、慣例に従い/var/www/htmlに保存していくことにします。

sudo mkdir /var/www/html/intensify_main
sudo mkdir /var/www/html/intensify_sub
sudo mkdir  /var/www/html/intensify_main/{public,private,log,backup}
sudo mkdir  /var/www/html/intensify_sub/{public,private,log,backup}

これで下準備が完了です

設定ファイルを作ります

sudo vim /etc/nginx/sites-available/intensify.site

まっさらなファイルに設定情報を書き込んでいきます

server {

        listen 80;
        server_name intensify.site;
        access_log /var/www/html/intensify_main/log/access.log;
        error_log /var/www/html/intensify_main/log/error.log;
        location / {
                   root /var/www/html/intensify_main/public/;
                   index index.html;
                   }
        }

server {

        listen 80;
        server_name www.intensify.site;
        access_log /var/www/html/intensify_sub/log/access.log;
        error_log /var/www/html/intensify_sub/log/error.log;
        location / {
                   root /var/www/html/intensify_sub/public/;
                   index index.html;
                   }
        }

これで設定はokです

補足として説明しておくと

listen 80 は待ち受けるポート番号を指定しています。

server_nameはサーバーの名前です。 VirtualHostを利用して疑似的に複数台のサーバーとして稼働させるので、このように2台のサーバーとして振舞う設定ができます。

access_log, error_logは名前の通りのログを保存しておくファイルを指定しています。

locationはそのサーバーにアクセスされたときどの場所のコンテンツを返すかを指定しています

それでは最後に

sudo ln -s /etc/nginx/sites-available/intensify.site /etc/nginx/sites-enabled/intensify.site

として設定は終わりになります

これはNginxが起動時にsites-enabledを読み込むからなのですが、avaliableに書き込んでシンボリックリンクでenabledに置くのが慣例らしいです。

これであとは指定したパスにおいたindex.htmlを好きなように記述して頂ければ完成です

sudo /etc/init.d/nginx stop
sudo /etc/init.d/nginx start

としてNginxを再起動すれば


うまくいきました、お疲れ様でした。

Cookieとセッション

違いが分かりますか?

本日は題名にもある通り、Cookieとセッションの違いってなーに?ということを書いていきます

この2つの違いについて貴方は即答できるでしょうか?

僕は無理でした。

なので備忘録を兼ねて書いていきたいと思います。

とはいっても前提の知識を間違えていたらしょうがないので、Cookieとセッションそれぞれについてまずは見ていきます。

Cookieって何?

正確には"HTTP COOKIES"と言います。

HTTPはステートレスなプロトコルであるため、ブラウザとサーバー間でやりとりを保持しておく機能がありません。

そのためやりとりを保存しておく必要のある場合にこのCookieと呼ばれるデータを使います。

Cookieはウェブサイトから送られてくる情報の一部で、HTTPレスポンスのメッセージヘッダーを利用して送られてきます。

そしてこの送られてきたCookieをブラウザは自身に保存しておき、再度同じサーバーにアクセスした際にはサーバーがCookieを読み戻し、今アクセスしているのがどんなユーザーなのかを識別します

これらがCookieの役割ですが、実はCookieには2種類あります。

とはいっても担っている仕事は同じです。

ではどう分かれているのでしょうか?

セッションCookie

一つ目はこちら、セッションCookieです。

有効期限が特に設定されていないCookieで、Webブラウザが終了すると削除されます。

パーシステントクッキー

二つ目はこちら、パーシステントクッキーです。

有効期限が設定されている、もしくは有効期限が無限のCookieです。

よく一度ログインしたら翌日以降も勝手にログインしてくれるサイト等を皆さん知っていると思いますが、それらはこのパーシステントクッキーを採用しているからです。

以上が簡単ではありますが、Cookieの説明になります。

セッションって何?

では次にセッションについて見ていきます

セッションとは一連の関連性のある処理をセッションと呼びます。

ECサイトを例に出せば、商品を選ぶ、かごに入れる、かごを確認する、決済をする といった処理の流れです。

上の例のように一人のユーザーからの処理の流れを管理したい場合、Cookieを使ってセッション管理が行われます。

例えばIDとパスワードを入力しログインすると、サーバーがセッションIDを生成し、Cookieに乗せて渡します。

次回からそのユーザーはリクエストを送る際にセッションIDをリクエストする際に送るようにし、サーバー側がセッションIDを用いてデータを管理する。

以上がセッションの説明になります。

ではいよいよ違いの説明に入りますが、ここまで説明してきたことを単純にまとめているだけです

Cookieとセッションの違い

Cookieとは何か?

Cookieは、ウェブブラウザとウェブサーバー間で情報をやり取りするための仕組みです。ウェブサーバーから送信され、ウェブブラウザに保存される情報であり、ブラウザが同じサイトに再度アクセスする際にサーバーに情報を提供します。

セッションとは何か?

セッションは、一連の関連性のある処理の流れのことです。例えば、ECサイトで商品を選択し、カートに追加し、購入するといった一連の手順がセッションとして扱われます。セッションはサーバー側で管理され、ユーザーごとに一意のセッションIDが割り当てられます。

Cookieとセッションの違い

  1. 保存場所:
    • Cookieはブラウザに保存されます。
    • セッションはサーバー側で管理されます。
  2. 有効期限:
    • Cookieは有効期限が設定されている場合はブラウザが終了しても削除されません。
    • セッションの有効期限はサーバー側で任意に設定されます。
  3. セキュリティ:
    • Cookieはブラウザに保存されるため、不正アクセスのリスクが大きいです。
    • セッションはサーバーに保存されているため、リスクがない訳ではないがCookieに比べれば低いです。

以上がCookieとセッションの違いになります。

もし突っ込みどころがありましたら優しく教えてください。

それではお疲れ様でした。

参考サイト様

Cookieとセッション管理 - Qiita

クッキー(Cookie)について

参考書籍 この1冊で全部わかる Web技術の基本

HTTPって何なのさ?

HTTP(Hyper Text Transfer Protocol)とはプロトコルである

今日はHTTPとは何なのかについて纏めてみたいと思います。

結論からいうとHTTPっていうのは表題にもある通り、プロトコルです。

プロトコルとは何なのでしょうか?

Webページ(例えば今貴方が見ているこのページも)を開くときにブラウザがWebサーバーに対してコンテンツを要求します、それに対してWebサーバーは要求されたコンテンツをブラウザに対して送信します。

これを人間対人間のやりとりとして考えてみて欲しいのですが、面識のないA君とB君が会話をすることになりました、事前の取り決めは何もありません。

これではA君とB君がしゃべる言語が違った場合、話したい話題が違った場合に話が通じませんよね?

人間同士であればよしなに会話をすることも出来るかもしれませんが、コンピューター同士だと会話が通じなくてエラーを起こしてしまう訳です。

そこでこの言語を使って会話しようねー、会話する順番はこうしようねーっていう取り決めを作ることにしました、このように通信の際の約束事を決めたものがプロトコルと呼ばれます。

HTTPもプロトコルの1種であり、ハイパーテキストの通信をする際の約束事をまとめたものです。

URLの意味

実際のHTTP通信の話に入る前に少しURLの話をしようと思います。

HTTP通信で利用者の私たちがサーバー側に対してコンテンツを要求する際にはURLを利用して、このコンテンツをくれと要求を出すわけです。

http://example.com/test.html を例にとって話を進めていきます。

httpの部分でプロトコルexample.comの部分でサーバーを test.htmlの部分でファイルを指定しています。

httpというプロトコルexample.comというサーバーからtest.htmlというファイル(コンテンツ)をくださいー!という要求が http://example.com/test.html の正体なんですね。

HTTPによる通信

ここからは実際にHTTP通信を行ってみて、どのような通信が行われているのかを見ていきたいと思います。

今回はtelnetを使って通信してみたいと思います

telnet example.com 80で接続を確立したあと、リクエストを送ります

まずは接続を確立させます。

ちなみにこのコマンドの意味は telnetexample.comサーバーの80番ポートに接続しますよ という意味です。

それではサーバーに接続できたところでコンテンツを要求しましょう

この要求作業こそがHTTPプロトコルを利用する部分です。

要求する際はプロトコルに従い、HTTPリクエストを送信します。

このHTTPリクエストはリクエスト行, メッセージヘッダー, 空白行, メッセージボディの4種で構成されます。

メッセージボディはサーバーにデータを送るために使われますが、今回は使用しません。

まずはリクエスト行を書いていきます

GET /test.html HTTP/1.1 今回書くリクエスト行は以上になります

このリクエスト行が何を意味しているかですが GETは要求する処理 /test.htmlは要求するファイル HTTP/1.1は使用するバージョンになります

GETは情報を取り出す要求なので、このリクエスト行では test.htmlってファイルをhttp1.1を使用してこっちにちょうだいー! という事を先ほど接続したexample.comサーバーに伝えています。

それでは次にメッセージヘッダーを書いていきます

Host: example.com 以上になります

ブラウザからリクエストを送る場合はもっと詳細な情報を送ってあげる必要があるのですが、telnet等を使用してCUI環境からリクエストを送る場合はメッセージヘッダーに書くべき情報も少ないことが多いです。

特に今回は1回限りのファイルを取得する要求ですので、なおさらですね。

さてこのメッセージヘッダーの意味ですが、

このリクエストはexample.comあてですよー、という意味になります。

あれ?最初にexample.comに接続したんだからその情報必要?と思うかもしれません。

これは1つのWebサーバーが複数のドメインをホストできるので、どのドメインに対して接続しているのかを明確にするために必要とされます。

ということで以上二つと、これでHTTPリクエストは終わりということを示すための空白行を送ってみます

とするとexample.comから返事が返ってきます

HTTP/1.1 404 Not Found
Age: 155613
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Wed, 03 Apr 2024 09:50:28 GMT
Expires: Wed, 10 Apr 2024 09:50:28 GMT
Last-Modified: Mon, 01 Apr 2024 14:36:55 GMT
Server: ECS (sac/251D)
Vary: Accept-Encoding
X-Cache: 404-HIT
Content-Length: 1256

<!doctype html>

省略

この返事がHTTPレスポンスとなります

ではどのようなことが書いてあるのか見ていきたいと思います

HTTPレスポンスも、HTTPリクエストと同じ4つの要素に分かれています

まず1行目のHTTP/1.1 404 Not Foundからいきましょう

この1行目はステータス行と呼ばれる処理の結果を伝える部分です

今回の結果で言えば HTTP1.1を使ったよ要求したコンテンツはなかったよ

という意味になります。

実はexample.com/test.htmlというファイルは存在しない、ということですね。

実際にやってみたらhtmlファイルが返ってきますが、これはドメイン側で404エラーだった場合に表示するhtmlを設定しているというだけです。

では次に2行目からのメッセージヘッダーをみていきます、ちなみに2行目以降の要素はリクエストの時と同じ名前です。

行ごとに全て説明していると長くなってしまうので、どんな情報が渡されているのかを全体的にお伝えしたいと思います。

このメッセージが作られた日付、ファイルのエンコード方法、キャッシュの有効期限、ファイルの容量等が格納されています

そしてリクエストの時と同じ空白行があり、メッセージボディとなります。

当然サーバーは要求したファイルがあれば返してくれるので、返ってきたデータはメッセージボディに格納されています。

以上がHTTP通信の中身になります。

終わりに

いかがだったでしょうか?

別にtelnetなんて使わないし、こんなの知ったところでどうするんだよーと思われたかもしれません。

ですが皆さんが普段よく使っているブラウザでも、実はこのやりとりをしてその結果をブラウザが解釈して画面に表示してくれているんですね。

普段使っている物の中身を知るというのも、それはそれで面白かったのではないでしょうか?

それではこの辺で終わりにしたいと思います、ありがとうございました。