商売力開発ブログ

非エンジニアがWebサービスの開発、運営によって商売力をつける記録、その他の雑記

「売れるもマーケ 当たるもマーケ マーケティング22の法則」から学ぶ①

今回はマーケティング本の名著に上げられる「売れるもマーケ 当たるもマーケ マーケティング22の法則」を読んでの我々なりの解釈を紹介します。 

マーケティングの教科書

「売れるもマーケ 当たるもマーケ マーケティング22の法則」は1994年に発売されてますから20年以上前に書かれたもので、マーケティングの教科書として紹介されることもある本です。実際、「星野リゾートの教科書」で教科書として紹介されていて、その活用方法が書かれていました。

売れるもマーケ 当たるもマーケ―マーケティング22の法則

売れるもマーケ 当たるもマーケ―マーケティング22の法則

  • 作者: アルライズ,ジャックトラウト,Al Ries,Jack Trout,新井喜美夫
  • 出版社/メーカー: 東急エージェンシー出版部
  • 発売日: 1994/01/01
  • メディア: 単行本
  • 購入: 17人 クリック: 250回
  • この商品を含むブログ (61件) を見る
 

非常に読みやすくなっていて、どんどん読み進めることが可能です。色々な事例を紹介しているところも良いですが、20年以上前のアメリカでの事例なので企業名ではピンとこないところもあります。記載されている法則と反することを実際に企業が行っていて、それが原因で失敗していると強調します。最後に「本書を終えるにあたっての警告」として、これらの法則を読者の企業に適用しようとする場合の危険について警告しています。これまでのやり方を全否定されると感じてしまう勢力から、疎まれるだろうと。

この手の教科書は書かれている内容を知識として頭に入れるだけでは勿体ない。自分だったらどうするかなど自分事として考えたり、法則と書かれていることが本当かを実際の世界で考えてみたり、示唆に富むセンテンスも多いのでそこから自分で問いを立ててなぜなぜと考えてみたりと、思考をどんどん広げていくことで大きな収穫を得られると思います。本書では「○○の法則」となっていますが、この手の法則・ルール系の本はその内容が正しいと仮定とし、法則に沿っていないように見える現実の事象を考えて何故法則に沿っていないかを考えてみたり、法則を疑いどのような条件でその法則は破れるか、逆にどのような条件で法則は正しいかを考えるのが思考を深めるパターンです。
そこで我々の場合、どんなことを考えたかを何回かに別けて紹介していきたいと思います。

中心となる法則

本書では全部で22章あり、各章で1つの法則が説明される構成となっていますが、各法則は完全に独立しているわけではなく相互に関連している部分もあります。我々なりに解釈すると、これらの法則の中で中心となっていると考えられる法則は以下の2つです。

  • 第3章:心の法則
  • 第4章:知覚の法則

この2つの法則についてまずは考えてみたいと思います。

心の法則は知覚の法則に続く法則である。
(第3章:心の法則 P35)

とありますので、まずは知覚の法則を見てみましょう。

本書の指摘する知覚とその法則とは

知覚の法則の副題として「マーケティングとは商品の戦いではなく、知覚の戦いである。」として提示しており何度も強調されています。そして著者の言いたいことはこの言葉に集約されています。

客観的な現実というのは存在しないし、事実というものは存在しない。ベストの商品などありっこないのだ。マーケティングの世界に存在するのは、ただ、顧客や見込客の心の中にある知覚だけである。知覚こそ現実であり、その他のものはすべて幻である。
(第4章:知覚の法則 P38)

この「知覚」とは何でしょうか。我々は顧客が認知することで顧客の心の中で築かれる事物やその認識といった解釈をしました。これは感情的なものや感覚的なものも含まれます。そしてこの「知覚」はそれぞれの認識・心の中にあるので、事実というものは存在しないと指摘しています。なのに多くの企業は事実の確認に莫大な予算を割いていると。
また「商品の戦いではない」というのは、優れた商品が必ず勝つというわけではないという警告です。

マーケティング計画の主役は商品であり、商品の持つ価値によって勝敗が左右されるという誤った前提に基づいている。
(第4章:知覚の法則 P40)

これは必ずしも優れた商品が勝つわけではないのに、多くのマーケティング計画の内容が「我々の商品は優れています!」というものになってしまっているという指摘です。

心の中で知覚がどのように形成されるかを研究し、マーケティング計画の焦点をこうした知覚に合わせることによってのみ、あなたは基本的に間違っているご自分のマーケティング上の発想を正すことができる。
(第4章:知覚の法則 P40)

本書では知覚することで顧客の心の中はどのようになっているか、どのような状態にすれば勝つことができるかを色々な法則で説明しています。

知覚から心の法則へ

心の法則の章では、「顧客の心の中に入り込むこと」が重要であるとされます。これはどいうことか。顧客に知覚・認知された状態だけではその製品について忘れ去られることもあります。知覚・認知されたときに、顧客の心の中に入り込み継続して存在し続けることが重要であるということです。「心の法則は知覚の法則に続く法則である。」とはそのような意味だと解釈できます。

知覚の法則と心の法則はマーケティングの購買行動モデルとして説明に用いられる、AIDMAやAISASのAction(購入)の前までの部分に対応していると解釈できます。

法則の描く全体像のイメージ

本書では22の法則を説明されていますが、上記の2つの法則を中心にして考えて解釈したイメージは以下のようなものになります。

顧客は自社や外部から絶えず多くの情報にさらされています。一部の情報は無視され、一部の情報は知覚・認知されます。自分にとって興味のある情報は知覚・認知されやすいでしょう。その中で心・マインドの模様・あり様が形成されていきます。
この中で、自社のこと知覚・認知してもらう活動を「マーケティング活動」とし、その結果、心・マインドの模様(「心模様」)に及ぼす影響を「マーケティング成果」と定義しました。本書の各法則の説明では色々な要素を含んでいますが、今回の2法則以外をこの定義を軸にして次回以降説明していきたいと思います。

このイメージ図はある一時点を表したものです。時間経過と共に心・マインドの模様は変化していきます。これは自社だけでなく他社や外部環境も大きく影響するでしょう。また「マーケティング成果」はプラス面だけではなくマイナス面も含まれます。

法則で書かれたことのその他考察

あるマインドがすでに出来上がっている場合は、それが変わることはまずありえない。マーケティングにおいて最も無駄な行為は、人の心の中を変えようとする試みである。
(第3章:心の法則 P35)

マインドは短期的には変えることはできないものである。特にマイナスのイメージを自らのマーケティング活動で変えることはできない。よって既存のイメージを変えるように努力するのではなく、新しいイメージを与えることで結果としてイメージが変わるようにする方がマーケティング活動としては良い。
「ブラック企業」というイメージがついた和民が、和民ブランドから別ブランドにすることで2018年の上期は4期ぶりの黒字となっている。

あなたが他人に強い印象を与えたい場合には、その人の心の中に徐々に入り込み、ゆっくりと時間をかけて醸成しようとしたのではだめだ。心というのはそんなふうに動かない。心の中には一気に入り込まなければならない。
(第3章:心の法則 P35)

既存のカテゴリーや類似のカテゴリーに新しい製品を出す場合、一線を画したイメージを顧客に一気に知覚してもらう必要がある。実際、そのようにものが自社の新製品の中にあるでしょうか、これは自社の中ではどの段階で検討する内容でしょうか。
イーロンマスクのスペースX社は2018年2月に全世界に見れる状態で新型ロケットの発射を中継した。2個のブースターが自動で戻ってくる映像は圧巻で、新しい宇宙産業時代の到来を告げるのに十分すぎるほどのインパクトがあった。
2017年末に楽天は携帯電話事業に参入を表明した。まだ現時点では周波数帯割当に申請した段階ではあるが、国内の大手3社とどのような違いを示すでしょうか。

たいていの人が、自分は他の人よりも認識力が優れていると考えている。
(第4章:知覚の法則 P39)

特に自身の体験に基づいた認識は、より正しい・優れいてるという補正が入り込みやすいので省みる必要がある。この傾向を顧客に向けて考えてみると、製品を体験してもらい良いイメージを植え付けることができれば、強力なものとなる。
更に自分の思いついた意見・アイデアは特別だ、特殊だと考えてしまう傾向がある。たいていの場合、新しくも面白くもなく、ありふれたもので特別ではない。ただその意見・アイデア自体ではなく、その意見・アイデアの何について新しい・面白いと思ったのかは考察する余地がある。

ある商品に関して、自分自身の知覚ではなく、だれか他の人の知覚をもとに購入決定をするのである。
(第4章:知覚の法則 P45)

BtoCの領域では口コミサイトや比較サイトを利用する顧客が普通になっているカテゴリーが多くなっている。逆にそのようなサイトを利用しないカテゴリーはどのようなものか。またBtoBの領域ではどうか。見込顧客が製品を利用・使用している顧客を紹介して欲しいということがあります。それはどのようなカテゴリーの製品でしょうか。また見込顧客はなぜ紹介を要求するのでしょうか。

マーケティングとは商品の戦いではない。知覚の戦いなのである。
(第4章:知覚の法則 P47)

これは製品の性能・品質はどうでも良いと言っているわけではありません。性能・品質ばかりに着目し、それを製品の価値だと考えるのが間違っている。顧客の心の中で価値があると認識されなければ性能・品質が良くても勝てないということです。
新製品を作るときに「(自社:提供する側が考えている)価値の高い製品を作る」以外の戦略がない場合、それは失敗する可能性が大きくなります。また逆に考えると、性能・品質が多少低い部分がある場合でも、マーケティング戦略が有効であれば勝つチャンスがあるとも言えます。この場合、その時点の製品の完成度にこだわらずにチャレンジする価値があるかもしれません。

まとめ

今回は「売れるもマーケ 当たるもマーケ マーケティング22の法則」の全体像の紹介でした。

以上

【関連するリンク】

www.prj-alpha.biz

www.prj-alpha.biz

www.prj-alpha.biz

CSSのoverflowの使い方 overflow-x、overflow-yを両方指定する場合は注意が必要

今回はCSSのoverflowプロパティとoverflow-x、overflow-yについて確認します。
今回は環境により表示のされ方が一部違う可能性があります。Windows7/10でChrome、FireFoxでの表示のされ方について記載しています。

CSSのoverflowプロパティの概要

ovreflowプロパティは、領域内に収まらない内容をどのように処理するかを指定するものとなります。このプロパティの取る値は以下の4つがあります。

説明
visible はみ出して表示する。初期値となります。
hidden はみ出した部分を表示しない。
scroll スクロールして表示する。
auto ブラウザに依存します。一般的にスクロールして表示する。

各値毎の表示のされ方を確認します。overflow以外は以下の設定のdiv要素に対して、同じ文言を設定しています。

.sampleBox {
  width:250px;
  height:100px;
  background-color:gold;
  padding:10px;
  margin-bottom:35px;
  box-sizing:border-box;
}

「visible」の場合

縦方向に、はみ出して表示されます。

overflow : 指定なし=visible
指定の領域内に収まらない内容の場合、その収まらない部分がどのようにして表示されるかを確認する。

「hidden」の場合

表示されません。

「scroll」の場合

縦方向にスクロールして表示されます。横方向のスクロールバーは非活性の状態で表示されます。
ちなみにスクロールバーが表示される場合、その分だけ文言などが表示される領域が狭くなることになります。繊細なレイアウトの場合、スクロールバーが表示されることで表示幅が影響しレイアウトが崩れることがあるのでご注意下さい。

overflow : scroll
指定の領域内に収まらない内容の場合、その収まらない部分がどのようにして表示されるかを確認する。

「auto」の場合

ブラウザに依存します。現在のブラウザでは一般的に縦方向にスクロールして表示されます。横方向のスクロールバーは表示されません。

overflow : auto
指定の領域内に収まらない内容の場合、その収まらない部分がどのようにして表示されるかを確認する。

はみ出し方による違い

ここまでの説明でoverflowの設定はイメージはできたと思いますが、実ははみ出し方の違いにより一部見え方が変わってきます。縦方向と横方向にそれぞれはみ出るようなdiv要素を配置した場合どうなるかを確認します。まずは下方向と右方向にはみ出る要素の場合です。

「visible」の場合

表示されます。

overflow : visible

「hidden」の場合

表示されません。

「scroll」の場合

縦方向、横方向にスクロールして表示されます。

overflow : scroll

「auto」の場合

ブラウザ依存ですが「scroll」と同じようにスクロールして表示されるのが多いと思います。

overflow : auto

続いては上方向と左方向にはみ出る要素の場合です。

「visible」の場合

表示されます。

overflow : visible

「hidden」の場合

表示されません。

「scroll」の場合

縦方向、横方向にスクロールバーは表示されますが、非活性状態でスクロールはできず表示されません。

overflow : scroll

「auto」の場合

ブラウザ依存ですが「hidden」と同じように表示されないのが多いと思います。

overflow : auto

「scroll」については、はみ出した方向が右方向または下方向の場合スクロールして表示することができますが、はみ出した方向が左方向または下方向の場合スクロールして表示することができないことがわかります。

overflow-x、overflow-yを両方指定する場合は要注意

overflowは縦方向と横方向の共通に設定されますが、overflow-x、overflow-yによりそれぞれ別に設定することができます。overflow-xが横方向、overflow-yが縦方向の設定です。設定できる値はoverflowプロパティと同じです。
ここまで書くと、overflowと同じ機能と思いますが、設定の組み合わせにより想定外のことになりますので説明したいと思います。overflow-x、overflow-yが両方とも同じ値のときは、overflowでその値にしたときと同じ状態になりますので、ここでは特に示しません。
使用する状態は以下の2種類になります。
下方向にはみ出す状態

overflow : visible

右方向にはみ出す状態

overflow : visible

下方向にはみ出す場合

縦方向はoverflow-yの設定が関係するように思えます。overflow-x、overflow-yの組合せ別の設定の見え方は以下のようになります。

overflow-x : visible
overflow-y : hidden
overflow-x : scroll
overflow-y : hidden
overflow-x : visible
overflow-y : scroll
overflow-x : hidden
overflow-y : scroll

ここまでは想定した通りです。overflow-yに「scroll」または「hidden」とした場合、その設定が有効です。
以下の場合、注意が必要です。

overflow-x : hidden
overflow-y : visible
overflow-x : scroll
overflow-y : visible

overflow-yに「visible」を設定しているのに、はみ出して表示されません。overflow-yに「visible」を設定していて、overflow-xに「hidden」または「scroll」している状態で下方向にはみ出した要素があると、縦方向にスクロールされて表示されるようになっています。縦方向の表示が、横方向の設定であるoverflow-xの値によって表示が変わってきます。

右方向にはみ出す場合

右方向はoverflow-xの設定が関係するように思えます。overflow-x、overflow-yの組合せ別の設定の見え方は以下のようになります。

overflow-x : hidden
overflow-y : visible
overflow-x : hidden
overflow-y : scroll
overflow-x : scroll
overflow-y : visible
overflow-x : scroll
overflow-y : hidden

ここまでは想定した通りです。overflow-xに「scroll」または「hidden」とした場合、その設定が有効です。
以下の場合、注意が必要です。

overflow-x : visible
overflow-y : hidden
overflow-x : visible
overflow-y : scroll

overflow-xに「visible」を設定しているのに、はみ出して表示されません。overflow-xに「visible」を設定していて、overflow-yに「hidden」または「scroll」している状態で右方向にはみ出した要素があると、横方向にスクロールされて表示されるようになっています。横方向の表示が、縦方向の設定であるoverflow-yの値によって表示が変わってきます。

まとめ

今回はCSSのoverflow、overflow-x、overflow-yについて確認しました。
特にoverflow-x、overflow-yについては、「visible」と設定していても想定通りに表示されないことがあるので注意が必要です。我々の場合、この特性を知らずに特定条件で「visible」にしてもうまくいかずにはまりました。

以上

Laravelのマイグレーション機能の活用③ カラム定義の管理を楽にする方法

今回はPHPフレームワークの一つのLaravelの中から、データベースのマイグレーションの機能の利用に当たって、我々の活用方法を紹介します。
今回利用するDBはMySQLですが、他のDBでもほぼ同様に対応できます。
またマイグレーションに関連する内容は以下を参照して下さい。

Laravelのデータベースのマイグレーション機能 順番を強引に入れ替えることも可能 - 商売力開発ブログ
Laravelのマイグレーション機能の活用① メンバ変数を追加した上でテーブルのコメント追加も簡単に設定する方法 - 商売力開発ブログ
Laravelのマイグレーション機能の活用② 1つのファイルで複数のテーブル管理も可能 - 商売力開発ブログ

テーブルの物理設計のときにカラム定義は確定できてるか?

テーブルを物理設計する際には、テーブル名やカラム名とその属性を定義しなければなりません。当たり前ですね。ただこの定義って皆さん最初から確定できてるんでしょうか。
名前に関しては命名規約があれば、それに従って決まるものとして、今回問題として考えるのはカラムの属性です。特に新規のサービス開発しているときなどは、途中でカラムの属性を変更することがあります。このカラムの属性の管理を簡単にできないかLaravelのマイグレレーションで考えてみたいと思います。まずは以下のマイグレーションファイルを見てましょう。

class CreateSamplesTable extends Migration
{
    public $tbl_name='samples';//テーブル名のプロパティ追加
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create($this->tbl_name, function (Blueprint $table) {
            $table->increments('id');
            $table->string('name',255);
            $table->string('group_cd',5)->nullable();
            $table->smallInteger('amount');
            $table->double('rate', 5, 2);
        });
        // add comments
        DB::statement("ALTER TABLE ".DB::getTablePrefix().$this->tbl_name." COMMENT 'サンプルテーブル'");
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists($this->tbl_name);
    }
}

このテーブルでは5つのカラムが定義されています。ここで各カラムの定義の変更が必要になった場合、通常Laravelではカラム変更用のマイグレーションファイルを作成して対応することになります。
新規サービス開発のときなど何度も変更がされるような開発状況の場合、ファイルが多くなっていって結構面倒です。また同じカラムを持つ他のテーブルについてもマイグレーションファイルを作成することになりますので、ファイルは更に多くなります。一つの変更用のマイグレーションファイルで複数のテーブルに対応することも可能ではあります。ただ途中で新たに追加されたテーブルが出てきて、その後にカラムの変更する際には対象から外れてしまったりと、色々と事故の要因になります。このように初期開発時などテーブルの物理設計がどんどん変更されても、あまり面倒にならないように対応方法を考えてみたいと思います。
※サービスが開始している場合は標準の変更用のマイグレーションファイルを作成しての対応を推奨します。

どのように対応していくか

まず我々が最初に行っていたのはテーブルの定義が変更となる度に、そのテーブルを持つマイグレーションファイルをロールバックして、修正し再度マイグレーションする方法です。以前の内容でも触れましたが、以下のSQLで取得できるbatchの値を変更することでロールバックの対象にする方法です。

Select * From migrations
Order By batch desc,id;

batchの値を最大値にupdateすることで、マイグレーションの順番を強引に入れ替えて強制的にロールバックの対象となります。例えばSQLで取得した結果が以下の状態だっとします。

id migration batch
1 2018_01_01_000000_create_users_table 1
2 2018_01_01_000000_create_password_resets_table 1
3 2018_01_02_000000_create_samples_table 1
4 2018_01_03_000000_create_others_table 1

id:3の「2017_12_31_000000_create_samples_table」が変更対象のテーブルのとき、以下のようにbatchの値を更新します。

id migration batch
1 2018_01_01_000000_create_users_table 1
2 2018_01_01_000000_create_password_resets_table 1
3 2018_01_02_000000_create_samples_table 2
4 2018_01_03_000000_create_others_table 1

この状態でロールバックした後のSQLでの取得結果は以下のようになります。

id migration batch
1 2018_01_01_000000_create_users_table 1
2 2018_01_01_000000_create_password_resets_table 1
4 2018_01_03_000000_create_others_table 1

マイグレーションファイルに必要な修正を行います。ファイル名称は変更していません。その後、マイグレーションを実行するとSQLでの取得結果は以下のようになります。

id migration batch
5 2018_01_02_000000_create_samples_table 2
1 2018_01_01_000000_create_users_table 1
2 2018_01_01_000000_create_password_resets_table 1
4 2018_01_03_000000_create_others_table 1

この対応で特定のテーブルだけを再作成し、列定義の変更する度にマイグレーションファイルが増加させずに済ませることができます。
この方法の大きな問題点は複数環境がある場合です。(大抵の場合、当てはまりそうですが・・・)
強引にロールバックの対象を変更する作業を行っていますが、他の環境にこの修正後のマイグレーションを適用するには同じ作業が必要となってしまいます。この辺りを運用方法や回避策についてはまた別のエントリーで書きたいと思います。

カラム定義の共通化

ここからはカラム定義の管理の仕方を考えます。以下のupメソッドがある2つのテーブルがあるとします。
1つ目のテーブルは上で出てきたサンプルテーブルです。

    public $tbl_name='samples';//テーブル名のプロパティ追加
    public function up()
    {
        Schema::create($this->tbl_name, function (Blueprint $table) {
            $table->increments('id');
            $table->string('name',255);
            $table->string('group_cd',5)->nullable();
            $table->smallInteger('amount');
            $table->double('rate', 5, 2);
        });
        // add comments
        DB::statement("ALTER TABLE ".DB::getTablePrefix().$this->tbl_name." COMMENT 'サンプルテーブル'");
    }

2つ目のテーブルはグループテーブルです。1つ目のサンプルテーブルの「group_cd」にはこのグループテーブルに存在する「group_cd」が登録されるものとします。

    public $tbl_name='groups';//テーブル名のプロパティ追加
    public function up()
    {
        Schema::create($this->tbl_name, function (Blueprint $table) {
            $table->increments('id');
            $table->string('group_cd',5);
            $table->string('name',255);
        });
        // add comments
        DB::statement("ALTER TABLE ".DB::getTablePrefix().$this->tbl_name." COMMENT 'グループテーブル'");
    }

ここで「group_cd」は5桁の文字列型(MySQLではVARCHARで作成されます)となっています。この「group_cd」の桁数や型を変更することになった場合、これら2つのマイグレーションファイルを変更する必要が出てきます。このカラムがもっと多くのテーブルに使用されている場合、変更するだけでも結構な作業量になるのでどうにかして、効率化したいと思います。
といってもやることは簡単で、カラムの定義を関数で行ってしまおうというものです。

$table->string('group_cd',5);

としている部分を、例えば

columnDef('group_cd');

というようにカラム名を渡すと共通の定義ができるようにするイメージです。我々の場合、Laravelのファサード(仮にMigrationFuncとします)を作成しています。またBlueprintオブジェクトの$tableにカラムの定義をすることになるので$tableを渡す必要があります。こんな感じです。

MigrationFunc::columnDef($table,'group_cd');

このMigrationFuncファサードのメソッドによって、「$table->string('group_cd',5);」が実行されるように実装しています。ただ2つのupメソッドの設定を見れば分かる通り、テーブルによってはnullableにできる必要があります。MigrationFuncファサードのメソッドの引数の定義は以下のようになります。(実装部分については省略します。)

public function columnDef(Blueprint $table,$column_name,$nullable_flg=false){}

カラムの共通定義は連想配列などで以下のような感じで、MigrationFuncファサード内に設定しておきます。

$column_def = [
    'id' => ['type'=>'increments','comment'=>'ID'],
    'name' => ['type'=>'string','length'=>255,'comment'=>'名前'],
    'group_cd' => ['type'=>'string','length'=>5,'comment'=>'グループCD'],
];

渡ってきた$colNameから、カラムの共通定義の設定を$tableに行い、必要に応じて追加される設定(この場合はnullable)を行うようにします。このメソッドをマイグレーションファイルに設定します。
1つ目のサンプルテーブル

    public $tbl_name='samples';//テーブル名のプロパティ追加
    public function up()
    {
        Schema::create($this->tbl_name, function (Blueprint $table) {
            MigrationFunc::columnDef($table,'id');
            MigrationFunc::columnDef($table,'name');
            MigrationFunc::columnDef($table,'group_cd',true);
            $table->smallInteger('amount');
            $table->double('rate', 5, 2);
        });
        // add comments
        DB::statement("ALTER TABLE ".DB::getTablePrefix().$this->tbl_name." COMMENT 'サンプルテーブル'");
    }

2つ目のグループテーブル

    public $tbl_name='groups';//テーブル名のプロパティ追加
    public function up()
    {
        Schema::create($this->tbl_name, function (Blueprint $table) {
            MigrationFunc::columnDef($table,'id');
            MigrationFunc::columnDef($table,'group_cd');
            MigrationFunc::columnDef($table,'name');
        });
        // add comments
        DB::statement("ALTER TABLE ".DB::getTablePrefix().$this->tbl_name." COMMENT 'グループテーブル'");
    }

このようにしておくことで特定のカラムで変更があった場合、カラムの共通定義の設定を変更し、対象となるマイグレーションファイルをロールバックしてマイグレーションをすることで変更が反映されます。このときマイグレーションファイル自体には何の修正もする必要がありません。共通定義から同じ設定が対象のカラムにされることになります。サンプルテーブルでは一部のカラムの定義は$tableのままになっています。複数のテーブルで使用しないカラムは通常の設定で行っても良いかもしれません。
この方法の問題点はあるカラムの変更がある場合、そのカラムを使用しているマイグレーションファイルを洗い出して、ロールバックできるようにする作業が必要になることです。こちらを参考にして、カラム名を指定してSQLを流せば、使用しているテーブルを確認することはできます。

Select * From information_schema.columns I1
Where I1.table_schema = 'DB_NAME'
And I1.column_name='COLUMN_NAME';

ただし、 MigrationFunc::columnDefではなく標準の設定方法で定義したカラムも同じカラム名であれば取得されることになりますので注意して下さい。MySQLの場合、カラムに対してコメントの設定が可能です。 我々の場合、MigrationFunc::columnDefで設定したカラムは特定のコメントが付くようにして、標準の設定方法のカラムと区別するようにしてます。

まとめ

今回はLaravelのマイグレーションの我々の活用方法のうちカラムの管理方法を紹介しました。
新規サービスの開発段階では一部は使える方法ではないかと思いますので、参考にしてみて下さい。

以上

【関連するリンク】 www.prj-alpha.biz www.prj-alpha.biz www.prj-alpha.biz

刻々と時は流れて10年・・・刻刻

今回の内容は、一部あいまいな記憶を元に記載しています。

モーニング2の創刊

今から約12年前、2006年にモーニング2が創刊されました。Wikipediaを見ると2006/08/10創刊となってます。創刊号と2号は押入れのどこかにあるはず・・・
この雑誌はモーニングの増刊扱いとして始まってます。どーも今も増刊という扱いは変わっていないようです。手元ですぐ見つかった黒田硫黄のアップルシード連載開始号を見ると、裏表紙の部分に「モーニング9月2日号増刊」となっています。(ちなみに平成26年なので2014年ですね・・・)
増刊扱いで始まっているというのが、どういう事かというとモーニング2はモーニング編集部が担当しているということです。モーニング2が創刊されたときの編集長は当時のモーニング編集部の副編集長だったと思います。なのでモーニングの新人賞であるちばてつや賞、MANGA OPENの受賞作品が掲載されたり、そこから連載したりしていました。

創刊当時の看板作家はモーニング本誌で不思議な少年を不定期連載していた山下和美や当時メジャー雑誌にも進出し始めてたオノナツメです。この当時の雑誌の特徴の一つが作品のページ数が毎号決まっていないということ。通常の漫画雑誌の場合、作品ごとに16ページとか24、32ページとか決まっているんすが、一部の作品については制約がないことを編集後記とかで謳っていたような記憶があります。確かこれは不思議な少年がモーニング本誌に載せるにはページ数が多くて合わない話が結構あって、いっそページ数を作家に好きなようにして載せられる雑誌にしてしまおうという経緯だった気がします。

刻刻

モーニング2も創刊からしばらく後に刻刻が連載開始しました。作者は堀尾省太で、これが初連載作品です。Wikipediaを見ると2008年からの連載でモーニング2は月刊化に変わった時期です。連載当初から一部の間で面白い漫画があるって感じで評判になってました。

この作品、初連載だというのにストーリーの進み方が長期連載を前提にしているような作り。「止界」という時が止まった世界を舞台にしていくのですが、キャラクターも世界観も割と話数をかけている。これ連載前から相当担当編集者と打ち合わせを重ねて、構成を考えたんじゃないかと思います。絵は特別上手いわけじゃないですが、完成度が高いので見やすいです。連載後半でもあまり絵は変わっていないみたいなので、絵の進化はあまりない作家かもしれません。
この作品の単行本の発売日を見てみると、1巻と2巻が2009/08/21の同時発売です。これ1巻が発売できる量の話数が進んでも、単行本化してもらえなかったってことですね。新人で実績のない漫画家だと、中々単行本化してもらえないことがあるんです。かなり面白いと評判があっても厳しいですね。最終的には8巻まで出ています。

モーニング2がコンビニに置いてあったときは、立ち読みで追っていたのですがコンビニに置かれなくなってからは追ってませんでした。久々に買った上述のモーニング2を見ると、まだ連載されていてほとんど終盤のような内容です(最終回まであと3回と書かれてます)。気になりながらもしばらく忘れていた刻刻ですが、なんと連載開始してから10年後の今年、刻刻がアニメ化されて現在放映中です。

kokkoku-anime.comもう物語は佳境に入ってきていますが、おすすめです。

以上

AWS Certificate Manager (ACM)に関するメールが来ていたので調べてみた

「Preparing for Certificate Transparency with AWS Certificate Manager (ACM)」という件名の連絡がAWSから来ていたので調べてみた。

SSL証明書とCertificate Transparency

まずはググって調査してみる。「ACM Certificate Transparency」などでググると、AWSのブログの該当ページが見つかります。
aws.amazon.com
クラスメソッドさんのブログでも今回の件に関するページがあります。相変わらずの素早い情報提供で助かりますね。
dev.classmethod.jp

どういった内容か

上のリンク先を見ればだいたいの事が分かるようにまとまっていますが、要約すると「Google ChromeでのSSL証明書の要件が変更されるので、ACMで発行する証明書もそれに対応します」とのことです。

もう少し詳しく

SSL証明書の信頼性を高めるための新しい技術、Certificate Transparency(「証明書の透明性」、以下「CT」)というものがあります。仕組みとしては以下のようになります。

  1. 認証局は発行した証明書をCTログサーバーに送信します。
  2. CTログサーバーはSigned Certificate Timestamp (以下「SCT」)を認証局に返す。
  3. 認証局はSCT付きの証明書を発行し、Webサーバーが受け取る。
  4. ブラウザはWebサーバーにアクセスすると、証明書のSCTをCTログサーバーと照合できるか確認する。

ブラウザであるGoogle Chromeが2018/04/30より、SCTの照合を全てのSSL証明書で行うようになるので、認証局であるACMはそれに対応するためにCTログサーバーに証明書を送付し、返ってきたSCT付き証明書を発行することになるということです。
ちなみに2018/04/30より全てのSSL証明書が対象ですが、2015年からEV証明書についてはこのCTの対象です。EV証明書でCT対応していない場合、Google Chromeで証明書情報を確認すると「公開監査記録がありません」と表示されるようです。ACMはDV証明書なので、これまではCT対応が不要でした。

ユーザー側の対応事項は基本的になし

今回の対応は認証局であるACMが行うので、ユーザー側では特に対応する事項はありません。
ただし、このCTログサーバーは一般に公開されて誰でも閲覧できるようです。ドメイン情報が公開されると困る場合はCT対応しないように設定が必要になります。AWSでは「例えば、未発表製品の Web サイトを構築中で newproduct.example.com のようなサブドメインを登録しているような場合」として注意喚起しています。この設定については、「2018/03/27より ACM の API や AWS CLI を使って証明書単位で Certificate Transparency ログへの記録を無効にできるようになります。」とのことです。大抵の場合は気にする必要がなさそうです。

まとめ

今回はACMのCT対応について確認しました。ACMを使用してSSL証明書の発行している方は、念の為問題がないか確認して下さい。
ACM以外のSSL証明書を使用している方は認証局に一応対応状況を確認した方が良いと思います。
【追記内容】
2018/05/01にACMのアップデートのメールが来ていたので、以下のリンクでは問題ないかを確認しています。 www.prj-alpha.biz

以上

MySQLでテーブル、カラム、インデックスの情報を取得する方法

今回はMySQL用の備忘にたまに使うテーブルなどの定義取得用のSQLをまとめておきます。
MySQLではデータベース=スキーマと考えて良いみたいなので、指定に必要な場合はDB_NAMEと記載します。

テーブルを一覧で取得する方法

テーブル名の一覧のみ取得する場合(「DB_NAME」を取得対象に変更、引用符なし)

Show tables From DB_NAME;

テーブル情報の一覧を取得する場合(「DB_NAME」を取得対象に変更、引用符あり)

Select * From information_schema.tables I1
Where I1.table_schema = 'DB_NAME'
And I1.table_type = 'BASE TABLE';

TABLE_TYPEの条件を変更するとビューの一覧が取得できます

Select * From information_schema.tables I1
Where I1.table_schema = 'DB_NAME'
And I1.table_type = 'VIEW';

カラムを一覧で取得する方法

テーブル名を指定して取得する場合

Show columns From TABLE_NAME;

スキーマを指定してテーブルとカラム情報の一覧を取得する場合

Select * From information_schema.columns I1
Where I1.table_schema = 'DB_NAME';

インデックスを一覧で取得する方法

テーブル名を指定して取得する場合

Show index From TABLE_NAME;

スキーマを指定してテーブルとカラム、インデックス情報の一覧を取得する場合

Select * From information_schema.statistics I1
Where I1.table_schema = 'DB_NAME';

表示項目を絞ると

Select table_name,index_name,column_name,seq_in_index,non_unique
From information_schema.statistics I1
Where I1.table_schema = 'DB_NAME';

以上

Laravelのマイグレーション機能の活用② 1つのファイルで複数のテーブル管理も可能

今回はPHPフレームワークの一つのLaravelの中から、データベースのマイグレーションの機能の利用に当たって、我々の活用方法を紹介します。
今回利用するDBはMySQLですが、他のDBでもほぼ同様に対応できます。
またマイグレーションに関連する内容は以下を参照して下さい。

Laravelのデータベースのマイグレーション機能 順番を強引に入れ替えることも可能 - 商売力開発ブログ
Laravelのマイグレーション機能の活用① メンバ変数を追加した上でテーブルのコメント追加も簡単に設定する方法 - 商売力開発ブログ
Laravelのマイグレーション機能の活用③ カラム定義の管理を楽にする方法 - 商売力開発ブログ

Laravelの一つのマイグレーションファイルで複数のテーブルを管理する

今回は以前に紹介しました以下の雛形となるマイグレーションファイルを基にします。

class CreateSamplesTable extends Migration
{
    public $tbl_name='samples';//テーブル名のプロパティ追加
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create($this->tbl_name, function (Blueprint $table) {
            $table->increments('id');
            $table->string('name',255);
            $table->string('foreign_cd',5);
            $table->integer('sample_num');
        });
        // add comments
        DB::statement("ALTER TABLE ".DB::getTablePrefix().$this->tbl_name." COMMENT 'サンプルテーブル'");
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists($this->tbl_name);
    }
}

マイグレーションファイルはupとdownの2つのメソッドで構成され、upメソッドがマイグレーションの実行時の対象メソッドで、downメソッドがロールバックやリセットの対象メソッドとなることは以前説明しました。このupメソッドとdownメソッドを変更することで、複数のテーブルを一つのマイグレーションファイルで管理することも可能です。

class CreateSamplesTable extends Migration
{
    public $tbl_name='samples';//テーブル名のプロパティ追加
    public $tbl_name2='samples2';//もう一つのテーブル名のプロパティ追加
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create($this->tbl_name, function (Blueprint $table) {
            $table->increments('id');
            $table->string('name',255);
            $table->string('foreign_cd',5);
            $table->integer('sample_num');
        });
        // add comments
        DB::statement("ALTER TABLE ".DB::getTablePrefix().$this->tbl_name." COMMENT 'サンプルテーブル'");

        Schema::create($this->tbl_name2, function (Blueprint $table) {
            $table->increments('id');
            $table->string('name',255);
            $table->string('foreign_cd',5);
            $table->integer('sample_num');
        });
        // add comments
        DB::statement("ALTER TABLE ".DB::getTablePrefix().$this->tbl_name2." COMMENT 'サンプルテーブル2'");
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists($this->tbl_name);
        Schema::dropIfExists($this->tbl_name2);
    }
}

このようにすることで複数のテーブルを一つのマイグレーションファイルで管理することができます。同じ構造となるテーブルがある場合、マイグレーションを別けるよりも同じマイグレーションで管理しておくことで、後にカラムの変更がある場合など対象となるテーブルの漏れを防ぐのに役立ちます。
データベースのマイグレーションの管理をすることが目的なので、必ずしもテーブルごとに管理することなく、このようなやり方も可能です。

まとめ

今回はLaravelのマイグレーションの我々の活用方法の一部を紹介しました。

以上

【関連するリンク】

【スポンサーリンク】