【OSS-DB Silver黒本】1章つまづいたところまとめ。

正直初めて見る単語が多くてつらい。

PostgreSQLライセンス

PostgreSQLBSDやMITに似たライセンス。 著作権表示とすべてのライセンス条文の表示があれば、使用、複製、改変、再配布は自由。

リレーショナルモデル

リレーショナルデータベースが基づく集合モデル。 モデルを構成する要素として、リレーション、タプル、属性がある。

f:id:KazmaArakaki:20170724202354j:plain

候補キー

タプルを一意に特定できる属性。

主キー

候補キーの中から主に使用するものを明示的に選択したもの。主キーには以下の制約がある。

  • UNIQUEである
  • NULL値を許容しない

正規化

1事実1箇所の原則に従って同じデータを集約することにより、更新漏れや更新箇所の増加を抑え、データ操作を効率化すること。

  • 正規化前

f:id:KazmaArakaki:20170724220705j:plain

  • 第一正規形

SQLで扱いやすいデータ構造に変更する。

f:id:KazmaArakaki:20170724220806j:plain

  • 第二正規形

キー属性に関数従属している列を別テーブルに分離する。

f:id:KazmaArakaki:20170724221111j:plain

f:id:KazmaArakaki:20170724221159j:plain

  • 第三正規形

非キー属性に関数従属している列を別テーブルに分離する。

f:id:KazmaArakaki:20170724221111j:plain

f:id:KazmaArakaki:20170724221317j:plain

関数従属

ある列の値によって別の列の値が一意に決まるような列間の関係

完全関数従属

(1) { A, B } -> C
(2) A -> C
(3) B -> C

(1)が成り立ち、かつ、次の(2)、(3)が成り立たないとき、
Cは{ A, B }に完全関数従属している
と言う

候補キーの全ての値が埋まってはじめて他の列の値が一意に決まる。

下の例では、学年、組、番号の全ての値が埋まったときに氏名が一意に定まる。 学年だけ、もしくは組や番号だけでは氏名は特定できない。

f:id:KazmaArakaki:20170724222118j:plain

部分関数従属

(1) { A, B } -> C
(2) A -> C
(3) B -> C

(1)が成り立ち、かつ、次の(2)、(3)のどちらかが成り立つとき、
Cは{ A, B }に部分関数従属している
と言う

候補キーの一部の値が埋まると他の列の値が一意に決まる。

下の例では、学年と組の値が埋まれば学級担任が一意に特定できる。 番号は学級担任の特定に関係がない。

f:id:KazmaArakaki:20170724222810j:plain

推移関数従属

(1) A -> B
(2) B -> C
(3) B -> A

(1)、(2)が成り立ち、かつ、(3)が成り立たないとき、
CはAに推移関数従属している
と言う

候補キーによって他の列の値が一意に定まり、その定まった値からさらに別の列の値を一意に定められる。

下の例では、ISBNが分かれば著者が特定でき、著者が分かれば国籍が特定できる。 さらに著者からはISBNを一意に特定することができない。

f:id:KazmaArakaki:20170724225112j:plain

DBMSの主な機能

機能 説明
データベース管理 データベースの定義と操作
トランザクション管理 データベースの操作の一貫性を保障
同時実行制御 複数のユーザーからのアクセスを制御
機密保護管理 不正アクセスからデータベースを保護
障害回復管理 障害発生時の復旧

SQL

大きく3つに分類できる。

  • DDL (Data Definition language)
    テーブル操作のコマンド
  • DML (Data Manipulation Language)
    データの検索、追加、更新、削除のコマンド
  • DCL (Data Control Language)
    DDLDML以外のコマンド

リレーショナル代数の演算

※演算イメージはWikipedia)より。

f:id:KazmaArakaki:20170724231602j:plain

f:id:KazmaArakaki:20170724231726j:plain

交差

f:id:KazmaArakaki:20170724231757j:plain

直積

f:id:KazmaArakaki:20170724231830j:plain

結合

f:id:KazmaArakaki:20170724231909j:plain

選択

f:id:KazmaArakaki:20170724231944j:plain

射影

f:id:KazmaArakaki:20170724232014j:plain

データベース設計の流れ

  1. 概念設計
    モデル化、ER図、クラス図の作成
  2. 論理設計
    テーブル定義、正規化
  3. 物理設計
    DBMSの選定、設定、マシン構成やディスク構成の設計

参考URL

OSS-DB Silverの資格を取りたい。

Linux系の資格とDBの資格を取りたいと思っている。

まずはDBの資格の一つであるOSS-DB Silverを受けてみようと思う。

OSS-DB Silverとは

資格取得メリット

OSS-DB技術者認定資格に認定されると、市場から必要とされるスキルを持つ技術者として活躍できます。 また、OSS-DB技術者認定資格の認定者には、LPI-Japanから次のような特典を提供します。

  • 認定証と認定カードの進呈( Silver / Gold )
  • 認定者ロゴの使用(別途使用ガイドラインに基づく)( Silver / Gold )
  • OSS-DB技術者認定試験メンバーズページへのアクセス
  • LPI-Japan の最新情報+技術情報の提供
  • LPI-Japan 主催のイベント/セミナーへの招待

認定者が得るメリットは、LPI-Japanが提供する具体的な特典だけにとどまりません。

OSS-DB技術者認定資格の認定者は、OSS-DB系IT分野に関する広範な知識を公に認められたのと同然であり、 業界から高い信頼を得ることができます。OSS-DB技術者認定資格は、確かな技術力の証でもあるのです。

また企業にとっても、雇用、昇進、キャリアプランニングに対する確実な評価基準として利用できるなど、様々なメリットが考えられます。

資格取得のメリット「OSS-DB技術者認定資格のメリット」|DBスペシャリストを認定する資格 OSS-DB技術者認定試験

試験概要

試験時間 90 分
出題数 50 問
合格ライン 64点
受験料 15,000円(税別)
会場 ピアソンVUE

ラムダ式を引数に取るメソッドを書いてみる。

Consumer<T> consumer::acceptcallbackみたいな感じで使える。

import java.util.function.Consumer;

public class Main {
  public static void main(String[] args) {
    String[] messages = new String[] {
      "hoge", "fuga", "foo", "bar"
    };

    each(messages, message -> {
      System.out.println(message);
    });
  }

  private void each(String[] messages, Consumer<String> consumer) {
    for(String message: messages) {
      consumer.accept(message);
    }
  }
}

出力

John
Sarah
Kevin

JavaScriptで書くとこんな感じか

(function() {
  const messages = [
    "hoge", "fuga", "foo", "bar"
  ];

  each(messages, message => {
    console.log(message);
  });

  function each(messages, callback) {
    for(message of messages) {
      callback(message);
    }
  }
})();

過去、現在、そしてこれからのことを

とりとめのない文章をつらつらと書く。

youtu.be

たしか僕が15、6歳だったころ。

18歳はお姉さんで25歳はキャリアウーマン、30歳はおばさんだと思っていた。

22歳で大学卒業して社会人になって、それから数年で結婚して子供産まれて、30歳には家庭を持っているんだろうな、と思っていた。

今年の11月で僕は29になる。

youtu.be

特別お題「『選択』と『年齢』」

せん‐たく【選択/×撰択】

多くのものの中から、よいもの、目的にかなうものなどを選ぶこと。「―を誤る」「テーマを―する」「取捨―」

せんたく【選択/撰択】の意味 - goo国語辞書

あらためて語義を調べてみたときに、僕は本当の意味での「選択」を、今までほとんどしてこなかったのではないかと思った。

高校を決めたときも、大学を決めたときも、その後も、僕の歩いてきた道は、一番考えずに済む、そんな道だったと思う。

選択するためには選択肢がなければならない。 それは周りが用意してくれる場合もあるかもしれないけど、最終的な責任は自分にしかない。 選択肢を用意しなかった「つけ」は自分に返ってくる。

高校受験

僕は地元では頭が良いほうだった。

地域の進学校。設立7年目の新しい校舎。県立。

高校は自分で選んだつもりだったが、実際には僕の中に選択肢は一つしかなかった。

二つ以上の選択肢を用意する、と言う選択肢が僕の中には無かった。

大学受験

中学生のころから、僕は教員になることを期待されていた。 自分でもその期待に乗っていた。 期待に応えるつもりもあったし、いつのまにか自分でもそれが目標だと思っていた。

教育学部。地元の国立大学。

ここでも選択肢は一つだった。

自分が好きなことは何か、なにが向いているのか、考えなかった。

その後

派遣を転々としながら毎年一回の教員採用試験に臨むことになる。

今年の、28歳の春までそれが繰り返された。

選択

今、僕は選択をしようとしている。

自己分析や業界分析などを行い、選択肢を用意している。就職活動だ。

新卒枠ではもう入れないから、資格とって製作物作って、自分の武器を増やしていかないといけない。

大学卒業前に踏み切れていたら。

高校卒業前に将来のことや自分のことを深く考えていたら。

近くに道を示してくれる人がいたら。

しがらみに気を取られずに自分を主張できていたら。

これから

悔やむことは多くある。

だけど、結果論であって、僕にとってもっとも効率的な道じゃなかったかもしれないけど、これまでの人生で僕はたくさんの素敵な人に出会えたと思う。

もし、過去に戻れて、今と違う選択ができると言われても、この人たちとの出会いを無かったことにはしたくないと思う。

昔描いてた大人像には程遠い、不器用な自分だけど、これからも自分の人生を歩いていきたいと思う。

ずっと心に残っているフレーズを引用して良い感じに終わろうと思う。「紅」というライトノベルにでてくる登場人物のセリフだ。

いいことを教えてやろう。

人生には無数の選択肢がある。

が、正しい選択肢なんてもんはない。

選んだ後で、

それを正しいものにしていくんだ。

紅|ダッシュエックス文庫

StringBuilderの各メソッドについて

今週末にJava Programmer Iの試験の予約を入れた。税込28,728円である。

kazmaarakaki.hatenablog.com

実はもう黒本については一通り終わっていて、今週中に間違えたところを重点的にもう一周するか、という感じだ。

8章以降のまとめもこのブログにしていきたいのだが、ノートが手元に無いのでとりあえず試験頻出のStringBuilderクラスについてまとめておきたいと思う。

コンストラクタ

返り値 引数
- なし 長さ16のint配列を内部に持つインスタンスを作成する
- int capacity 引数で指定した長さのint配列を内部に持つインスタンスを作成する
- String str 引数で指定した文字列の長さ + 16の長さのint配列を内部に持つインスタンスを作成する
- CharSequence seq 引数で指定したシーケンスの長さ + 16の長さのint配列を内部に持つインスタンスを作成する

append

返り値 引数
StringBuilder boolean b booleanの文字列表現をStringBuilderに追加
StringBuilder double d doubleの文字列表現をStringBuilderに追加
StringBuilder float f floatの文字列表現をStringBuilderに追加
StringBuilder int i intの文字列表現をStringBuilderに追加
StringBuilder long lng longの文字列表現をStringBuilderに追加
StringBuilder char c charの文字列表現をStringBuilderに追加
StringBuilder String str 文字列をStringBuilderに追加
StringBuilder char str char配列の文字列をStringBuilderに追加
StringBuilder Object obj Objectの文字列表現をStringBuilderに追加
StringBuilder StringBuffer sb StringBufferが持っている文字列をStringBuilderに追加
StringBuilder CharSequence s CharSequenceが持っている文字列をStringBuilderに追加
StringBuilder char str, int offset, int len char配列の文字列を部分的にStringBuilderに追加
StringBuilder CharSequence s, int start, int end CharSequenceが持っている文字列を部分的にStringBuilderに追加
public class Main {
  public static void main(String[] args) {
    CharSequence seq = "abcde";

    new StringBuilder().append(true); // => true
    new StringBuilder().append(0.1); // => 0.1
    new StringBuilder().append(0.1F); // => 0.1
    new StringBuilder().append(1); // => 1
    new StringBuilder().append(1L); // => 1
    new StringBuilder().append('a'); // => a
    new StringBuilder().append("abcde"); // => abcde
    new StringBuilder().append(new char[]{'a','b','c','d','e'}); // => abcde
    new StringBuilder().append(new Main()); // => Main@1db9742
    new StringBuilder().append(new StringBuffer("abcde")); // => abcde
    new StringBuilder().append(seq); // => abcde
    new StringBuilder().append(new char[]{'a','b','c','d','e'}, 1, 2); // => bc
    new StringBuilder().append(seq, 1, 2); // => b
  }
}
  • Objectを引数に取れるので、基本的に何を入れても実行できる。
  • 書いてないけどfloatも普通に引数に使える。
  • 部分的に追加するオーバーロードが2種類ある。第一引数にcharを入れるかCharSequenceを入れるかでその後の引数の意味が変わる。
    • charを入れた場合:第二引数で指定した文字から、第三引数で指定した長さを追加する。
      (abcdeのインデックス番号1の文字bから2文字分取得して追加する => ab)
    • CharSequenceを入れた場合:第二引数で指定したポインタから、第三引数で指定したポインタまでの文字を追加する。
      <0> a <1> b <2> c <3> d <4> e <5><1>から<2>の間の文字を取得して追加する => b)

appendCodePoint

返り値 引数
StringBuilder int codePoint Unicodeコードポイントの文字列表現を追加する
public class Main {
  public static void main(String[] args) {
    new StringBuilder().appendCodePoint(0x3042); // => あ
  }
}

capacity

返り値 引数
int - 現在の容量を返す

デフォルト

容量に初期化時の文字列の長さ + 16文字分のバッファを持っている。

public class Main {
  public static void main(String[] args) {
    new StringBuilder().capacity(); // => 16
    new StringBuilder("012").capacity(); // => 19
  }
}

appendされた時

容量内で文字列操作を行う。

public class Main {
  public static void main(String[] args) {
    new StringBuilder().capacity(); // => 16
    new StringBuilder().append("012").capacity(); // => 16
  }
}

長い文字列をappendして容量を超えた時

  • 17文字~34文字:バッファが34文字分に自動で拡張される。
  • 34文字~:バッファが文字列の長さと同じ容量に自動で拡張される
public class Main {
  public static void main(String[] args) {
    String str1 = "[20文字の文字列]";
    String str2 = "[40文字の文字列]";
    new StringBuilder().append(str1).capacity(); // => 34
    new StringBuilder().append(str2).capacity(); // => 40
  }
}

1文字ずつappendして容量を超えた時

(前レベルバッファ容量 + 1) * 2のバッファ容量が新しく設定される。

  • 1文字~16文字:バッファ容量 16
  • 17文字~34文字:バッファ容量 34
  • 35文字~70文字:バッファ容量 70
public class Main {
  public static void main(String[] args) {
    for(int i = 0; i < 100; i++) {
      StringBuilder sb = new StringBuilder();

      for(int j = 0; j < i; j++) {
        sb.append("aa");
      }

      System.out.println(
          sb.length() + ": " + sb.capacity()
      );
    }
  }
}
0: 16
2: 16
4: 16
6: 16
8: 16
10: 16
12: 16
14: 16
16: 16
18: 34
20: 34
22: 34
24: 34
26: 34
28: 34
30: 34
32: 34
34: 34
36: 70
38: 70
40: 70
42: 70
44: 70
46: 70
48: 70
50: 70
52: 70
54: 70
56: 70
58: 70
60: 70
62: 70
64: 70
66: 70
68: 70
70: 70
72: 142
74: 142
76: 142
78: 142
80: 142
82: 142
84: 142
86: 142
88: 142
90: 142
92: 142
94: 142
96: 142
98: 142
100: 142
102: 142
104: 142
106: 142
108: 142
110: 142
112: 142
114: 142
116: 142
118: 142
120: 142
122: 142
124: 142
126: 142
128: 142
130: 142
132: 142
134: 142
136: 142
138: 142
140: 142
142: 142
144: 286
146: 286
148: 286
150: 286
152: 286
154: 286
156: 286
158: 286
160: 286
162: 286
164: 286
166: 286
168: 286
170: 286
172: 286
174: 286
176: 286
178: 286
180: 286
182: 286
184: 286
186: 286
188: 286
190: 286
192: 286
194: 286
196: 286
198: 286

charAt

返り値 引数
char int index 指定されたインデックスのcharを返す
public class Main {
  public static void main(String[] args) {
    new StringBuilder("hello").charAt(1); // => e
  }
}

codePointAt

返り値 引数
int int index 指定されたインデックスの文字のコードポイントを返す
public class Main {
  public static void main(String[] args) {
    new StringBuilder("Hello").codePointAt(1); // => 101
  }
}

codePointBefore

何に使うのこれ。。。?

返り値 引数
int int index 指定されたインデックスの前の文字のコードポイントを返す
public class Main {
  public static void main(String[] args) {
    new StringBuilder("Hello").codePointBefore(2); // => 101
  }
}

codePointCount

返り値 引数
int int startIndex, int endIndex 指定された範囲ののコードポイントの数を返す
public class Main {
  public static void main(String[] args) {
    new StringBuilder("Hello").codePointCount(0, 3); // => 3
  }
}

【Java Silver黒本】7章のつまづいたところまとめ

「サブ」と言ったら感覚的に「副」みたいなイメージだけど、Javaのサブクラスは継承元クラスを拡張するイメージ。

インターフェース

  • インターフェースのメンバは全てpublicにしなければならない
  • インターフェースのフィールドは自動的にstatic finalになる
  • インターフェースは多重継承が可能
  • インターフェースの抽象メソッドは具象クラスで全て実装すればよい
interface SampleInterface1 {
  String str1 = "hoge";
  public String str2 = "fuga";

  // インターフェース宣言の中で
  // public以外のアクセス修飾子を使用するとコンパイルエラーになる
  protected String str3 = "foo"; // コンパイルエラー

  void method1();
  public void method2();

  // インターフェース宣言の中で
  // public以外のアクセス修飾子を使用するとコンパイルエラーになる
  protected void method3(); // コンパイルエラー
}

interface SampleInterface2 {

}

// インターフェースは多重継承が可能
interface SampleInterface3
    extends SampleInterface1, SampleInterface2 {

}

// インターフェースを実装した中傷クラスでは
// インターフェースのメソッドを全てオーバーライドする必要はなく、
// 実装の一部をサブクラスに任せてもよい
abstract class SampleAbstractClass
    implements SampleInterface3 {
  // method1のみオーバーライドして
  // method2はサブクラスで定義する
  @Override
  public void method1() {

  }
}

public class Main extends SampleAbstractClass {
  public static void main(String[] args) {
    Main app = new Main();
  }

  public Main() {
    // インターフェースのメンバは全てpublic staticとなっている
    System.out.println(SampleInterface1.str1); // => hoge
  }

  @Override
  public void method2() {

  }
}

継承先に同名フィールドが存在する場合

  • フィールドを直接参照した場合は、型のクラスに定義された値を使う
  • メソッド経由でフィールドにアクセスする場合は、メソッドの指示に従う
class ClassA {
  int number = 10;

  public int getNumber() {
    return this.number;
  }
}

class ClassB extends ClassA {
  int number = 20;

  public int getNumber() {
    return this.number;
  }
}

public class Main {
  public static void main(String[] args) {
    Main app = new Main();
  }

  public Main() {
    ClassA hoge = new ClassB();

    // フィールドを直接参照した場合は、型のクラスに定義された値を使う
    System.out.println(hoge.number); // => 10

    // メソッド経由でフィールドにアクセスする場合は、メソッドの指示に従う
    System.out.println(hoge.getNumber()); // => 20
  }
}

継承関係にあるクラスのキャスト

  • BクラスがAクラスを継承しているとき、BインスタンスをA型にキャストすることは可能だが、逆は不可
class ClassA {

}

class ClassB extends ClassA {

}

public class Main {
  public static void main(String[] args) {
    Main app = new Main();
  }

  public Main() {
    ClassA a = new ClassA();
    ClassB b = new ClassB();

    // ClassBはClassAを継承しているため、ClassAの情報を持っている
    // そのためClassBのインスタンスはClassA型にキャストできる
    a = (ClassA)b;

    // しかし、ClassAは、クラス定義時にClassBの情報を与えられていないので
    // 互換性があるかどうかわからない
    // そのため、ClassAのインスタンスはClassB型にキャストできず
    // ClassCastExceptionがなげられる
    // b = (ClassB)a;
  }
}

サブクラスのコンストラクタ

  • サブクラスのコンストラクタ内にsuper()を記述しなかった場合、コンパイラによって自動的に追加される
  • super()の記述はコンストラクタの先頭行でなくてはならない
class ClassA {
  public ClassA() {
    System.out.println("A");
  }
}

class ClassB extends ClassA {
  public ClassB() {
    System.out.println("B");
  }

  public ClassB(int i) {
    this();
    
    System.out.println("B: " + i);

    // 先頭行以外にsuper()を書くとコンパイルエラーになる
    // super();
  }
}

public class Main {
  public static void main(String[] args) {
    Main app = new Main();
  }

  public Main() {
    new ClassB(0);
    // => A
    // => B
    // => B: 0
  }
}

オーバーライドのルール

  • シグニチャが同じであること
  • 戻り値型は同じか、サブクラスであること
  • アクセス修飾子は同じか、より緩いものであること

※クラス内のデフォルト修飾子がpackage privateであるのに対して、インターフェース内のデフォルト修飾子はpublicであることに注意。

class ClassA {

}

class ClassB extends ClassA {

}

abstract class ClassC {
  protected abstract ClassA method(int i);
}

class classD extends ClassC {
  public ClassB method(int i) {
    return new ClassB();
  }

  // 継承元メソッドのシグニチャと同じでなければならない。
  // 次のコードはコンパイルエラー
  @Override
  protected ClassA method(String s) {
    return new ClassA();
  }

  // 戻り値の型は継承元メソッドの戻り値の型と同じかサブクラスでなければならない。
  // 次のコードはコンパイルエラー
  @Override
  protected void method(int i) {

  }

  // 継承元メソッドのアクセス修飾子より緩い宣言でなければならない
  // 次のコードはコンパイルエラー
  @Override
  private ClassA method(int i) {
    return new ClassA();
  }
}

public class Main {
  public static void main(String[] args) {
    Main app = new Main();
  }
}

MariaDB (MySQL) の起動方法

今日は一日下のエラーと戦った。

ERROR 2002 (HY000): Can't connect to MySQL server on 'localhost' (10061)

f:id:KazmaArakaki:20170703223910j:plain

いろいろと調べた経緯も書こうと思ったが疲れ果てたので結論だけ。

MySQLを起動したらOK。

次のコマンドでプロセスを起動するか、

> mysqld --console

もしくは次のコマンドでサービスを起動する(sc startコマンドは管理者権限がないとはじかれる)。

> sc start MySQL

GUIからもサービスの起動は可能。

「コントロールパネル」>「全てのコントロールパネル項目」>「管理ツール」>「サービス」>「MySQL」>「サービスの開始」

疲れたけどなんか勉強になった。