15
DATABASE SCHEMA AS CODE ででででで / ででででで でででででで YOSHIYUKI NAKAHARA 2016.9.5

Database Schema as Code

Embed Size (px)

Citation preview

DATABASE SCHEMA AS CODEで楽に開発 / 運用しよう

社内勉強会用YOSHIYUKI NAKAHARA

2016.9.5

楽に運用したいなーと思ったら・あるべき状態を記述したコード・冪等性動作があれば楽になります。データベーススキーマにおいては、プロダクトの成長とともに変化していくDBスキーマの変更は意外と面倒くさいよね環境ごとにDBスキーマの状態は異なるよね現状を把握してどういう ALTER 文を書くかとやってませんか?その時間省きましょうRIDGEPOLE を使いましょう

RIDGEPOLE とはHTTPS://GITHUB.COM/WINEBARREL/RIDGEPOLERIDGEPOLE IS A TOOL TO MANAGE DB SCHEMA. IT DEFINES DB SCHEMA USING RAILS DSL, AND UPDATES DB SCHEMA ACCORDING TO DSL. (LIKE CHEF/PUPPET)

コードで書かれた状態にする ( 冪等性 ) の動作をしますコードの内容と実際のスキーマの内容の差分をとって- テーブルがなかったら作成します- カラム定義に差分があったら変更します- 差分がなかったらなにもしませんRIDGEPOLE が状況判断して差分 SQL 文を作成し、実行します

CI ツールと組み合わせてさらに楽に複数の開発環境で並行分散開発して時間とともにスキーマの定義がどんどん変わっていっても大丈夫( ブランチ名から開発環境名を認識できれば )コードが PUSH なり MERGE されたときに RIDGEPOLE を実行してその環境のDBに適用すればいいだけまさに DATABASE SCHEMA AS CODE ができる大分時間省けそうな気がしてきたよね

RIDGEPOLE を使ってみよう

10.10.10.10 に RIDGEPOLE プログラムをインストールし、10.10.10.11( リモート ) の MYSQL 上でスキーマ更新していくデモをやります

MYSQL サーバの準備 (10.10.10.11)

mysql> create database ridgepole_test

なにかを参考にして MYSQL SERVER を立ち上げてくださいデータベースの作成が必要です

RIDGEPOLE をインストールしよう (10.10.10.10)

MYSQL アダプターのインストール

gem install –g ridgepole

yum install epel-releaseyum install ruby

RIDGEPOLE 本体のインストール

yum groupinstall "Development Tools“yum install mysql-develgem install –g mysql2

RIDGEPOLE のコンフィグ (1/2)

MYSQL アダプターのインストール

# vi config.yml

development_1: adapter: mysql2 encoding: utf8 host: <%= ENV['MYSQL_HOST'] %> port: 3306 database: ridgepole_test username: root #password:production: ・・・・

データベース接続定義ファイルを作成します

<%= ENV[‘MYSQL_HOST’] %> は、コマンドラインの環境変数で指定されたホストにつなぐ為の変数です

RIDGEPOLE のコンフィグ (2/2)

MYSQL アダプターのインストール

# vi Schemafile

create_table "articles", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| t.string "title", collation: "ascii_bin" t.text "text", null: false, collation: "utf8mb4_bin" t.datetime "created_at" t.datetime "updated_at"end

スキーマ定義ファイルを作成します

こんな感じで定義していきます。詳細は GITHUB を参照してくださいこれで準備完了です。

RIDGEPOLE 実行してみる (1/4)

# MYSQL_HOST=10.10.10.11 \ ridgepole --config config.yml -E development_1 --file Schemafile --apply --dry-run

# CREATE TABLE `articles` (# `id` int(11) auto_increment PRIMARY KEY,# `title` varchar(255),# `text` text NOT NULL,# `created_at` datetime,# `updated_at` datetime)# ENGINE=InnoDB DEFAULT CHARSET=utf8

まず DRY-RUN で実行してみます

# の後に実行しようとしているSQL文が出力されました。これが RIDGEPOLE が認識した コードと実際のスキーマとの差分です

RIDGEPOLE 実行してみる (2/4)# MYSQL_HOST=10.10.10.11 \ ridgepole --config config.yml -E development_1 --file Schemafile --apply

Apply `schemafile`-- create_table("articles", {:options=>"ENGINE=InnoDB DEFAULT CHARSET=utf8"}) -> 0.0146s

実際に適用してみます

実際に確かめてみましょう 成功ですcadmin@host1:~ $ mysql -u root -h 10.10.10.11 -D ridgepole_test -e 'show create table articles\G'

Table: articlesCreate Table: CREATE TABLE `articles` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(255) DEFAULT NULL, `text` text NOT NULL, `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8

RIDGEPOLE 実行してみる (3/4)

# vi Schemafile

create_table "articles", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| t.string "title", null: false collation: "ascii_bin" t.datetime "created_at" t.datetime "updated_at"end

次にカラムの変更をしてみますTEXT カラムを削除して、 TITLE カラムに NULL 制約をつけた状態です

RIDGEPOLE 実行してみる (4/4)

# MYSQL_HOST=10.10.10.11 \ ridgepole --config config.yml -E development_1 --file Schemafile –apply –dry-run

# ALTER TABLE `articles` CHANGE `title` `title` varchar(255) NOT NULL# ALTER TABLE `articles` DROP `text`

まずは DRY-RUN で確認

実際に適用して確認しましょう このようになるはずですCreate Table: CREATE TABLE `articles` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(255) NOT NULL, `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8

まとめ(RIDGEPOLE に限りませんが )あるべき状態を記述したコード + 冪等性動作 があることにより、状態管理を気にしなくてよくなり、時間が省けて効率があがるさらに、CIツールとうまく組み合わせることでさらに効率があがるまた、 AS CODE という名前の通りにコードで管理することにより、- GIT DIFF で差分をみるだけで更新内容が一目でわかる- コードレビューすることで、クオリティを確保しつつ、属人化 / 秘伝のタレ化を防ぐことができる

良いソフトウェアエンジニアライフを!

ANY QUESTIONS ?