営業さんまで、社員全員がsqlを使う 「越境型組織」...
TRANSCRIPT
How Livesense Works #1
営業さんまで、社員全員がSQLを使う "越境型組織" ができるまでの3+1のポイントYukihiko Kawarazuka, Engineer of Livesense, [email protected]
ある日、営業さんから来た依頼
あるある
わりとざっくり仕様。
※反響=お問い合わせのこと
でも
あるある
その8ヶ月後
これはほんの一例
なぜ?なぜ、営業さんもSQLを書くのか なぜ、営業さんにまでデータベースアクセス権を開放しているのか なぜ、SQLを学習しようと思ったのか なぜ、学習を完遂できたのか なぜ、学習にとどまらず実運用に耐えるスキルに昇華されたのか なぜ、このような協業文化ができ、根付いたのか
私は前職で「怠惰で横柄で直感頼りな営業」にしびれを切らし、*1
開発をやりつつ自分で営業もしていたので「なぜ?」を越えて「ショック」だった。
*1 切らしたのはしびれだけではなかったが
営業 「データベース?そんなよくわからんもの営業には関係ない」シス管 「DBにアクセスできる人数は、最小限にすべき。 技術コンタミを防ぐために、部署外の人間はアクセス禁止」マーケ 「昔いた〇〇さんはSQLでやってたみたいだけど、、 はてどうやるんだっけ」プロマネ「いいものを開発しよう。 いいものを作れば営業が売ってきてくれる。 どう売るか?知らないけどそれは営業が。」開発 「えっ外注して作ってもらったの? それうちの部署でツール化してたのに。」
私が前職でよく聞いた声
本質的な課題とは
無関心
責任範囲の固執
意図しない秘密主義
責任範囲への固執(セクショナリズム)
原因:
自分が与えられた責任を全うしようとする、責任感に起因。責任を全うするのは、当然重要。しかし部分最適になっていないか?
「セキュリティのため、DBにアクセスできる人数は最小限にすべき」「技術コンタミを防ぐために、部署外の人間はアクセス禁止」
無関心
「データベース?そんなよくわからんもの営業には関係ない」
「いいものを開発しよう。いいものを作れば営業が売ってきてくれる。どう売るか?知らないけどそれは営業が。」
原因:
(1)自分の持つ強み(技術・ノウハウ)のみで仕事を捉え、それを一般化してしまう。(2)事業やサービス全体を俯瞰した視野が持てておらず、自分の業務外の部分を吸収しようとしない。
”責任範囲への固執”から生まれていることも多い。
意図しない秘密主義
原因:
(1)本当はちゃんと皆に共有したいが、置き場がないため口伝の世界に(2)他に必要な人、あると嬉しい人がいることを知らない
その結果、人が目に届かないところに成果物がおかれ、意図せずに秘密主義化する。“無関心”から引き起こされることも多い。
「昔いた〇〇さんはそうやってたみたいだけど、、はてどうやるんだっけ」「えっ外注して作ってもらったの?それうちの部署でツール化してたのに。」
無関心
責任範囲の
固執
意図しない
秘密主義
そんなよくわからんもの営業には関係ない
お客様の情報が入ったデータをだれでも触らせるわけにはいかん
昔いた〇〇さんはそうやってたみたいだけど
各々が各々を引き起こす因果関係にあり、組み合わさると、ひどい悪循環に。
こんな悪循環にしないために、なにができるか。
#1 「意図しない秘密主義」から「共有カルチャーの醸成」へ ・情報共有するためののインフラを用意する ・情報共有マインドを醸成する
#2 「無関心」から「学習を通じた相互理解」へ ・関心を引く資料を共有し、それを実現するための技術要素の提示 ・身近な題材を用いた教材の用意 ・学習の見える化による相互作用
#3 「責任範囲への固執(セクショナリズム)」から「越境する組織」へ ・職種を越えるための環境の整備 ・越境者には伴走を ・越境したら伝道を
無関心
責任範囲の
固執
意図しない
秘密主義
学習
越境
共有
組織や職種という範疇を越境して協業を行い、その事例を共有し、
その共有事例がさらなる学習意欲を生むことで、より組織や職種を超えたコラボレーションが生まれるサイクルが理想的
営業さんもSQLを書くようになるまでの事例
#1
「意図しない秘密主義」から「共有カルチャーの醸成」へ
学習
越境
共有
導入している情報共有インフラRedmine(現在はJIRAに移行中)
ConfluenceHipchatCybouzu
GoogleApps
基本は社員に対してオープンアクセス必要に応じて制限するポリシー
Redmine(※現在はAtlassian JIRAに移行中)
すべての業務フローを一つのシステムに集約。営業さんからのSQL発行依頼からプロダクトの仕様決定まで、後から見返し経緯を知ることができる。
→新しく入社しても、創業初期からの経緯を知ることができる
Atlassian Confluence
トップページは人気順。企画・エンジニアリングから「本当に難しいショートケーキ」まで、フラットに並ぶ。
Atlassian HipChat (チャット)事業別ROOM(必須参加)と、要素別ROOM(任意参加)を用意。
情報共有インフラの導入≠
情報共有カルチャーの醸成
情報共有カルチャーの醸成 > 情報共有インフラの導入
情報共有カルチャーの醸成 > 情報共有インフラの導入
#2
「無関心」から「学習を通じた相互理解」へ
学習
越境
共有
関心を引くレポートと、その共有
調査レポートにSQLクエリが併記されることで、関心事と要素技術がつながる
再現方法があることで追試を行える、真似できる
身近な題材を用いた教材: SQL100本ノック
自習の見える化と相互作用
#3
「責任範囲への固執(セクショナリズム)」から「越境する組織」へ
学習
越境
共有
「職種を越えるための環境の整備」
非エンジニアへの分析用DB公開
「セキュリティのため、DBにアクセスできる人数は最小限にすべき」
技術による制約の回避
個人情報マスキングプログラム
本番系DBに格納された個人情報を保護(マスク)し、社内スタッフが触れるようするにためのプログラム。
DBマスキング処理を簡単に記述できるよう、よく使われるマスキングパターンを基本プログラム側で用意している。
テーブル名とカラム名を指定すれば即マスキング対応可能。
パターン マスキング処理内容
氏名 「山田 太郎」「ヤマダ タロウ」「ヤマダタロウ」「やまだ たろう」のどれかに変更住所 「東京都渋谷区南平台町16-28」に変更ビル名 「グラスシティ渋谷 2F」に変更
メールアドレス “@”とトップレベルドメイン以外をハッシュ化。ただしデバッグのため自社メールアドレス(*.livesense.co.jp)はハッシュ化しない
口座番号 半角7文字の乱数で埋める銀行コード 半角4文字の乱数で埋める銀行支店番号 半角3文字の乱数で埋めるその他 「このカラムはマスキングされています。」に変更
企業名 「株式会社マスキング」「カブシキガイシャマスキング」のどれかに変更
電話番号 半角12文字のユニークな乱数で埋める
基本プログラムで用意しているマスキングパターン
その上で
まずは再利用から
エンジニア主導のトレーニング「越境者には伴走を」
若手(入社1~2年目相当)2名
教材作成(SQL100本ノック)
&実地でのトレーニング
教えるかわりに、他の人へも教える約束
実地でのトレーニング
:
:指摘されたところをもう一度ミス
:
:
難しいところはExcelで乗り切る
その後、慣れてきた頃に
400万件のフルスキャン
重いクエリでDBサーバ止まる
“ー “未来企業 レジリエンスの経営とリーダーシップ” 94ページ
協働を最大限に促すために
1 責務の透明性を高める 2 サイバー空間で信頼を高めながら親睦を深める 3 コミュニケーションを欠かさない 4 思いやりの重要性を理解する
その後、各チームでの伝道師的な活動「越境したら伝道を」
各メディアごとの100本ノックの作成
伝道師的活動
アルバイトスタッフにも
アルバイトスタッフ向け勉強会資料
全員がSQLを書くようになるまでの事例はここまで。
ー “戦略サファリ” 258ページ
組織学習の基本原則 1 失敗から学ぶ 2 絶え間ない再検証 3 直接体験による学習 4 知識の流動性を保つ 5 外界に目を向け、知識を吸収する
“
One more thing…
学習
越境
共有
学習
越境
共有
知識創造
学習Internalization
(内面化)
越境Socialization
(共同化)
共有Externalization
(表出化)
知識創造Combination
(連結化)
多くの “知識創造企業” で見られる
“SECIモデル”
“ 組織的な知識創造は 個人レベルから始まり、 メンバー間の相互作用が、課、部、事業部門、 そして組織という共同体の枠を超えて 上昇、拡大していくスパイラル・プロセス
ー “知識創造企業” 108ページ
このスパイラルが回り出すことで、より組織や職種を超えたコラボレーションが生まれる
営業さんもSQLを書くようになった頃に
SQLクエリを登録しておき
ExcelのWebクエリ機能で、データを取得・更新
各種分析をExcelベースで行えるように
そしてその結果は、デイリーチャートとしてチームに共有
まとめ
学習・共有の環境を整えた上で、 「越境」を促すことで、
職種を超えたコラボレーションを行うことができる。
SQLはその一例。
自分の仕事の領域を決めすぎず学ぶこと 相手の仕事の領域を敬意をもって侵すことうまくいったことを、具体的に共有すること うまくいったスパイラルの伝道師となること
そして、 このサイクルを通じて皆が一緒に、
良い仕事・良いサービスを作っていこうとすること
その先にある、「創造型組織」を目指し続けること
“ー “イノベーションのDNA” 53ページ
イノベーティブなアイデアは、さまざまな人たちの多様な経験が交わる場所で花開く。歴史を通じて、偉大なアイデアは文化や 経験の交わるところで生まれている。
付録今日から社内で使えるSQL10本ノック
リブセンス社内で使われている実際の「SQL100本ノック」のうち 10本を厳選し、
教育用途として扱いやすいようにスキーマをカスタマイズしたものです。
DB環境がなくとも、ブラウザがあれば実施できるように準備しました。
題材は「アルバイト求人情報サイト」 (※貴社に馴染みのある題材に変更してお使いください)
応募テーブル、店舗テーブル、都道府県テーブルの構成
テーブル説明::entries(応募)
カラム名 説明 例id ID 23name 応募者氏名 木村太郎birthday 生年月日 1995-03-02mail メールアドレス [email protected] 応募日 2013-02-21
adopt_status採用確定時に1、 不採用確定時に2、 そうでなければ0
1
adopt_date 採用・不採用確定日 未確定のときは0 2013-02-27
client_id 店舗ID 3
device_type 応募時に利用したデバイス SMARTPHONE/PC
テーブル説明::client(店舗)
カラム名 説明 例
id ID 3
name 店舗名 井村商店
pref_id 都道府県ID 13
テーブル説明::pref(都道府県)
カラム名 説明 例
id ID 13
name 都道府県名 東京都
http://sqlfiddle.com/ にて、ダウンロードしたベースSQLを投入
まず、テーブル内の件数を出してみましょう動作確認
Run SQLを押して、件数が出れば成功です。
それでは10本ノック、行ってみましょう
2013年2月の応募数
SELECT COUNT(*) FROM entries WHERE entries.date BETWEEN '2013-02-01 00:00:00' AND '2013-02-28 23:59:59' ;
2013年2月の採用数
SELECT COUNT(*) FROM entries WHERE entries.adopt_status = 1 AND entries.date BETWEEN '2013-02-01 00:00:00' AND '2013-02-28 23:59:59' ;
2013年2月の不採用数
SELECT COUNT(*) FROM entries WHERE entries.adopt_status = 2 AND entries.date BETWEEN '2013-02-01 00:00:00' AND '2013-02-28 23:59:59' ;
2013年2月に応募があった店舗数
SELECT COUNT(DISTINCT client_id) FROM entries WHERE entries.date BETWEEN '2013-02-01 00:00:00' AND '2013-02-28 23:59:59' ;
2013年2月の応募数前年比
SELECT SUM(entries.date between '2013-02-01' and '2013-02-28 23:59:59') / SUM(entries.date between '2012-02-01' and '2012-02-29 23:59:59') AS ratio FROM entries WHERE YEAR(entries.date) IN (2012,2013) AND MONTH(entries.date) = 2 ;
2013年2月の東京都の応募数
SELECT prefs.id, prefs.name, COUNT(*) FROM clients INNER JOIN prefs ON clients.pref_id = prefs.id INNER JOIN entries ON clients.id = entries.client_id WHERE entries.date BETWEEN '2013-02-01 00:00:00' AND '2013-02-28 23:59:59' AND prefs.name = '東京都' GROUP BY prefs.id, prefs.name ORDER BY prefs.id, prefs.name ;
2013年2月の都道府県別応募数ランキング上位3位
SELECT prefs.id, prefs.name, COUNT(*) FROM clients INNER JOIN prefs ON clients.pref_id = prefs.id INNER JOIN entries ON clients.id = entries.client_id WHERE entries.date BETWEEN '2013-02-01 00:00:00' AND '2013-02-28 23:59:59' GROUP BY prefs.id, prefs.name ORDER BY COUNT(*) DESC LIMIT 3 ;
2013年2月のデバイス別応募数
SELECT device_type, COUNT(*) FROM entries WHERE entries.date BETWEEN '2013-02-01 00:00:00' AND '2013-02-28 23:59:59' GROUP BY device_type ;
以上で問題終了です。
解いた事例は共有してもらましょう!