OmniAICreator/Qiita-1.07M huggingface dataset:
[Vue/Nuxt]client-onlyのコンポーネントはrefで取得できない

`client-only`はSSRさせるアプリケーションにおいて、SSRさせずにクライアント側で展開させたい場合に使うタグです。

```vue
<template>
  <div>
    <client-only>
      no-ssr
    </client-only>
    <p>ssr</p>
  </div>
</template>
```

この`client-only`内に展開したコンポーネントを`ref`で取得するケースで、まず通常の取得ケースは以下のようになります。

```vue
<template>
  <div>
    <client-only>
      <my-component ref="myComponentRef" />
    </client-only>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue'

export default {
  setup() {
    const myComponentRef = ref(null)
    onMounted(() => {
      console.log(myComponentRef.value)
    })
    return { myComponentRef }
  }
}
</script>
```

`ref`で空の変数を用意しておいて、テンプレートの`ref`に代入、`onMounted`後であればVue v2の`this.$refs`の様にスクリプト内でコンポーネントにアクセスできます。
ですが、`client-only`内に展開したコンポーネントではこの方法ではアクセスできません。
このコードを実行すると`myComponentRef.value`は`null`となります。

### nextTickを使う

この場合はnextTickを利用すると解決できます。

```vue
<script>
import { ref, onMounted, nextTick } from 'vue'

export default {
  setup() {
    const myComponentRef = ref(null)
    onMounted(() => {
      nextTick(() => {
        console.log(myComponentRef.value)
      })
    })
    return { myComponentRef }
  }
}
</script>
```

おわり
JetBrains IDE 初期設定。

いつも忘れるのでメモ用に残しておく
----

- エディタ 色味の設定
File -> Settings -> Color Scheme

- Smart Key：Enter押したときに挙動が気持ち悪い
File -> Seffings -> Editor -> General -> Smart Keys
Enter -> Smart Indent：uncheck.
Enter -> Unindent on Backspace：Disabled
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24160/fc6b3bf0-e9ba-fdc9-12e3-a6c68b7bb55c.png)

- タブ(Tab)を半角スペース(whitesoace)にする
File -> Settings -> Editor -> Code Style -> [言語]
Use tab character: uncheck
必要に応じて tab size. indent, continuous indentの変更

- 半角スペース(whitespace)可視化
File -> Settings -> Editor -> General -> Appearance
Show whitespaces: check

あとはお好みで！！！
というか、SettingをExportしておけばいいんだよね...
ECCUBE開発リンクまとめ

## YOUTUBE
https://www.youtube.com/channel/UCCRgY9_0JNX0PonVT5WEgZQ/videos

https://www.youtube.com/watch?v=jvBf6BQlQuY&t=454s

## BLOG
https://jum11.com/ec-cube4/

https://a-zumi.net/category/ec-cube/ec-cube4/

https://kumahiyo.com/category/work/e_commerce/

## Document
http://ec4.umebius.com/

[【PDF】管理画面デザインガイド](https://doc4.ec-cube.net/pdf/ec-cube4_design-guide180930.pdf)

## Book
https://books.google.co.jp/books?id=QtyoDwAAQBAJ&lpg=PA230&ots=2ArWULk-Pg&dq=symfony%20ArrayCollection&hl=ja&pg=PP1#v=twopage&q=symfony%20ArrayCollection&f=true

## Tips
[会員制サイトを作ってみよう](https://tsubo.ec-cube.net/2017/03/29/6215)
Jestでスナップショットのパスを変更する

ちょっと面倒だったのでメモ

## サンプル

TypeScriptをdistにコンパイルして、.jsファイルでテストを実行する場合でサンプルを書きますが、
別のパターンでも簡単に応用できると思います。

**ファイル構造は以下の想定**

```
src/
  ├─ index.ts
  ├─ index.test.ts // テスト
  └─ index.test.snap <= ここにスナップショットを出力したい
dist/
  └─ src/
      ├─ index.js
      └─ index.test.js
```

**実行コマンドの想定**

```
jest dist/src/index.test.js
```

## 実装

```typescript:jest.config.js
module.exports = {
  ...
  snapshotResolver: './src/snapshotResolver.js',
};
```

```typescript:src/snapshotResolver.js
module.exports = {
  /**
   * テストファイルのパス => スナップショットのファイルパスに変換
   * dist/src/index.test.js
   * => src/index.test.snap
   */
  resolveSnapshotPath: ( testPath, snapshotExtension ) =>
    testPath.replace( 'dist/', '' ).replace( '.js', '' ) + snapshotExtension,

  /**
   * スナップショットのファイルパス => テストのファイルパスの変換
   * src/index.test.snap
   * => dist/src/test/create.test.js
   */
  resolveTestPath: ( snapshotFilePath, snapshotExtension ) =>
    snapshotFilePath
      .replace( 'src/', 'dist/src/' )
      .slice( 0, -snapshotExtension.length ) + '.js',

  /**
   * 整合性の確認のためのサンプルが必須のようです
   */
  testPathForConsistencyCheck: 'dist/src/example.test.js',
};
```

以上！
【TypeScript】React.VFCとは何ぞや

## はじめに
ReactにHooksが導入され、最近ではFunction Componentを採用することがほとんどになってきたように思います。

Function Componentを定義するための型として`React.FC`が提供されているのですが、いくらかのデメリット（というより使う必要のなさ）があり、敢えて使っていないプロジェクトも数多く存在しています。
そんな中、デメリットを少し解消した`React.VFC`が生み出されていたため共有します。

## React.FCとは
先述したとおりFunction Componentを定義するための型で、以下のように使用します。

```tsx
interface Props {
  hoge: string;
}

const Component: React.FC<Props> = (props) => {
  return (
    <div>
      <p>{props.hoge}</p>
    </div>
  );
};

const Parent: React.FC = () => {
  return (
    <div>
      <Component hoge="piyo" />
    </div>
  );
};
```

デメリットの一つとして、「`children`（タグの間の要素）の有無がわからない」というものがあります。
`React.FC`では`children`が最初から暗黙的に定義されてしまっているため、**必要ないときに渡してしまってもエラーにならない**仕様になっています。

```tsx
interface Props {
  hoge: string;
  // childrenを定義していない
}

const Component: React.FC<Props> = (props) => {
  // childrenは必要ない
  return (
    <div>
      <p>{props.hoge}</p>
    </div>
  );
};

const Parent: React.FC = () => {
  return (
    <div>
      {/* childrenがあるのにエラーが出ない */}
      <Component hoge="piyo" >
        children
      </Component>
    </div>
  );
};
```

これではTypeScriptの良さが半減してしまいます。

## React.VFCの登場
`React.VFC`では`children`が含まれておらず、先程のように渡そうとするとエラーになります。

```tsx
interface Props {
  hoge: string;
  // childrenを定義していない
}
// React.VFCに変更
const Component: React.VFC<Props> = (props) => {
  // childrenは必要ない
  return (
    <div>
      <p>{props.hoge}</p>
    </div>
  );
};

const Parent: React.VFC = () => {
  return (
    <div>
      <Component hoge="piyo">
        children
      </Component>
      {/* ERROR: Type '{ children: string; hoge: string; }' is not assignable to type 'IntrinsicAttributes & Props'.
          Property 'children' does not exist on type 'IntrinsicAttributes & Props'.ts(2322) */}
    </div>
  );
};
```

`children`が必要な場合は、以下のようにちゃんと明記してあげればOKです。

```tsx
interface Props {
  hoge: string;
  children: React.ReactNode;  // childrenを定義
}

const Component: React.VFC<Props> = (props) => {
  return (
    <div>
      <p>{props.hoge}</p>
      <p>{props.children}</p>  {/* "children"と表示される */}
    </div>
  );
};

const Parent: React.VFC = () => {
  return (
    <div>
      <Component hoge="piyo">
        children
      </Component>
    </div>
  );
};
```

`React.VFC`を用いることにより、`children`の有無がひと目で分かるようになりました！

## React.FCの今後
`React.VFC`の登場によって`React.FC`を使う理由がなくなってしまったのですが、このまま`React.FC`をなくしていくわけではないようです。
むしろReactとしては、今後も`React.FC`を主流として扱っていくようです。

というのも、`React.FC`に`children`が含まれないべきだという考え方はもとから存在しており、`@types/react 18`からは含まれなくなる予定です。
これは**破壊的な変更**であることから、移行措置として導入されたものが今回の`React.VFC`であるようです。

これからの開発では、一旦すべて`React.VFC`で定義し、必要に応じて`children`を定義するようにしましょう。
`@types/react 18`がリリースされればどちらも同じものになる（はず）なので、その際に`React.VFC`を`React.FC`に置換すると良いでしょう。
関数の→型について

関数でよく見る

func sample() →　なんとか

これについて余裕がなく調べることも聞くこともできなかったんですが、実務を通して理解したので忘備録

func sample() →　なんとか

上記の　→　なんとかの部分には型が入っていて

必要ない場合は書かなくて良い

必要というか型を指定したいところは

配列であったり、文字列であったりいろいろ使える

例えばこんな使い方もできる

func a() → 取得したいデータ

func a() →　取得したい配列

この前見たパターンはもしデータベースの情報を取得して同じクラス上でやるとしたら、ループを回してその中でifでゴニョゴニョしてみたいな処理を関数でデータを取れるようにして欲しい場所だけに適用するみたいなパターン。

こんな使い方ができるようになったら楽しいだろうなと思いつつ、仕組みを考えるのが結構大変そうだななんて思いました。

あまり参考にならないかもですが、自身の忘備録なんで時間の余裕のある方がふーーーんそうなんだみたいな感じで流し読みするのがちょうどいいのかなと。

そんな感じで終わりにします。
Konyで外部ライブラリをインポートする方法

目次
---
1.はじめに
2.実装方法
3.まとめ


はじめに
---
外部ライブラリとは、他の開発者が作成した様々な関数をパッケージにしたもので、用途に応じてインポートして関数を使用することができます。
例えば、チャットアプリを作成したい時には、データの送受信に役立つ機能がパッケージ化された外部ライブラリをインポートすることで、自分で一から作成することなく欲しい機能を実装することができます。
この記事では、Konyで外部ライブラリをインポートする方法をご紹介します。
それでは解説していきます。


実装方法
---
ライブラリ内のアラートを出すメソッドを、Formに設置したボタンで呼び出すデモを作成しながら解説していきます。
完成イメージはこちらです。
![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/b3816e44-cc20-e086-688c-25132c1a0c50.gif)


今回は分かりやすいように、インポートする jsファイル(ライブラリ)を作成します。
アラートを出す処理を記載した``setAlert.js``を作成しました。こちらをKonyにインポートします。

```js:setAlert.js
define(function(){  
  function setAlertSample(){
    alert('Konyでライブラリをインポート');
  }
  return {
    setAlertSample : setAlertSample
  };
});
```

Konyでは、外部ライブラリに対してFormやCompornentのようにインポート機能がないため、対象のファイルを直接フォルダーに入れていきます。
パスは以下の通りです。
**"Project" > modules > require**
![スクリーンショット 2021-03-02 12.18.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/40b52d4d-79d4-7f04-ce11-637a1c02d894.png)

requireフォルダに対象のファイルを追加したら、**File > Refresh**でプロジェクトを更新します。Project> Modules > require に追加したファイルがあることを確認してください。
![スクリーンショット 2021-03-02 16.57.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/e51dbfbc-c86b-35b7-1c26-9cdbe26db82b.png)

#### デモの作成
ボタンを押すことで追加した``setAlert.js``内の``SetAlert``を呼び出すデモを作成します。

**1. Widgetの作成**  
Formを作成して、Button Widgetを作成します。
![スクリーンショット 2021-03-02 16.58.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/6780eb73-368e-3636-21cc-5c86ee4441ea.png)

**2. frmControllerに処理を追加**
ボタンを押した際に動く**onClick**メソッドを作成します。

```js:formDemoController.js
  onClick : function() {
    require(['setAlert'], function(setAL) {
      setAL.setAlertSample();	
    });
  }
```
module > require に格納した**setAlert**を``require``メソッドで取得して``setAlertSample``を実行しています。functionの引数には、setAlertメソッドで**return**した中身が格納されています。

```js:setAlert.js
  return {
    setAlertSample : setAlertSample
  };
```
複数のmoduleを使用したい時は、以下のように指定することができます。
``require(['xxx'],['yyy']), function(XX, YY) {})``
  
**3. Actionの紐付け**
Controllerで作成した``onClick``をButtonに紐付けます。
Buttonを選択して、右の**Action**タブ > **onClick**横の**Edit** > **Invoke Function** > **onClick**を選択します。
![スクリーンショット 2021-03-02 12.29.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/7dc53aa9-acf8-2e1a-ff95-2acab1d96423.png)

**4.ビルド結果**
![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/b3816e44-cc20-e086-688c-25132c1a0c50.gif)



まとめ
---
今回はKonyで外部ライブラリをインポートする方法について紹介いたしました。
ライブラリのインポート以外にも、requireを使えばソースを役割ごとに分けてコードの可読性をあげることも可能です。是非、お試しください！


**参考**

https://basecamp.temenos.com/s/question/0D56A00000TMn2XSAT/i-would-like-to-know-how-to-import-external-javascript-libraries-into-kony-visualizer-or-the-correct-way-of-using-other-libraries

https://basecamp.temenos.com/s/article-detail/a046A000001ld96QAA/require-modules-in-kony-v8

https://basecamp.temenos.com/s/question/0D52K00004EtxLqSAJ/how-to-call-a-module-defined-in-modulesrequire-from-form-controller
JDLA E資格取得までの学習内容のまとめ

# はじめに

2021年にJDLA E資格を受験したものです。
これまでに学習したものをまとめて共有したいと思います。
これからAI学習する方に少しでも参考になればと思います。

# 学習について

学習については、以下で進めて行きました。

1. 認定コース受講 
  
  当時の最安値ということもあり、以下のコースを受講しました。
　 https://portal.ai-trend.jp/ai_engineer_course
　　
　　質問の受付や２回の面談などのサポートもありますが、あまり利用せず、動画の視聴と演習課題の作成を行いました。
　　最近ではslackを通じ受講生同士で交流することができ、輪読会などのイベントも開催されています。
　　他のコースの話は聞いていないのでわかりませんが、個人的には費用以上の価値があったと思います。

２．無料動画による学習

　　線形代数等の数学については、以下がお勧めです。
　　【大学数学】線形代数入門①(概観&ベクトル)【線形代数】
　　https://www.youtube.com/watch?v=svm8hlhF8PA

３．Udemy受講
　
　　資格対策とだけでなく、以下のコースをUdemyで受講しました。
　　
　　（１）【キカガク流】人工知能・機械学習 脱ブラックボックス講座 - 初級編 -
　　　　　https://www.udemy.com/share/101rnwCEoTdVZRQHg=/

　　　→ 数学の話と、Pythonでの実装の話を手書きとPythonの画面を交えて解説しており、初心者に非常わかりやすいと思います。
　　

　　（2）【キカガク流】人工知能・機械学習 脱ブラックボックス講座 - 中級編 -
        https://www.udemy.com/share/101rnwCEoTdVZRQHg=/
　　　→ 上記と同様です。
　　　　数学の話と、Pythonでの実装の話を手書きとPythonの画面を交えて解説しており、初心者に非常わかりやすいと思います。

　　（3）【キカガク流】プログラミング力向上のためのPythonで学ぶアルゴリズム論（前編）
         https://www.udemy.com/share/102cvsCEoTdVZRQHg=/
      → １から自分で考えてコーディングをする経験が少なかったので、１からコーディングする考え方が学べてよかったです。

　　(4) 【世界で18万人が受講】実践 Python データサイエンス
         https://www.udemy.com/share/101s92CEoTdVZRQHg=/
      → ともかくデータサイエンスで使用するpythonのコードが網羅的に学べます。

　　(5) 【世界で34万人が受講】データサイエンティストを目指すあなたへ〜データサイエンス25時間ブートキャンプ〜
        https://www.udemy.com/share/102G3wCEoTdVZRQHg=/
     → データサイエンスの知識と実践の両方を学ぶことができます。

　　(6) 【画像判定AIアプリ開発・パート1】TensorFlow・Python・Flaskで作る画像判定AIアプリ開発入門
        【画像判定AIアプリ開発・パート2】Django・TensorFlow・転移学習による高精度AI アプリ開発
        https://www.udemy.com/share/101YmgCEoTdVZRQHg=/
        https://www.udemy.com/share/102XkyCEoTdVZRQHg=/
     → 実際にDeep learningで作成した画像判定AIを使ってWebアプリケーション、iOSアプリケーションを作ることができます。

　　(7) Learn BERT - most powerful NLP algorithm by Google
       https://www.udemy.com/share/103cKyCEoTdVZRQHg=/
       →試しに英語講座を受けてみました。内容を理解しているところは説明内容わかるのですが、今ままで知らなかったことを説明している部分は、あまり理解できませんでした。
　　　　　コードは読めばわかるので、実践的な内容であれば英語講座でもそんなに問題ないことがわかりました。



４．書籍による学習
　　
　　E資格のPythonコード問題に対する対策は、やはり以下の２冊になると思います。

　　ゼロから作るDeep Learning　Pythonで学ぶディープラーニングの理論と実装
    https://books.rakuten.co.jp/rb/14424645/
    ゼロから作るDeep Learning 2　自然言語処理編
    https://books.rakuten.co.jp/rb/15381732/

   直前の試験対策は、以下が良いと思います。
    ディープラーニング E資格　エンジニア　問題集
　　https://book.impress.co.jp/books/1118101176
　　

５. 実戦
　　
　実践の場としては、Kaggleが一番メジャーだと思いますが、Signateのコンペや練習問題を利用しています。
  https://signate.jp

　
# 最後に

　まだ、E資格の結果通知は頂いていませんが、これまで学習した内容を簡単にですが、まとめてみました。
カフェでプログラミングしてる風（でも何もやってない）Java（クソ）コード

# おしゃれなカフェで...
私はエンジニア。
コーヒー片手にMacでプログラミングしています。
今日はどんな素晴らしいアート(プログラム)が生まれるかしら？♪

的な事を演出したいときって、誰にだってありますよね？

今日は、カフェでMacを使っている時に周りから
「お、この人Macで何かやってるな。何か難しそうな事をしているからエンジニアなんだな。素敵だな。」
と思わせる素敵な（Kuso）プログラムを用意しました。

ぜひ、おしゃれカフェで使ってみてください。

# ターミナルで実行すればカッコイイJavaコード2つ

## ステータスが変化してる風コード

まずは、何か処理が動いているように見せるコードがこちら！

```java:DungStatusChange.java
/**
 * ステータスを更新してる風コード
 */
public class DungStatusChange {
  public static void main(String[] args) {
    // 50文字まで#を表示する
    int x = 50;
    // カウントアップする変数
    int y = 0;
    while (true) {
      if (x != y) {
        // 上限まで#を足していく
        System.out.print("#");
      } else {
        // 50文字になったら「 done!! + 改行」を出力し
        // 何かが終わった感を演出
        System.out.println(" done!!");
        // カウントアップをリセット
        y = -1;
      }
      // カウントアップしていく
      y++;
      // 高速で出力すると素敵感が出ないので
      // 出力待ち時間を作成する
      int sleepTime = 10;
      // ランダム値にマッチすると待ち時間をさらに長くする。
      // 何か大きな処理をしているように見えること請け合い
      int osooso = (int)(Math.random() * 10);
      if (4 < osooso  && osooso <= 6) {
        sleepTime = 100;
      }
      try {
        // 待つ
        Thread.sleep(sleepTime);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}
```

これを実行したものがこちら！
![DungStatusChange.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567235/873eeacf-2893-617f-4d29-17b420916766.gif)

どうですか、この何かしている感！！笑
こりゃきっと何かしてますね！！笑

## コンパイルが動いている風コード

そして、何かを自動で作っている感を演出するコードがこちら！

```java:DungCompiler.java
/**
 * 数字の羅列を出力し、何かを自動で作ってる風コード
 */
public class DungCompiler {
  public static void main(String[] args) {
    while (true) {
      // カウントアップ
      int x = 1;
      // 出力文字列
      String code = "";
      while(true) {
        // 0から9までの数値をランダムで出力
        int num = (int)(Math.random() * 9);
        // 出力文字列に足していく
        code += String.valueOf(num);
        if (x == 50) {
          // 50文字でブレイク
          break;
        }
        x++;
      }
      // 数値の羅列を出力：いい感じにコンパイルしてる感が出る
      System.out.println(code);
      // 高速で出力すると素敵感が出ないので
      // 出力待ち時間を作成する
      int random = (int)(Math.random() * 10);
      int sleepTime = 100;
      // ランダム値にマッチすると待ち時間をさらに長くする。
      // 何か大きな処理をしているように見えること請け合い
      if (4 < random  && random <= 6) {
        sleepTime = 500;
      }
      try {
        // 待つ
        Thread.sleep(sleepTime);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}
```

動かすとこんな感じ！
![DungCompiler.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567235/e57495c8-1474-75e6-bda6-780cfced4f81.gif)

どうですか、これは確実に何かを自動で作っていますね！！
ヘタすりゃ、スカウトされますよ！！

さらにこれらのコードを２つ同時に起動しておくと完璧です。
![cap01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567235/577e677c-49b6-a780-60d0-9408e3977bda.gif)

ね？完璧でしょ！？笑
よ！！マルチタスク人間！！笑

これでちょっとイイ感じのスーツ着て、髪の毛をナチュラルにキメて
片手にコーヒー、片手にiPhoneで、ちょっと考えてるフリすりゃもうデキる人間にしか見えないでしょ？！
写真撮ってsnsにアップすればより多くの満足感が得られますね！

自己肯定感爆上げですわ！！

# ついつい。。。
夜中に酒飲んで勢いで作っちゃいました。笑
動画の撮り方もよくわからずグズグズしてますね。苦笑
これを恥ずかしげもなくカフェに持ち込めればテンションが上がるはず。
自己演出は結構テンションが上がりますね。

一応Kusoコードgithubに上げたんで好きに使ってください。

https://github.com/3sLaboo/nice_cafe_code

ありがとうございました。
Dockerコマンド チートシート


## FEOM RUN CMD
### はじまり
#### FROM<image>: Docker imageのベースとなるDocker imageを指定
#### RUN<command>: コマンドを実行（image layerを作成）
### 終わり
#### CMD["executable","param1","param2"]

### run = create + start

### -it
- `-i`はインプットのチャネルを開く。stdinのチャネルを開く
- `-t`は出力した結果を開く。整えてくれる

### デフォルトコマンドの上書き
```
docker run <image> <command>
```
## コンテナ名の指定
```
docker run --name <container_name> <image>
```



## foreground コンテナを起動するけど、閉じたらコンテナを削除
```
docker run --rm <image>
```

## コンテナの削除
### 削除したいコンテナはPSを予め止める必要がある
```
Docker stop
```

### IDなどを指定して削除
```
docker rm
```
### まとめて削除
```
docker system prune
```


## detached バックグラウンドでコンテナを回す
```
docker run -d <image>
```

## Docker buildの流れ　コンテナからイメージを作る

```
cd ~~~~~   ## Dockerfileがあるカレントディレクトリまで移動
docker build .     ## .はカレントディレクトリ
docker build -t new-ubuntu:latest . ## imageに名前をつける -> new-ubuntu:latestは自由に名前をつけていい

```

## Dockerimageをrunする

```
docker run -it new-ubuntu bash ## new-ubuntuは自分が作ったimage
```

## Dockerfileとは？
- Docker imageの設計図
- 

## RUNはLayerを作る。CMDは作らない
## 参考資料

[米国AI開発者がゼロから教えるDocker講座 \| Udemy](https://www.udemy.com/course/aidocker/)
コンポーネントの Expose skinをOnにしてウィジェットの見た目を変更する

#目次
1. はじめに
2. 実装方法
3. まとめ
4. 参考

#はじめに
コンポーネントを作成後、元のソースを変更せずに、アプリやフォームに配置したコンポーネントのウィジェットの外観を変更したい場合、
コンポーネントのExpose skinをOnにすることで、変更を行うことができます。
今回はコンポーネントの Expose skinをOnにしてウィジェットの見た目を変更する方法についてご紹介します。

なお、Expose skinをOffにしている場合、元のソースを編集する必要があります。

#実装方法
####**①コンポーネントの作成**
コンポーネントを作成します。
左のメニューから`Template` > `Component`のメニューを開く > `New`をクリック > `with Contract`を選択

※コンポーネントについては下の記事をご参照ください。
https://qiita.com/Kony_Team/items/a25b322d9524f9f1ac92

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/0bc061c4-9468-423a-299e-067978d17219.png)
青色のFlex Containerを配置しました。

次にExpose skinをOnにします。
右のメニューから`Skin` > `Normal` > `Component` > `Expose skin`をOn
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/add1e712-2822-5b18-7240-06a869887118.png" width=50%>

####**②フォームにコンポーネントを配置**
1) フォームを新規作成
2) 先ほど作成したコンポーネントのメニューを開き、`Insert Into`を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/7a5c5ae8-0aaf-f87c-459f-8ff7cce9eef2.png)

3) 右のメニューから`Properties` > `Skin` > 上の`Expose Skins`のリストをクリックし、`Normal(skin1)`を選択
この時点では、先ほど作成したコンポーネントのSkinが反映されている
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/96c554e0-02d7-f9b1-0039-7bf385bdeb84.png" width=50%>

4) 好きなSkinの設定をする
今回は、ピンクにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/8e178cb2-9bd2-27fb-8643-7cbf2d8a38d2.png)

これで元のコンポーネントに影響を与えずに、
このフォーム限定のSkinを作成することができました。

念のため、先ほど作成したコンポーネントのSkinが変更されていないか確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/b51a7fc3-3136-d89c-49ba-3a360dea306d.png)
変更されていません。

####**③実装の確認**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/fc4e17f4-bad5-733b-d74d-4b742be72190.png)
先ほど設定したピンクが表示されています！

#まとめ
今回は、コンポーネントの Expose skinをOnにしてウィジェットの見た目を変更する方法について説明しました。
みなさんもぜひ活用してみてくださいね:wave:

#参考
Create a Component：
https://docs.kony.com/konylibrary/visualizer/visualizer_user_guide/Content/C_CreatingComponent.htm

Kony Visualizerでコンポーネントを作成する:
https://qiita.com/Kony_Team/items/a25b322d9524f9f1ac92
マーケティング用語

#まず初めに
売上向上の５原則は以下。

①新規顧客を増やす
②既存顧客を逃さない 
③リピート購買増やす  
④商品単価を上げる
⑤商材を増やす 

どれが目的かでアプローチが変わってくる

#ブランド強度分析
ブランド強度分析10項目
① 概念明瞭度
② 関与浸透度
③ 統治管理度
④ 変化対応度
⑤ 信頼確実度
⑥ 要求充足度
⑦ 差別特有度
⑧ 体験一貫度
⑨ 存在影響度
⑩ 共感共創度

ブランド価値の評価は「財務分析xブランド役割分析xブランド強度分析」で導き出せる。

#ファネル
マーケティングファネルのことを指しますが、これは、お客さまが購入までの過程でたどる可能性のある最も単純なジャーニーの概要を示したもの。
マーケティングファネルの最上部は、認知段階の購入者を表し、ファネルの最下部は購買段階の購入者を表す。

| 1 | 2 | 3 |
|:-:|:-:|:-:|
|  上位ファネルマーケティング |  認知度を高める戦略 |  TVCMなどで名前を知ってもらう段階 |
|  ミッドファネルマーケティング | 検討を強化し、カテゴリー内で目立つための戦略  |  ブログ・SEO強化・比較サイトなど |
| 下位ファネルマーケティング  | 既に購入検討段階のターゲットを逃さない為の戦略  | お問い合わせボタンなどの色や配置・デザイン  |


#フルファネルマーケティング
ユーザーはストアでのショッピング中に携帯電話で商品レビューをざっと見たり、テレビコマーシャルを見ながらブランドのソーシャルメディアフィードやウェブサイトを切り替えて閲覧したりする。
その経路(カスタマージャーニー)は未知数であり、今までの「上位から下位ファネルへ順々に行く」といった直線的ルートではなく変則的に上位からミッドファネルを飛ばして下位ファネルへ到達する、ということもある。


#広告の費用対効果を測る指標
「かけた広告費（とそれによるコンバージョン）を上回る利益が出たか？」を測定するためには、CPAとROASという指標がある。

###CPA
Cost Per Acquisitionの略。1コンバージョンあたりのコストのこと。
`CPA＝コスト÷コンバージョン数`
ここでいうコストとはクリック数×平均CPCを指す。
この数値が低いほど、費用対効果の高い広告という意味。
CPAを用いることで、どの広告がより安価でコンバージョンを獲得することができるかを比較・検討することができる。
実際のコンバージョン数とCPAの両方を比較しながら検討する必要がある。
CPAが想定より高い場合は、コストを抑えるか、コンバージョン数を増加させる対策が必要となる。入札価格の見直し、予算設定の見直し、広告の品質の向上、リンク先URLとリンク先ページの見直しなど

###ROAS = 広告の費用対効果
Return On Advertising Spendの略。
広告経由で発生した売上を広告費用で割った数値のことで、広告の費用対効果を表す。
`売上高÷広告費用費×100（％）`で算出が可能。
ROASが低い場合は、売上をアップさせるか、コストを抑える必要がある。具体的な対策としては、コンバージョン率の向上、売上増に結び付くリンク先ページの構築、入札価格と予算設定の見直しなど

###CPAとROASの使い分けは？
|  | CPA | ROAS |
|:-:|:-:|:-:|
| 意味	| コンバージョンの獲得単価	| 投資広告費の回収率/広告掲載料金1円あたりの売上額    |
| 計算方法 | コスト÷コンバージョン数 | 売上÷コスト×100（％) |   
| 適しているサイト  | 会員登録や資料請求などオンラインだけで購買活動が完結しないサイト（例：転職、不動産）扱っている商品が1種類だけのサイト・複数の商品を同一価格で販売しているサイト  |  オンラインだけで購買活動が完結し、かつ価格帯の異なる多種多様な商品を販売しているサイト
| 適さないサイト　|	販売商品の価格帯がさまざまなサイト　|	会員登録や資料請求など実際の売上を測定できないサイト     |

#CPO = 注文１件あたりに必要となる費用
Cost Per Orderの略。営業の人件費、広告費などの合計。

#ROI
Return On Investmentの略。「投資額（広告における広告費）に対してどれだけの利益を得ることができたのか」を測るための指標。
ROASは「売上高を基準にしている」が、ROIは「利益額を基準としている」。

#アトリビューション
コンバージョンに至るまでの各アクションの貢献度を分析して評価すること。
例: その時にクリックはしなかったが印象に残ったバナー広告があり、時間が経ってからその商品名を検索して購入まで至った場合、従来の考えではバナー広告は評価対象とならない。しかし、実際にはバナー広告は最初のきっかけを与えており、重要な役割を果たしている。


#アクティブユーザーを示す指標
###MAU(Monthly Active Users)
月あたりのアクティブユーザー数


###DAU（Daily Active Users）
1日あたりのアクティブユーザー数
ウェブページを崩壊させてみたいときに唱える呪文

ウェブページの見た目を崩壊させてみたいときに唱える呪文（JavaScript）です。

ウェブページを開いて、開発ツールのコンソールに下記コードをおもむろにペーストして実行。

``` javascript 
var lastEl;
var whileLastEl = () => {
  var el = document.lastElementChild;
  while (el !== null) {
    el = el.lastElementChild;
    if (el !== null) {
      lastEl = el;
    }
  }
}
var removeEl = () => {
  el = document.lastElementChild;
  whileLastEl();
  lastEl.remove();
  var timeoutId = setTimeout(removeEl, 100);
    if (lastEl.tagName === 'BODY') {
      clearTimeout(timeoutId);
    }
 }
setTimeout(removeEl, 100);
```

ウェブページを一番下までスクロールしてみてください。
ひとつずつ要素が消えていきます。

もう少し詳しく説明すると、
DOM ツリーの、末っ子要素の、末っ子要素の、末っ子要素
という具合に null が返されるまで捜査して一番最後の要素を消します。

これを 100ミリ秒ごとに DOM 要素がBODY になるまで繰り返します。

クリックなど、何かイベントに仕込んでもいいかもしれません。
Java のマルチスレッド備忘録

## スレッドの状態

[Thread.State](https://docs.oracle.com/javase/jp/1.5.0/api/java/lang/Thread.State.html) に定義されている

| 状態 | 説明 |
|---|---|
| NEW | 起動していないスレッドの状態 |
| RUNNABLE | Java 仮想マシンで実行されているスレッドの状態 |
| BLOCKED | ブロックされ、モニターロックを待機しているスレッドの状態 |
| WAITING | ほかのスレッドが特定のアクションを実行するのを無期限に待機しているスレッドの状態 |
| TIMED_WAITING | 指定された待機時間、ほかのスレッドがアクションを実行するのを待機しているスレッドの状態 |
| TERMINATED | 終了したスレッドの状態 |
Anaconda覚え書き

## パッケージ管理
### パッケージのインストール可能バージョン一覧の取得
```shell
> conda search <パッケージ名> -c <チャネル名>
```

### パッケージの特定バージョンのインストール
```shell
> conda install <パッケージ名>=<バージョン> -c <チャネル名>
```
サーバーサイドの全体像

#サーバーとは


サーバーとは、情報やデータをいつでも提供してくれる、提供専用のコンピューターのこと。

個人用のPCと比較した時に、大きく異なる部分は２つ

・IPアドレスが固定されている
・レスポンスを返すようにOSとアプリケーションが設定されている


##IPアドレスが固定されている

普段私たちが使っているPCは、IPアドレスが固定されていません。
なぜなら、

・情報を取得する側であり、提供する側でないから
・セキュリティの観点から同じIPアドレスだと外部からの攻撃を受けやすいから

※AWSのEC2もデフォルトではIPアドレスが変わってしまう設定になっています。そこでElastic IP addressをEC2にアタッチさせることで、IPアドレスを固定させます。IPアドレスを固定化した後は、Route53(DNSサーバー）でドメインとIPアドレスを対応させます。こうすることで、クライアント側（個人用のPC)からサーバーへリクエストを送ることができます。

しかし、これだけではダメです。
サーバーがリクエストを返すには、OSを設定する必要があります。


##サーバーのOSの設定


OSとは、スマホやパソコンに搭載された基本ソフトウエアのことです。スマホでアプリケーションが使えたり、パソコンで基本的な操作ができるのは、全てOSがあるおけげです。またWebサービスやアプリケーションを動かすには、必ずOSが必要です。そのためサーバーにもOSを入れないと動かすことができません。

では、サーバーでは具体的にどのようなOSを使うかというとLinux(RedHat, CentOS, Amazon Linux 2など）が一般的です。Linuxは、サーバーの用途にあったOSとなります。


###サーバーの管理と操作

サーバーは通常、温度管理やセキュリティが行き届いた専用施設であるデータセンターに置かれています。
※EC2もAWSが管理するデータセンタに置かれています。

サーバーは離れた場所にあるので、遠隔で通信してログインして操作する必要があります。

操作の設定には、

・CUI : コマンドを使って操作する
・GUI : マウスや指を使って直感的に画面を操作する

の2種類が存在します。

サーバーでは、CUIを使うのが一般的です。
理由は、コマンドを打って作業した方が作業効率が良いからです。


##サーバーのアプリケーションの設定

サーバーにOSを設定しただけでは、サイトを見ることはできません。具体的なアプリケーションを設定してサーバーにアップロードし、それをOSを連携させることが必要になります。


###HTML,CSSの仕組みとデメリット


HTML,CSSのファイルをアップロードすると、シンプルなWebページだけのサービスが提供することが可能です。クライアント(あなたのPC）が、「Webページの情報ください」というシンプルなリクエストを出して、サーバーがHTML, CSSで作られたファイルをレスポンスとして返す。これだけでもシンプルなWebページを世界中に公開することができます。

しかし何度アップデートしても同じページが表示されるだけで、ユーザごとのプロフィールページ、データなどは扱うことができません。


###データベース、サーバーサイド言語の存在意義
クライアントからリクエストを受け取ったサーバーは、クライアントにリスポンスを返す前に処理を行っています。


SNSのプロフィールを更新したり、いいねを押したり、世界中の人に最新のWebページを更新するためには、２つの仕組みが必要です。

それは、データを保存と作成する仕組みです。

####データの保存(データベース）

例えば、SNSのユーザのプロフィール情報、サイトの更新情報、獲得したいいね数などの膨大の情報はWebページ運用するために管理する必要があります。

このデータを保存する場所をデータベースと言います。
そのデータベースに保存されているデータを取り扱う言語があります。
それが、SQLです。

ここでの注意点は、
データベースはあくまで情報の保管庫であり、データベースのデータをSQLで取り出すことはできます。しかし、そのデータを加工したり表示したりするには別の仕組みが必要になります。

####データの作成(サーバーサイド言語)

そこで必要になるのが、サーバサイド言語です。

サーバサイド言語は、

・取り出したデータをどのように加工するか
・どのように表示するか

処理する言語です。

Ex) python, Ruby, PHP, Java

SNSの例だと、

⓵あなたがSNSを見たいと、サーバーにリクエストを送ります。
⓶サーバーがあなたのプロフィールの情報(データ)を、サーバーサイド言語を用いてデータベースから取り出す
⓷取り出したデータをHTMLの中に組み込んで、あなたのプロフィールが入ったWebページを生成する
⓸その生成したWebページをリスポンスとして返す

という流れになります。


※AWSでは、EC2(サーバー）の中にデータベースやサーバサイド言語もインストールして、EC2一台でWebサービスを構築することも可能です。しかし通常はセキュリティの観点からデータベースだけ別のサーバーに分けて配置します。そこでRDS(データベースのサービス)を用いて、その中のEC2のデータベースにソフトウエアをインストールして、AWS上で使いやすくアレンジしています。
Vimの設定/変数の一覧を確認する (Vim/Vimscript)

#概要
Vimscriptに親しむため、一覧を出すコマンドを確認してみる。
#内容
##環境
macOS Catalina
VIM - Vi IMproved 8.1 macOS version Normal version without GUI.

今回は基本的に、外部ファイル記述保存し、vim起動後、コマンドを実行する。
##レジスタの一覧
```Vimscript
:registers
```
```:output
Type Name Content
  c  ""   を得る
  l  "0   ##環境^J
  l  "1   ^J
  l  "2   #環境^J
  l  "3   ^J
  l  "4   SayHello^J
  l  "5   Say Hello world^J
  l  "6   scriptencoding utf-8^J
  l  "7   SayHello^J
  l  "8     echo a:0^J  echo a:1^J  echo a:2^J  for s in a:000^J    echon ' ' . s^J  endfor^J
  l  "9     echo^J
  c  "a   A^R-^[u$pj
  c  "d   d^[dq
  c  "j   jjjjjjjjjj
  c  "k   kkk^[
  c  "q   yyp^A
  c  "v   j^[kkjjjggFkkkjjj
  c  "w   2@qj
  c  "-   を得る
  c  "*   Vimscriptに親しむため、コマンドから関数に引数を渡してみる。
  c  ".   ```:output^@```
  c  ":   let name = "hello"
  c  "%   qiita1.txt
  c  "#   qiita1.txt
  c  "/   \<super\>
```
##マーカの一覧
```Vimscript
:marks
```
```:output
mark line  col file/text
 '     45    0
 0      6    0 ~/hello.vim
 1      1    0 ~/hello.vim
 2      1    0 ~/hello.vim
 3      5    6 ~/hello.vim
 4      5    6 ~/hello.vim
 5      5    6 ~/hello.vim
 6      5    6 ~/hello.vim
 7      5    0 ~/hello.vim
 8      5    0 ~/hello.vim
 9      5    0 ~/hello.vim
 "      1    0 #概要
 [      1    0 #概要
 ]     56    0 #今後
 ^     43    6 :marks
 .     43    5 :marks
 <     47    0 ```Vimscript
 >     49    0 ```
```

##その他の一覧
引数を渡さないことで、変数・バッファなどの一覧が確認できる。
cf. [現在の設定を出力する](https://nanasi.jp/articles/code/coding/current-status.html)

##蛇足
見られて困る内容は出力されてないはず。。
#参考にさせていただいた頁・本
- https://nanasi.jp/articles/code/coding/current-status.html

#感想
整理できて良かった。
正確にはVimscriptの話題ではないかもしれないが、通ずると思うのでタグはそのままとした。
#今後
たまに確認して、慣れていきたいと思う。
Firestore データ取得の制限について

# 概要
- 普段大変お世話になっているFirestoreですが、DBから直接データを取得しようとすると、制限があるので自分なりにまとめました。
- 今回は下記の様な例で説明していきたいと思います。6人の男の子の身長と体重が入ったDBです。

**collection名：boys**

|id|name|height|weight
|---|---|---|---
|0|一郎|160|60
|1|二郎|165|65
|2|三郎|170|70
|3|四郎|175|75
|4|五郎|180|80
|5|六郎|185|85



# orderByの制限
## 不等号を使った複数フィールドの絞り込みができない
- 例のデータだと、例えば、身長160cm~170cmかつ、体重65kg~80kgの人、みたいな絞り込みが仕様上できません。

```js
  let boysRef = db.collection("boys").where("height", ">=", 160).where("height", "<=", 170).where("weight", ">=", 65).where("weight", "<=", 80); 
  let items = await boysRef.get(); // エラー
```
- 出てくるエラーはこんな感じ。`不等号を含むwhereフィルターは全て同じフィールドに対しての指定である必要があります`みたいに言われます。
- 今回の例でいうと、身長160cm~170cmの人、体重65kg~80kgの人、どっちか片方だけの絞り込みはできます。

```
Uncaught (in promise) FirebaseError: Invalid query. All where filters with an inequality (<, <=, !=, not-in, >, or >=) must be on the same field. But you have inequality filters on 'height' and 'weight'
```

## 不等号をつかった絞り込みと、orderByに異なるフィールドを指定できない
- 今回の例だと、例えば、身長160cm~170cmの人に絞り込みつつ、体重を降順に並び替える、というのができません。

```js
  let boysRef = db.collection("boys").where("height", ">=", 160).where("height", "<=", 170).orderBy("weight", "desc");
  let items = await boysRef.get(); // エラー
```
- こんなエラーです。`不等号を含むwhereフィルターはheightについてのものなので、最初のorderByのフィルターも、heightについて指定する必要があります`ということでした。

```
Uncaught (in promise) FirebaseError: Invalid query. You have a where filter with an inequality (<, <=, !=, not-in, >, or >=) on field 'height' and so you must also use 'height' as your first argument to Query.orderBy(), but your first orderBy() is on field 'weight' instead.
```
- ちなみに、2個目のorderByにweightを指定する↓のやり方だとエラーはでませんが、身長順で並び替えたあと、同順位のデータを体重順で並び替えるだけなので、期待する結果は得られません。

```js
  let boysRef = db.collection("boys").where("height", ">=", 160).where("height", "<=", 170).orderBy("height", "desc").orderBy("weight", "desc");
  let items = await boysRef.get();
```


# ページネーションが実現しづらい
- まずfirestoreを使ってのページングにはstartAfterを使います。上の例だと以下の通りです。

```js
  let boysRef = db.collection("boys").orderBy("height", "asc").limit(2);
  let items = await boysRef.get(); // itemsには一郎、二郎のデータ
  let last = items[items.length - 1];
  let nextItems = boysRef.startAfter(last.doc).get(); // 三郎、四郎のデータ
```
- 上記のやり方だと`もっと見る`形式の追加ローディングにはさくっと対応できますが、googleの検索結果ページにある様なページネーションには対応が困難です。
- 例えば、100件データがあるうちの51件目から表示したい場合、一発で51件目のデータを特定することが、startAfterでは不可能です。

# 参考リンク
https://firebase.google.com/docs/firestore/query-data/order-limit-data?hl=ja
AWS ECRでAccessDeniedExceptionが発生したときの解決法

## 概要

自作RailsアプリをECSにデプロイするために、ECRにログイン時に発生しました。


```bash
$ aws ecr get-login-password --region ap-northeast-1

An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:iam::125724222608:user/ecr_replication is not authorized to perform: ecr:GetAuthorizationToken on resource: *
```

## 環境

```bash
$ aws --version
aws-cli/2.1.26 Python/3.9.1 Darwin/20.2.0 source/x86_64 prompt/off
```

## 解決策(IAMを作成して、ECR用のポリシーをアタッチする)

[Amazon ECR エラーメッセージのトラブルシューティング](https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/common-errors.html)に詳細は記載されていますが、`AccessDeniedException` が発生した場合は下記のどちらかか原因です。

- ECRを使用するアクセス権限がユーザーに付与されていない
- アクセス権限が正しく設定されていない

そこで、「アクセス権限が正しく設定されていない」に対しては、適切なポリシー(下記)を作成し、ECRへのデプロイ用IAMロールにアタッチしました。

```bash
{
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "ecr:GetAuthorizationToken",
            "ecr:BatchCheckLayerAvailability",
            "ecr:GetDownloadUrlForLayer",
            "ecr:GetRepositoryPolicy",
            "ecr:DescribeRepositories",
            "ecr:ListImages",
            "ecr:DescribeImages",
            "ecr:BatchGetImage",
            "ecr:InitiateLayerUpload",
            "ecr:UploadLayerPart",
            "ecr:CompleteLayerUpload",
            "ecr:PutImage"
],
          "Resource": "*"
        }
] }
```

次に、「アクセス権限が正しく設定されていない」に対しては、ターミナル上で `aws configure` と入力し、作成したIAMの設定を入力しました。
作成後、`aws configure list` と入力し、IAMの情報が記載されていることを確認しました。

結果、無事ログインに成功し、ECRへのイメージのPushもすることができました🎉

**参考**

[Amazon ECR エラーメッセージのトラブルシューティング](https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/common-errors.html)
スクロールバーを上下に挿入

業務でスクロールバーを上下に挿入したので、記録に残していきたいと思います。

イメージとしてはこんな感じです。
![ev003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700700/00d40a19-82d0-18df-003a-a7f17fe8a45e.jpeg)
スクロールバー上下が連動して移動できるようになってます。

#実装

```html:index2.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <title>上下スクロールバー</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <div id="containar">
    <div class="scrollbar" id="scrollbar">
      <div class="inner"></div>
    </div>
    <div class="scrollbox" id="scrollbox">
      <div class="inner">
        <table id="data-table">
          
            <th>項目1</th>
            <th>項目2</th>
            <th>項目3</th>
            <th>項目4</th>
            <th>項目5</th>
            <th>項目6</th>
            <th>項目7</th>
            <th>項目8</th>
            <th>項目9</th>
            <th>項目10</th>
            <th>項目11</th>
            <th>項目12</th>
            <th>項目13</th>
            <th>項目14</th>
            <th>項目15</th>
            <th>項目16</th>
            <th>項目17</th>
            <th>項目18</th>
          
        </table>
      </div>
    </div>
  </div>
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
    integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E=" crossorigin="anonymous"></script>
  <script src="main.js"></script>
</body>

</html>
```
tableタグにthをセットします。
※thは「Table Header（見出し）」のことです。

```css:style.css
#containar {
    width: 500px;
    padding: 100px;
  }
  .scrollbar {
    width: 100%;
    overflow-x: scroll;
    overflow-y: hidden;
  }
  .scrollbar .inner {
    width: 2500px;
    height: 1px;
  }
  .scrollbox {
    width: 100%;
    margin-top: 5px;
    overflow-x: scroll;
    overflow-y: hidden;
  }
  .scrollbox .inner {
    width: 2500px;
    margin-bottom: 5px;
    background-color: #F9F8F6;
  }
  .scrollbox .txt {
    margin: 0;
    font-size: 16px;
    line-height: 1.5;
  }
```
レイアウト変更とスクロールバーをセットします。
この時点では行にデータが入っていなく、上下のスクロールバーが連動していないことがわかります。
では次

```javascript:main.js
//上下のスクロールバー連動
$(function () {
    //「対象要素.on( イベント名, 関数 )」
    //イベント名がscrollなので、画面がスクロールした時に発動
  $("#scrollbar, #scrollbox").on("scroll", function () {
    if ($(this).attr("id") === "scrollbar") {
        //scrollLeftでスクロール量を取得
      $("#scrollbox").scrollLeft($(this).scrollLeft());
    } else {
      $("#scrollbar").scrollLeft($(this).scrollLeft());
    }
  });
});

//行にデータを挿入
var tableEle = document.getElementById("data-table");

for (var i = 0; i < 5; i++) {
  // テーブルの行を 5行追加する
  var tr = document.createElement("tr");

  for (var j = 0; j < 18; j++) {
    // テーブルの列を 18行追加する
    var td = document.createElement("td");
    td.innerHTML = "データ" + (i + 1) + "-" + (j + 1);
    tr.appendChild(td);
  }
  tableEle.appendChild(tr);
}

```

このようにすることによって行にデータが入り、上下のスクロールバーが連動していることがわかります

##参考
[https://qiita.com/kuro-wassan/items/86b6a24787116797a5d0](https://qiita.com/kuro-wassan/items/86b6a24787116797a5d0)
JavaScript クッキーの読み・書き・削除(承認パネル)

クッキーの読み、書き、削除について学んだ。備忘録を残す。
##クッキーとは
* ブラウザ間でやりとりされる小さなデータ。ヴラウザとユーザー間でやりとりされ、主にログイン情報などを管理する。ECサイトやSNSなどで広く使用される。

##OSライブラリ「js-cookie」
* クッキーのデータを操作するのに利用するOpenSourceライブラリ。クッキー操作をするための補助プログラム。
HTMLファイルに読み込ませることでクッキーデータの操作ができるようになる。
##jsライブラリのメソッド

##クッキー保存のメソッド
`Cookies.set('変数名','値',{expire: 有効期間});`

* 上記のメソッドを使用すると、指定した変数に有効期間、値が保存される。
【技術書まとめ】『JavaScript Promiseの本』を読んだまとめ

## Chapter.1 - Promiseとは何か

- E言語で発見された
    - 並列/並行処理の言語デザインの一種
- コールバックでエラーを返して、`if (error) {}`するのとの違い
    - あくまでコーディングルール
        - Promise は`then`と`catch`しか使えない
            - 統一される
                - 非同期処理をうまくパターン化する


## 2. Chapter.2 - Promiseの書き方

- Promiseのショートカット
    - テストコードに使える
        - `Promise.resolve`
        - `Promise.reject` 
- `thenable`なオブジェクト
    - `.then`を持っている
        - Array like みたいなもの
    - `jQuery.ajax()`の返り値
        - `Promise.resolve`でpromiseオブジェクトにできる
- Promise#finally
    - 引数を受け取らない
        - どんな引数を返しても影響なし
    - isLoadingで使う
- thenは常に新しいpromiseオブジェクトを返す
- Promise.all
    - promiseをまとめる
        - 全て並列に実行される
- Promise.race
    - 最初にFulfilledになった時点でthenが呼ばれる
        - 他のpromiseはキャンセルされない


## 4. Chapter.4 - Advanced

- throw でなく reject する
    - throw が意図したものか例外なのかわからない


## Chapter.5 - Async Function

- Async Function
    - 必ず`Promise`インスタンスを返す
        - `Promise.resolve(返り値)`を返す
    - `await`が使える
        - 外の処理は止まらない
- `await`式
    - 右辺の`Promise`インスタンスが**Fullfilled**か**Rejected**になるまで待つ
- Async Functionと配列
    - `for`を使う
        - 順番が重要でなければ`Promise.all`を使う
    - `forEach`は使えない
        - `await`は`Async Function`の直下でしか使えないから
            - コールバックにするとどうか？
                - 外側の処理が先に進んでしまう
デコレーターを使おうとしたら怒られた

# 背景
vuex-module-decoratorsを使ってストアを宣言したら、
クラス名にて怒られた

```typescript
import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators';

@Module
export default class AuthStore extends VuexModule {
}
```

> デコレーターの実験的なサポートは将来のリリースで変更になる可能性がある機能です。'experimentalDecorators' オプションを設定してこの警告を削除します

# 対処
VSCodeの設定にてExperimental Decoratorsの設定を変更。

1. 基本設定を開く
2. 設定を開く
3. 検索窓にexperimentalと入力
4. `JS/TS › Implicit Project Config: Experimental Decorators`の設定にチェックを入れる

# 参考記事
https://ihatetomatoes.net/how-to-remove-experimentaldecorators-warning-in-vscode/
スキーマとはなにか

## スキーマとは
スキーマとは、「趣旨、要旨」とかいう意味らしい。
ほかにも、図式とか図解とかそのような意味でもあるっぽい。

これは結局どんなものかというと、``データベースの構造や仕様を定義``することに使われるものらしい。
【Unity　tips】　Cloth機能を使ってみよう



今回は、Cloth【クロス】機能の使い方を見ていきます。　

クロス機能は知ってますかね？　

オブジェクトを布のような動きにすることができる機能です。　

これを使えば　

キャラクターの髪の毛をゆらゆらしたり　

動物の尻尾をゆらゆらしたり　

スカートをひらひらひらひらしたりできるんです。　

あとは、オブジェクトを布で包んだりもできますね。




それでは、今回は試しにプレーンをゆらゆらしていきます。　

まずはプレーンを入れて

インスペクターにある　Meshcolliderの凸状にチェック

【ついていなければMeshcolliderを入れていきます】

そしてトリガーにも、チェックを入れます。　

そして　コンポーネントを追加から　

Clothを入れます。　

Clothを入れると、自動的にskinnedも入ります。


![bandicam 2021-02-27 20-01-55-383.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295760/6ba2fb54-a7b9-7ede-5f6e-73cdb9c975c6.png)


で次にですね。　

Clothの右下にある緑矢印のアイコンを選択します。　

そうすると、　シーンビューにクロスのセルフコリジョンというメニューが　

出てくるので、　そこで選択を選びます。　

そして、　囲みたい所をドラッグして選択していきます。　

そして囲んだら　すぐ下にある　

セルフコリジョンとインターコリジョンにチェックを入れます。　

この画像ですと、　プレーンの上側だけを囲んでいます。　

囲む所は、固定したい所になります。　

囲んだ所は青い点に変わります。

つまり、囲んでいない所がゆらゆらするということです。

![bandicam 2021-02-27 20-29-17-225.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295760/edc14250-dd57-cd04-83b3-10f8316685ee.png)




ではこれで再生してみましょう。　

この状態でプレーンを動かしてみると　

画像のように、　プレーンが　布のようにゆらゆらしていると思います。


![bandicam 2021-02-27 20-38-55-345.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295760/bd1bed19-7449-d211-8824-24892eccb3b6.png)




このようになっていれば成功です。　

※注意点としては、　１回囲んでしまうと、ポインターが消えてしまうので　

また設定をやり直す必要があるんですよね。



PS　

Unityの寺子屋ユニコーンもやってまーす。　

一部、Unity講座なども値下げしましたよ。
Valheim専用サーバーの立て方(Windows)

# 概要

* Valheim専用サーバーの立て方を書いてます。

# 条件

* Valheimを起動できるスペックのPC/OS(20210303時点)

最低:

```
64 ビットプロセッサとオペレーティングシステムが必要です
OS: Windows 7 or later
プロセッサー: 2.6 GHz Quad Core or similar
メモリー: 8 GB RAM
グラフィック: GeForce GTX 950 or Radeon HD 7970
DirectX: Version 11
ストレージ: 1 GB 利用可能
```
推奨:

```
64 ビットプロセッサとオペレーティングシステムが必要です
OS: Windows 7 or later
プロセッサー: i5 3GHz or Ryzen 5 3GHz
メモリー: 16 GB RAM
グラフィック: GeForce GTX 1060 or Radeon RX 580
DirectX: Version 11
ネットワーク: ブロードバンドインターネット接続
ストレージ: 1 GB 利用可能
```

# 専用サーバーを導入した場合の良いところ、悪いところ

## 良いところ

* 24時間いつでもログインすることが出来る。

## 悪いところ

* 専用のリソース（PC、電気代等）がかかる。
* インターネットへ公開する場合はセキュリティに注意する必要がある。

# 導入方法

* 「Valheim」を購入済みの場合、「Valheim Dedicated Server」という「ツール」がライブラリに追加されているためダウンロードします。

* ダウンロード後、起動ボタンを押すと専用サーバーが起動します。
    * ファイヤーウォールがある場合は「valheim_server.exe」に関するポートを開放しておいてください。
* 停止する場合は「CTRL+C」を押してください。

# 接続方法

* 「Valheim」クライアントを起動します。
* 「スタート」→「キャラクター選択」→「スタート」
* 「サーバー選択」→「IP参加」→専用サーバーのIPアドレスを入力→「接続」
    * デフォルトポートで専用サーバーを起動している場合はIPアドレスのみでログインできます。

# 起動時の設定及び起動方法

* 「Steamクライアント」→「ライブラリ」→「「Valheim Dedicated Server」」→「右クリック」→「ローカルファイルを閲覧」で専用サーバーインストール先フォルダを開きます。

## 設定方法

* 「start_headless_server.bat」の起動オプションを変更することにより設定変更が出来ます。
    * 設定可能項目については「Valheim Dedicated Server Manual.pdf」に記述されています。

オプション|詳細
---|---
-name “My server”|サーバーリストに表示される名前を設定します。
-port 2456|ポート番号を設定します。デフォルトは「2456-2457」です。
-world “Dedicated”|ワールド名を設定します。作成されていない場合は作成されます。
-password “Secret”|パスワードを設定します。5文字以上で設定してください。
-savedir [PATH]|保存先を設定します。デフォルトパス「“../%USERPROFILE%/AppData/LocalLow/」
-public 1|公開オプションを設定します。「1」サーバーリストに表示されます。「0」サーバーリストに表示されません。IPアドレス指定でのみログイン可能です。

## 起動及び停止方法

* 「start_headless_server.bat」を実行してください。
* 停止する場合は「CTRL+C」を押してください。

# Steam同一アカウントで専用サーバーへログインする方法

* 専用サーバーを起動したPCのSteamを終了しておくだけです。
* バッチから起動する場合、Steamを起動しておく必要はありません。

## ローカルゲームで遊んだゲームを専用サーバーで起動する方法

*　起動時の設定で「-world 」のワールド名をローカルゲームのワールド名に合わせます。
【gcloud】config削除方法

## ユースケース

不要なconfigの削除

## configの確認

```bash
gcloud config configurations list
```

## configの削除

```bash
gcloud config configurations delete [CONFIGURATION_NAME]
```

## 参考文献

- [gcloud config configurations  |  Cloud SDK のドキュメント  |  Google Cloud](https://cloud.google.com/sdk/gcloud/reference/config/configurations)
【gcloud】複数config設定

# ユースケース

`複数プロジェクト`、 `複数クラスタ` を利用する場合

## configの確認

```bash
gcloud config configurations list
```

## configの作成

```bash
gcloud config configurations create [CONFIGURATION_NAME]
```

## configの切り替え

```bash
gcloud config configurations activate [CONFIGURATION_NAME]
```

## 参考文献

- [gcloud config configurations  |  Cloud SDK のドキュメント  |  Google Cloud](https://cloud.google.com/sdk/gcloud/reference/config/configurations)
- [gcloud configで複数の設定を持って切り替える](https://qiita.com/sky0621/items/597d4de7ed9ba7e31f6d)
【ubuntu】日本語を入力の為にMozcをinstall


<h1>日本語の設定</h1>
```
sudo apt install -y ibus-mozc
sudo reboot
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/dfa28684-e9ab-399c-bba8-41c78c61b82d.png)



<h1>参考文献</h1>
https://www.hiroom2.com/2018/04/29/ubuntu-1804-ibus-mozc-ja/
【storyboard編：一旦頓挫】初心者がApp StoreにiOS自作アプリを公開する過程

#なぜ書くのか
つまずいたポイントを記録するため。
僕と同じように、初めてApp Storeに自作アプリを公開しようとしている人の参考にしてもらうため。

主に以下の記事を参考にさせていただいており、適宜参照します。
[【2020年度版】 iOSアプリをApp Storeに公開する手順を簡潔に解説](https://qiita.com/Labi/items/3b71b8f5ef065904c1de)

#つまずいたポイント

###プライバシーポリシー用のサイト作成
つまずいたのは、github Pagesに作成したはずのプライバシポリシーが表示されないという内容です。
表示されない原因は、プライバシーポリシーが書いてあるhtmlファイルの名前が「index.html」で無かったことでした。

プライバシーポリシーは、テンプレート作成サイト（[App Privacy Policy Generator](https://app-privacy-policy-generator.firebaseapp.com/)）で作成し、公開はgithub Pagesで行いました。
完成したプライバシーポリシーは以下のURLから見ることができます。
[プライバシーポリシー](https://atamakonkurii.github.io/J-and-T-language-learning/)

参考にした記事は以下の二つです。
[個人開発者がAppStore用にプライバシーポリシーを書く](https://qiita.com/Hiroki_Kawakami/items/94f012d20afdb692df20)
[iOSでプラポリが必須になったのでGitHub Pagesで対応した](https://qiita.com/mtfum/items/6d7882a1ca389dcc6e31)


###App Developer Programの登録に時間がかかるということ
iOSアプリをApp Storeに公開するためにはApp Developer Programの登録が必要ですが、登録料金(税別11800円)を支払ってからいくらか時間が必要です。登録と審査への提出をそのままやるつもりでしたが、できないようです。

約48時間後、登録完了のメールが届きました。

#iOSアプリ審査の指摘事項
審査請求後、これも約48時間後にレビュー結果が送られてきました。
３つ指摘事項がありました。

###Guideline 1.5 - Safety - Developer Information
(2021/2/22)サポートURLが不適切なようです。twitterのURLを提出したのですが、リジェクトされてしましました。以下の記事ではアプリのスクリーンショットと連絡先を明記すれば良いとのことですが。しかし、以下の記事では自分のブログを持っており、そこにサポートURL用のページを追加することで対処されていました。私は個人ブログを持ち合わせていないので、以下のツイートのURLで審査が通るか試してみます。

![スクリーンショット 2021-03-03 21.51.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010233/2b0314e4-77ac-916e-26ca-88c73f65aa18.png)


[【AppStore】Guideline 1.5でリジェクトされた時の対処法](https://ymgsapo.com/2020/11/22/guideline1-5/)

###Guideline 2.3.7 - Performance - Accurate Metadata
(2021/2/22)タイトルが不適切なようです。以下の記事に３つ以上のキーワードが入っているとリジェクトされやすいと書いてありましたので、減らしました。

訂正前
AtamaConcrete　台湾中国語、日本語勉強アプリ

訂正後
AtamaConcrete　日台言語学習アプリ

[【AppStore】アプリ名におけるキーワードについて](https://exgyaruo.com/appstoreconnect/appstore-guideline-2-3-7-performance-accurate-metadata-2)


###Guideline 4.2 - Design - Minimum Functionality

(2021/2/22)この記事を見たのですが、このリジェクトはやばいらしいです笑
[デベロッパーが最も怖れる最恐のリジェクト「4.2 Minimum Functionality」とは](https://kanasys.com/tech/669)

>これはなにか
一言で言うと「これはク○アプリですね」ということです。

自覚はありましたが、初心者には厳しい現実です。アプリをとりあえず出して改善を重ねていこうと思っていましたが、最初のリリースでもある程度のレベルは求められるということなんですね。
上の記事でもあるように、このリジェクトはレビュワーさんの主観も入っているそうなので、デザイン面も気をつけなければいけないと考えています。

#まとめ

アプリは作りさえすれば簡単にAppStoreに公開されると思っていましたが、そんなことはなかったです。
当たり前のことに気づけたことが今回の収穫かと思います。
今後はAppStoreへのアプリの公開を目標に頑張っていきたいです。
ゼロ秒思考　テーマ

最近ゼロ秒思考を行なっているが、テーマを決めるのに時間がかかってしまっているため
思いついたテーマをまとめていく。随時更新する予定。

## もやもや系
- もやもやしていることは
- どうやったらもやもやが取れるか
- もやもやが取れたらやりたいこと
- 最近太ってきているどうすれば痩せられるか
- 最近だらけているどうすれば規則正しい生活にできるか
- （イベント名等）の準備に何が必要か
- 言いたくても言えない理由って何だろう
- 昨日の会議でのもやもや
- 今日の会議何となく不安どんな理由

##やりたいこと系
- （1日、１ヶ月、半年、1年、3年、5年、10年）の自分があなたを見たときになんていうか
- （1日、１ヶ月、半年、1年、3年、5年、10年）しか生きられないとしたら何をするか
- 何をしている時が楽しいか
- 今行きたい場所はどこか
- 今欲しいものは何か
- 今食べたい・飲みたいものは何か
- 今誰と会いたいか
- どういう状態になっていると心地よいか

##悩み系
- どんな健康に関する悩みがあるか
- 自分の健康の悩みは何か
- 家族・知人の健康の悩みは何か
- どんな人間関係で困っているか
- （人と名前）と話すときなぜ辛いか
- どんなお金の悩みがあるか
- どうやったら安定した生活を送れるか
- お金の使い道

# 感謝系
- 何かありがとう
- 必要なものは
- 

オススメのテーマがあればコメントください。
Go Snippet: 最小限の JSON API サーバー

シンプルな JSON API サーバー。
コピペ用

## コード

```golang
package main

import (
	"encoding/json"
	"log"
	"net/http"
)

type Post struct {
	ID    int    `json:"id"`
	Title string `json:"title"`
	Body  string `json:"body"`
}

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Content-Type", "application/json")
		if err := json.NewEncoder(w).Encode(&Post{ID: 1, Title: "hello", Body: "world"}); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	})
	log.Fatalln(http.ListenAndServe(":8080", nil))
}
```

## 確認

ブラウザから `http://localhost:8080/` にアクセスする

```json
{
	id: 1,
	title: "hello",
	body: "world"
}
```

`curl -i http://localhost:8080/` でアクセスする

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 40

{"id":1,"title":"hello","body":"world"}
```
カード型リンクでカード内に複数のリンクがあるときにリンクハイライトを綺麗に設定する

リンクをカード型デザインしているとカード内にリンクが複数あることが多々ある。
パソコンでは`:hover`で適当に実装できるが、スマホだとリンクのハイライトが綺麗に実装されない。

ので、リンクハイライトが綺麗に実装できる方法を記載します🥳

## カード型のレイアウトをつくる
```html
<a href="記事に飛ぶ" class="card">
  <a href="記事に飛ぶ">
    <img src="thumbnail.png" src="thumbnail">
    <h1>Title</h1>
    <p>Paragraph</p>
  </a>
  <a href="ユーザー情報に飛ぶ">Name</a>
</a>
```

見た目はこんな感じで実装したい
![Card](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500709/dc4d56c8-da4b-38df-30c7-8ca9728625ab.png)

## リンクを機能させる
上記のコードだとユーザー情報へのリンクが機能しなくなるので、

```html
<div class="card">
  <a href="記事に飛ぶ">
    <img src="thumbnail.png" src="thumbnail">
    <h1>Title</h1>
    <p>Paragraph</p>
  </a>
  <a href="ユーザー情報に飛ぶ">Name</a>
</div>
```

こんな感じのコードにする。
これで、記事情報とユーザー情報のどちらのリンクも機能する。
しかし、一番最初に記載した通り、ハイライトが綺麗に実装されない。

ハイライトはこんな感じでつく
くそブサイク
![Highlight](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500709/608c229c-4e15-5beb-e1e9-163bec76c505.png)

## ハイライトを全体につける

全体につけるのであればカード全体をリンクとして扱う必要がある。

```html
<div class="card">
<a href="記事に飛ぶ" class="card-link"></a>
  <a href="記事に飛ぶ">
    <img src="thumbnail.png" src="thumbnail">
    <h1>Title</h1>
    <p>Paragraph</p>
  </a>
  <a href="ユーザー情報に飛ぶ">Name</a>
</div>
```
```css
a {
  -webkit-tap-highlight-color: transparent; /* ここで一旦ハイライトを全部なくす */
}
.card {
  position: relative;
}
.card-link {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: block;
  -webkit-tap-highlight-color: rgba(77, 200, 220, .24);
}
```

これでカード全体にリンクのハイライトがかかるようになった

## z-indexでリンクのz位置を調整する
上記のままだと結局記事ページにしか飛ぶことができないので、z位置を調整してうまくリンクが配置されるようにする

わかりやすくクラス名をつけます

```html
<div class="card">
<a href="記事に飛ぶ" class="card-link"></a>
  <a href="記事に飛ぶ" class="article-link">
    <img src="thumbnail.png" src="thumbnail">
    <h1>Title</h1>
    <p>Paragraph</p>
  </a>
  <a href="ユーザー情報に飛ぶ" class="user-link">Name</a>
</div>
```
```css
a {
  -webkit-tap-highlight-color: transparent; /* ここで一旦ハイライトを全部なくす */
}
.card {
  position: relative;
}
.card-link {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: block;
  z-index: 2;
  -webkit-tap-highlight-color: rgba(77, 200, 220, .24); /* ここだけハイライトをつける */
}
.article-link {
  pointer-events: none;
  z-index: 3;
}
.user-link {
  z-index: 4;
}
```

図にするとこんな感じ
![z-index](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500709/32ca3be1-039c-58e0-78ef-bfcba83d9c29.jpeg)

`article-link`をタップすると`pointer-events: none;`だから、下のレイヤーにある`card-link`がタップされたことになり、記事に飛ぶ
`user-link`をタップすると一番上のレイヤーにあるから、そのままユーザー情報へ飛ぶ

ハイライトは`card-link`だけにつけてるから、`user-link`をタップしても変にハイライトされない。

`article-link`は`div`でええやんって思うかもですが、`pointer-events: none;`が正しく動作しない場合などの保険に`a`にしています。
今はそう思ってるだけで多分そのうち設計方法は変えると思うのでこれが正ではないです。

あくまで、レイヤー構造を変更して、スマホのリンクのハイライトがうまく活用できる方法のひとつとして捉えてください。
AWS Data Migration Serviceでは同一構成のDBを複製できない

# AWS Data Migration Serviceとは
データベースを短期間で安全に移行できるAWSのサービスで、移行中でもソースデータベースは完全に利用可能な状態に保たれ、データベースを利用するアプリケーションのダウンタイムを最小限に抑えられるのが特長。一般に普及している商用またはオープンソースのデータベース間の移行が可能で、Microsoft SQL から Amazon Aurora といった異なるデータベースプラットフォーム間の移行もサポートしている。さらにAmazon Redshift と Amazon S3 にデータをストリーミングすることで、データベースをペタバイト規模のデータウェアハウスに統合することもできる。
レプリケーション（複製）元となるDBやスキーマ、テーブルを「ソース」、レプリケーション先のことをターゲットと呼ぶ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/9939f899-51c6-c3d0-0d5b-2aa57ce5279e.png)


# AWS DMSではできないこと
大規模な移行プロジェクトでも使用可能だが、比較的日常のユースケースだと、既存のテスト環境で再現が困難かつ複雑なバグの調査等の為に本番スキーマを同一構成で複製したいというのがある。
しかし実際使ってみると、原理はともかく下記の制約があり使い勝手がいまいちという感が否めなかったりする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/7919833a-3d17-eb8e-cf4d-cd63e363f2da.png)
1. DMSで作成されるオブジェクトはテーブルと主キー等の一部の制約のみ
2. **インデックス**やプロシージャ、ビューは（レプリケーション後に）ターゲット側で**手動で反映する必要**がある
3. [DR(ディザスタリカバリ)](https://www.idcf.jp/words/dr.html)のような同一構成を維持する必要がある場合、ソース、ターゲット両方のDBにオブジェクトを作成する必要がある

特に手動とはいえインデックスを作成するのに地味に手間と時間がかかる為、自動化して欲しかったところ。

# その他惜しい点
移行タスクというのは、基本的に一時的なものでサービスのように常時行う必要はない。
一方でレプリケーションインスタンスは起動中ずっと料金が発生してしまう点に注意して欲しい。
タスクの実行中のみ課金される親切設計なら尚良かったが流石に求め過ぎか。

# 参考
[AWS Database Migration Service](https://aws.amazon.com/jp/dms/)
[AWS Database Migration Service のベストプラクティス](https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/CHAP_BestPractices.html)
[【AWS Black Belt Online Seminar】AWS Database Migration Service](https://www.youtube.com/watch?v=Od83ySfrzGc)