学習記録 (3/2 -3/19 )

Minitest

if $0 == __FILE__
  Sample.new(ARGV[0],ARGV[1],ARGV[2]).run
end

を実行のロジックに入れることで別のパスで実行するとき(特にテストコード)のエラーを防ぐ

ARGVは定数なのでコード内のどこでも呼び出せる

テストコード

assertequalで検証されるのはメソッドの戻り値(標準出力ではない) テストしやすくするためにコードを戻り値ベースでかき、最終的に出力する形が理想に思える。

  • cat -は入力をそのまま出力する
  • readlinesは改行しても入力が終わらない、Ctrl+Dで入力が終了する。
  • File.pipe?(STDIN) パイプによる標準入力の有無の判定
  • STDIN$stdinに書き換えることができる。
  • 戻り値が複数ある場合はreturnに戻り値をカンマ区切りで表示。メソッドから複数の要素に代入する。
def wc_files(files, option)
  output_files = ''
  total = { 'lines' => 0, 'words' => 0, 'bytes' => 0 }
  files.each do |filepath|
    str = File.read(filepath)
    lines = str.count("\n")
    words = str.split(/\s+/).size
    bytes = File.stat(filepath).size
    output_files += lines.to_s.rjust(8)
    output_files += option['l'] ? " #{filepath}\n" : "#{words.to_s.rjust(8)}#{bytes.to_s.rjust(8)} #{filepath}\n"
    total['lines'] += lines
    total['words'] += words
    total['bytes'] += bytes
    end
    return output_files, total
  end

return output_files, total[return output_files, total]と記述することができる

この戻り値を複数の変数に代入する。

    output_files, total = wc_files(files, option)
    output += output_files

filepahオブジェクト

ディレクトリであってもファイルであってもパスとして扱う Pathname.getwd : オリジナルのファイル(実行しているファイルではなく)のカレントディレクトリのパスを取得、require 'pathname'が必要 Pathname.new(文字列) : 文字列をもとにpathnameオブジェクトを作る/ Pathname()と同値 - File.extend_path:相対パス絶対パスに変換 File.extend_path("..") = 親ディレクトリまでの絶対パス

p Dir.getwd                      #=> "/home/matz/work/foo"
p ENV["HOME"]                    #=> "/home/matz"
p File.expand_path("..")         #=> "/home/matz/work"
p File.expand_path("..", "/tmp") #=> "/"
p File.expand_path("~")          #=> "/home/matz"
p File.expand_path("~foo")       #=> "/home/foo"
  • File.dirname : filenameのいちばん後ろのスラッシュより前を文字列として返す
p File.dirname("dir/file.ext")    # => "dir"
p File.dirname("file.ext")        # => "."
  • ヒアドキュメント 基本は ``` <<TEXT . . .

    TEXT

<<~にするとヒアドキュメント内の全行の頭のインデントが無視される

ヒアドキュメントの中では\や式展開が有効 識別子TEXTは自由。''で囲むとシングルクオート、""で囲むとダブルクオート

  • ヒアドキュメントに<<~TEXT.chompのようにメソッドを追加することができる。

  • バッククオートで囲むと``ターミナル実行結果が返る

path = "/Users/takunaka"
p expected = `ls #{path}`

#=> 
"Applications\nCalibre Library\nDesktop\nDocuments\nDownloads\nFBC\nGemfile\nGemfile.lock\nLibrary\nMovies\nMusic\nPictures\nPublic\nTEST\nTEST2\nVirtualBox VMs\nWine Files\nbin\necho\ngittutorial\nhello-world\nhotger\npatchwork\nresult\nrubybook\ntutor\nwork\n"

コミットの取り消し : git reset --soft HEAD^ ステージングの取り消し : git reset HEAD

  • getsコマンドは改行の"\n"まで含まれる、文字列だけを取り出すためにはchompメソッドを使用する。readlineも同様(readlinesは複数行を一度に読み込む別メソッド)だが読み込めない行があるとreadはEOErrorを返し,getsはnilを返す
  • ファイルの読み込み : str = File.read("./test_file.rb")
  • readは文字列、readlineは配列として取得
  • readlines gets readlineは標準入力を要求する。要求する入力方法は、

    • コマンドの引数のファイル名(ファイルをopenする)
    • パイプライン
    • 引数とパイプラインがある場合は引数が優先される(メソッドが標準入力を選択している)
    • 複数の引数がある場合でも一つ目の引数しか読み込まない
    • readline/readlines/getsは変数ではなく入力。読み込まれていったら順次消えていく。一度変数に代入したら次の変数には代入されない。
  • require 'optparse''を入れなければオプション-lはARGV配列に含まれるがoption = ARGV.getopts('-l')メソッドを入れることにより、-l`はA{"l" => true}という新たなハッシュに代入されARGVから除外される。

byebug

  • byebug (ファイル名で実行)/ rubyコマンドに-rbyebygオプションをつける / require 'byebug' ; byebygをファイルにrequireする。
  • c/s/fin/restart/next(メソッドの中に入らない)

*SQL入門 - データを集めることの大切さ - データの基準 <完全性><正確性><妥当性><一貫性><適時性> タイミングがふさわしく。正しい前提に基づき、矛盾なく、正確で漏れのないデータ「データに偏りがなく正確で新しいデータ」 - 不特定多数ののユーザーが同時に利用するデータベースの整合性を担うのがDBMS - DBMSはデータに対するアクセス要求に応えるソフトウェア - データベースの種類 - リレーショナル/RDB : 二次元表現、人が理解しやすい - オブジェクト指向データベス/OODB : オブジェクトを保存する - XMLデータベース/XMLDB : XML形式のデータを扱う - 階層型データベース : データを階層構造で表現する - ネットワーク型データベース : 階層構造だが横つながりも持つ

  • DBMSの種類 商用

  • OSSDBMS

  • 3層スキーマ

    • 外部スキーマ(ビュー)/概念スキーマ(テーブル定義)/内部スキーマ(データの物理配置)
    • スキーマを分けることで変更がほかのスキーマに影響を与えない
    • 概念スキーマを考える論理設計、データモデルをつくる ERモデル entiti(実態)reltionship(関連)attirbute(属性)を図で表したもの
  • データベースの物理設計

    • テーブル定義
    • インデックス定義
    • ハードウェアのサイジング
    • ストレージの冗長構成決定
    • ファイルの物理配置決定
  • RAID 高い耐障害性を持つシステム Redundant Array of Inexpensive Disks データを複数のディスクに分散

  • RAIDのレベル

    • 0 : 高速化と大容量化(ストライピング)
    • 1;耐障害性に特化した単純構成(ミラーリング)
    • 5:高速、大容量、冗長(分散型)、パリティ(誤り訂正符号)分散
    • 10:ミラーリング x ストライピング 冗長化とは複数のディスクに同じデータを書き込むこと
  • データベースのI/Oスピードがデータベースの性能問題の元凶

  • PostgreSQL

    • オンラインバックアップ/ストアドプロシージャ
    • レプリケーション : 複数のサーバにデータベースを自動的に複製する機能

SQLの分類 - DDL(Data Definition Language) DDL(データ定義言語)は、テーブルなどのオブジェクトを作成するためのコマンド群です。DDLに分類されるコマンドは以下になります。

  • CREATE データベースやテーブルなどを作成する。
  • DROP データベースやテーブルなどを削除する。
  • ALTER データベースやテーブルなどの構成を変更する。

  • DML(Data Manipulation Language) DML(データ操作言語)は、データの挿入/更新/削除などを行うためのコマンド群です。DMLに分類されるコマンドは以下になります。

    • SELECT テーブルから行を検索する。
    • INSERT テーブルに新規行を登録する。
    • UPDATE テーブルの行を更新する。
    • DELETE テーブルの行を削除する。
  • DCL(Data Control Language) DCL(データ制御言語)は、トランザクション関連のコマンドが含まれます。DCLに分類されるコマンドは以下になります。

    • COMMIT データベースに対して行った変更を確定する。
    • ROLLBACK データベースに対して行った変更を取り消す。
    • GRANT ユーザーに操作の権限を与える。
    • REVOKE ユーザーから操作の権限を奪う。
  • SQL記述ルール

    • 文末にセミコロンをつける
    • 大文字小文字は分けない
    • 定数はシングルクオーテーションで囲む
    • 数値はそのまま記述
  • psql SQLインタプリタ

  • シェルからpsqlコマンドを実行
    • psql -U <データベースユーザー名> <データベース名>
    • -l データベース一覧を表示する。コマンド実行後、データベースに接続したままにならず、プロンプトに戻る。
    • c ‘コマンド’ 引数で指定したSQLコマンドを実行し、結果を表示する。コマンド実行後、データベースに接続したままにならず、プロンプトに戻る。 -f ファイル名 引数で指定したファイルの中身をSQLとして実行する。コマンド実行後、データベースに接続したままにならず、プロンプトに戻る。
    • p ポート番号 接続するPostgreSQLのポート番号を指定する。
    • h ホスト名 接続するPostgreSQLのホスト名を指定する。

バックスラッシュコマンド 説明 \? バックスラッシュコマンドヘルプを表示 \h SQLヘルプを表示 \q psqlを終了 \l データベースの一覧を表示 \dn スキーマの一覧を表示 \d テーブル、インデックス、シーケンス、ビューの一覧を表示 \dt テーブルの一覧を表示 \di インデックスの一覧を表示 \ds シーケンスの一覧を表示 \dv ビューの一覧を表示 \dS システムテーブルの一覧を表示 \du データベースユーザーの一覧を表示 \df 関数の一覧を表示 \r 入力途中のクエリのリセット \timing SQL実行時間計測表示のON/OFF

  • CREATE TABLE

    列に指定する制約として以下の項目があります。

PRIMARY KEY 主キーとする。 UNIQUE 列内で重複する値を許可しない。 REFERENCES 表名(列名) 外部キーとする。参照先は指定した表名(列名)となる。 CHECK(条件) 条件に合う値のみ登録を許可する。 NOT NULL NULL値(空の値)を許可しない。 DEFAULT 値 新規行追加時の初期値を指定する。

  • INSERT INSERT INTO テーブル名 [(列名1 [, 列名2 …] )] VALUES (値1 [, 値2 …] );

    testdb=# INSERT INTO Staff (id, name, age) VALUES ('0001', '山田太郎', 26); testdb=# INSERT INTO Staff (id, name, age) VALUES ('0002', '佐藤隆', 34); testdb=# INSERT INTO Staff (id, name, age) VALUES ('0003', '斉藤達弘', 45);

testdb=# INSERT INTO Staff VALUES ('0004', '渡辺さつき', 28);

  • SELECT SELECT 列名, … FROM テーブル名;

    testdb=# SELECT name FROM Staff; name


山田太郎 佐藤隆 斉藤達弘 渡辺さつき (4 行)

testdb=# SELECT * FROM Staff; id | name | age ------+------------+----- 0001 | 山田太郎 | 26 0002 | 佐藤隆 | 34 0003 | 斉藤達弘 | 45 0004 | 渡辺さつき | 28 (4 行)

-UPDATE 既存のデータの変更 UPDATE テーブル名 SET 列名 = 式 WHERE 条件式;

testdb=# UPDATE Staff SET name = '桜井さつき' WHERE id='0004';

  • 全行更新testdb=# UPDATE Staff SET age = 46;

    testdb=# SELECT * FROM Staff; id | name | age ------+------------+----- 0001 | 山田太郎 | 46 0002 | 佐藤隆 | 46 0003 | 斉藤達弘 | 46 0004 | 桜井さつき | 46 (4 行)

  • DELETE DELETE FROM テーブル名 WHERE 条件式; DELETEコマンドで削除するのは行(レコード)単位です。例えば、一部の列だけを削除すると言ったことはできません。

testdb=# DELETE FROM Staff WHERE id='0002'; testdb=# SELECT * FROM Staff; id | name | age ------+------------+----- 0001 | 山田太郎 | 46 0003 | 斉藤達弘 | 46 0004 | 桜井さつき | 46

testdb=# DELETE FROM Staff; testdb=# SELECT * FROM Staff; id | name | age ----+------+----- (0 行)

  • DROP TABLE DROP TABLE テーブル名;

    testdb=# \d リレーションの一覧 スキーマ | 名前 | 型 | 所有者 ----------+-------------+----------+---------- public | staff | テーブル | postgres public | testTable01 | テーブル | postgres (2 行) testdb=# DROP TABLE staff; testdb=# \d リレーションの一覧 スキーマ | 名前 | 型 | 所有者 ----------+-------------+----------+---------- public | testTable01 | テーブル | postgres (1 行)

【第1回】データベースとデータベース管理システム 1.1 データベース管理システムが扱うデータ

1.2 データーベース管理システムとアプリケーション アプリケーションは用途がある、DBMSはそれを汎用的に管理する

1.3 データベース管理システムはデータベースを守る DBMSはデータの出し入れと同時にバックアップや変更履歴を保存し故障時の復旧に備えている 1.4 データベースを使うと何人もの人が同時にデータベースを使える

【第2回】PostgreSQL って何? 2.1 PostgreSQL はフリーなオープンソースソフトウェア PostgreSQLソースコードは80万行 2.2 世界中の開発者が作る高品質なプログラム

2.3 長期間にわたる維持管理 維持管理:脆弱性や不具合のアップデート

2.4 業務システムに耐える品質・機能と性能

【第3回】リレーショナルデータベースと DBMS 超入門 3.1 リレーショナルデータベースとは「表」のこと? "表=テーブル=リレーション" フィールドは連結、分割ができない フィールドの値の同じ2つの行は区別されない 読み書きはSQLという言語を使って行われる 3.2 データベース管理システムは大量のデータを保持できる DBMSは変更と保存を同時に行う

3.3 データベース管理システムはデータを安全確実に保存する ログを使ってデータベースを最新の状態に戻すクラッシュリカバリ バックアップディスクとログを使ってデータベースを復元するアーカイブリカバリ

3.4 データベース管理システムは処理を中途半端で終わらせない トランザクションの途中で止まった処理は元に戻る DBMSトランザクションの単位を認識できないので、アプリケーションがそれDBMSに通知する必要がある。

3.5 データベース管理システムは同時に複数のアプリケーションからの読み書きをサポート

  • POSTGRE SQL ユーザーの追加・削除など基本の操作を覚える。 起動 /etc/init.d/postgresql start サーバを起動させpostgresユーザにアクセス、postgresはサーバのrootユーザ
su - postgres
psql -l

テンプレートデータベースが表示される

                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------+----------+----------+-------------+-------------+-----------------------
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
(3 rows)

postgres ユーザにアクセス

$ psql postgres

このコマンドは $ psql -U postgres postgresの省略版

\dでデータベースの中を参照

サンプルテーブルの作成

postgres=# CREATE TABLE sampletable
postgres-# (
postgres(# idnumber serial,
postgres(# name text
postgres(# )
postgres-# ;

\d テーブル名でテーブルの中身(定義された項目と属性)を確認

データの確認

select * from sampletable

データベースの停止、終了 exitpsqlユーザからログアウト、再びexitでデータベースよりログアウトした上で

/etc/init.d/postgresql stop

psqlでユーザとしてデータベースにアクセス

  • ユーザを追加 (LOGIN,PASSWORD,CREATEDB権限付き)
postgres=# CREATE USER "caminopsql" CREATEDB PASSWORD 'caminopsql' LOGIN;
postgres=# CREATE USER "caminosql" CREATEDB PASSWORD 'caminosql' LOGIN;

全ての権限を持ったroleを追加

CREATE ROLE user01。この時点ではなんの権限も与えられていない
                               List of roles

Role name | Attributes | Member of -----------+------------------------------------------------------------+----------- caminosql | Create DB | {} postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} user01 | Cannot login ```

  • ユーザを削除
postgres=# DROP ROLE caminopsql;

\du作成済みのロールを表示 \du作成済みのデータベースを表示

postgres=# \du
                                    List of roles
 Role name  |                         Attributes                         | Member of 
------------+------------------------------------------------------------+-----------
 caminopsql | Create DB                                                  | {}
 caminosql  | Create DB                                                  | {}
 postgres   | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

SQLコマンドを実行するには最初にコマンドプロンプトを起動して psql を使って PostgreSQL に接続。 コマンドの入力途中ではプロンプトが=から-に変わる

postgres=# create table postgres-#

  • psql: error: FATAL: Peer authentication failed for user エラー

    peer認証とはPostgresのデフォルトの認証方法で、OS側のユーザー名とPostgreSQL側のユーザー名が一致していないと発生するエラーです。 デフォルトの状態であれば、以下の通りだとPeer認証のエラーが発生せずPostgresへログインすることが可能です。

/etc/postgresql/9.6/main/pg_hba.confこのサイトに則って変更

その後はコマンドラインから

psql -U user01 postgres

あるいは

psql -U user01 -d postgres

のような形でアクセスできる

だけれど、この場合スーパーユーザがアクセスできない(パスワードが未設定のため)

  • スーパーユーザのパスワードを設定

osでの設定 ソース 

# passwd postgres (nuttahに設定)
ユーザー postgres のパスワードを変更。
新しいパスワード:
新しいパスワードを再入力してください:

psqlにログインし、スーパーユーザのパスワード'postgress'を設定

postgres=# ALTER ROLE postgres WITH PASSWORD 'postgres';

コマンドからpsql -U postgrespsql -lのパスワード認証が通らなくなったので /etc/postgresql/9.6/main/pg_hba.confをさらに以下のように変更

# ↓追加

local all all trust

とすると

psql: error: FATAL:  role "root" does not exist

であるが, su - postgresでログイン可能

以下のコマンドでデータベース内でユーザに権限を追加削除できる

postgres=# GRANT SELECT ON sampletable ON user01;
postgres=# REVOKE SELECT ON sampletable FROM user01;

psql データベース名でデータベースにアクセス