PostgreSQL 9.5 beta1 インストール
itame でインストールしてみた。
一応変数を外部に押し出してみたけど、どうだろう。汎用性はなさそうだな。
my_postgresql.rb
# PostgreSQL Install ver = node[:postgresql][:ver] short_ver = node[:postgresql][:short_ver] package node[:postgresql][:pgdg] do not_if "rpm -q #{File.basename(node[:postgresql][:pgdg], ".rpm")}" end package "postgresql#{short_ver}" package "postgresql#{short_ver}-server" package "postgresql#{short_ver}-contrib" package "postgresql#{short_ver}-devel" package "postgresql#{short_ver}-libs" execute "initdb" do command "PGSETUP_INITDB_OPTIONS='--no-locale' /usr/pgsql-#{ver}/bin/postgresql#{short_ver}-setup initdb" not_if "test -e /var/lib/pgsql/#{ver}/data/postgresql.conf" end service "postgresql-#{ver}" do action :start end # Firewall execute "firewall port open" do command "firewall-cmd --add-port=5432/tcp --zone=public --permanent" not_if "grep -c 5432 /etc/firewalld/zones/public.xml" end service "firewalld" do action :restart end
node.yaml
# postgresql postgresql: pgdg: http://yum.postgresql.org/9.5/redhat/rhel-7-x86_64/pgdg-centos95-9.5-2.noarch.rpm ver: 9.5 short_ver: 95
実行
itamae ssh --host localhost -p 2222 -u vagrant ./my_postgresql.rb -y node.yml
Vagrant の Box を作る
Redmine を使う環境を構築しようと思ったが、せっかくなので掲題を試してみようと思った次第。
検索すると、以下のサイト様の通りで全然OKで言うことなかった。すごいね。
Vagrant の VirtualBox 用 Base Box ファイルを手動で作ってみる | CUBE SUGAR STORAGE
CentOS7の通常DVDイメージを使ってインストールした。
NICの設定とかはインストール時にやってしまった。
今回、勉強も兼ねて itamae を使って設定してみた。
で、最初は上記サイト様の操作コマンドをそのまま command にして記述していたいのだが、何度も実行するのには向いていない。
そもそも何度も実行することはないのだが、気にはなる。
正しいかどうかは分からないが、結局 sshd_config や sudoers ファイルをホストに置いて、それを remote_file 使うと勝手に diff 見てくれるので便利。
下の感じでどうだろ。
# sshd config remote_file "/etc/ssh/sshd_config" do owner "root" group "root" source "recipes/remote_files/sshd_config" mode "0600" end # vagrant remote_file "/etc/sudoers" do owner "root" group "root" source "recipes/remote_files/sudoers" mode "0440" end directory "/home/vagrant/.ssh" do owner "vagrant" group "vagrant" mode "0700" action :create end execute "vagrant public key" do user "vagrant" command "curl -L -o /home/vagrant/.ssh/authorized_keys https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub" end file "/home/vagrant/.ssh/authorized_keys" do owner "vagrant" group "vagrant" mode "0600" end service "sshd" do action :restart end
7つのデータベース7つの世界
- 作者: Eric Redmond,Jim R. Wilson,角征典
- 出版社/メーカー: オーム社
- 発売日: 2013/02/26
- メディア: 単行本(ソフトカバー)
- 購入: 3人 クリック: 56回
- この商品を含むブログ (15件) を見る
読了。 Cassandraを「使うのが目的」のことがあるんだけど、やっぱり間違ってると分かった。
第8章 Redis
- 速度に関していえば最高
- 超高速なキーバリューストア
- 何であるかを正確に分類するのは難しい
- 応用的なデータ構造をサポート
- ブロッキングキュー
- スタック
- Pub/Sub
- 有効期限/永続レベル/レプリケーションのオプションが設定可能
- 便利なデータ構造のアルゴリズムやプロセスのツールキット
% brew install redis % redis-server -v Redis server v=3.0.5 sha=00000000:0 malloc=libc bits=64 build=78b12a45f78ec0e % redis-server % redis-cli 127.0.0.1:6379> PING PONG 127.0.0.1:6379> SET 7wks http://www.sevenweeks.org/ OK 127.0.0.1:6379> GET 7wks "http://www.sevenweeks.org/" 127.0.0.1:6379> MSET gog https://www.google.co.jp/ yah http://www.yahoo.co.jp/ OK 127.0.0.1:6379> MGET gog yah 1) "https://www.google.co.jp/" 2) "http://www.yahoo.co.jp/" 127.0.0.1:6379> SET count 2 OK 127.0.0.1:6379> INCR count (integer) 3 127.0.0.1:6379> GET count "3" 127.0.0.1:6379> SET bad_count "a" OK 127.0.0.1:6379> INCR bad_count (error) ERR value is not an integer or out of range
127.0.0.1:6379> MULTI OK 127.0.0.1:6379> SET prag https://pragprog.com/ QUEUED 127.0.0.1:6379> INCR count QUEUED 127.0.0.1:6379> EXEC 1) OK 2) (integer) 4 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> INCR count QUEUED 127.0.0.1:6379> DISCARD OK 127.0.0.1:6379> GET count "4"
- 複雑なデータ型
- リスト・ハッシュ・セット・ソート済みが保存できる
- ハッシュ
- ネストできない
- HDEL 削除
- HINCRBY インクリメント
- HLEN フィールド数
127.0.0.1:6379> MSET user:eric:name "Eric Redmond" user:eric:password s3cret OK 127.0.0.1:6379> MGET user:eric:name user:eric:password 1) "Eric Redmond" 2) "s3cret" 127.0.0.1:6379> HMSET user:eric name "Eric Redmond" password s3cret OK 127.0.0.1:6379> HVALS user:eric 1) "Eric Redmond" 2) "s3cret" 127.0.0.1:6379> HKEYS user:eric 1) "name" 2) "password" 127.0.0.1:6379> HGET user:eric password "s3cret"
- リスト
127.0.0.1:6379> RPUSH eric:wishlist 7wks gog yah (integer) 3 127.0.0.1:6379> LRANGE eric:wishlist 0 -1 1) "7wks" 2) "gog" 3) "yah" 127.0.0.1:6379> LREM eric:wishlist 0 gog (integer) 1 127.0.0.1:6379> LRANGE eric:wishlist 0 -1 1) "7wks" 2) "yah" 127.0.0.1:6379> LPOP eric:wishlist "7wks" 127.0.0.1:6379> LRANGE eric:wishlist 0 -1 1) "yah" 127.0.0.1:6379> RPOPLPUSH eric:wishlist eric:visited "yah"
% gem i redis
Successfully installed redis-3.2.1
1 gem installed
- リストのブロック
- 別でコンソールを立ち上げブロッキングコマンドを実行
127.0.0.1:6379> BRPOP comments 300
127.0.0.1:6379> LPUSH comments "Prag is great! I buy all my books there." (integer) 1
127.0.0.1:6379> BRPOP comments 300 1) "comments" 2) "Prag is great! I buy all my books there." (30.38s)
- セット
127.0.0.1:6379> SADD news nytimes.com pragprog.com (integer) 2 127.0.0.1:6379> SMEMBeRS news 1) "pragprog.com" 2) "nytimes.com" 127.0.0.1:6379> SADD tech pragprog.com apple.com (integer) 2 127.0.0.1:6379> SINTER news tech 1) "pragprog.com" 127.0.0.1:6379> SDIFF news tech 1) "nytimes.com" 127.0.0.1:6379> SUNION news tech 1) "pragprog.com" 2) "apple.com" 3) "nytimes.com" 127.0.0.1:6379> SUNIONSTORE websites news tech (integer) 3 127.0.0.1:6379> SMEMBErS websites 1) "pragprog.com" 2) "apple.com" 3) "nytimes.com"
- ソート済みセット, 範囲
127.0.0.1:6379> ZADD visits 500 7wks 9 gog 9999 prag (integer) 3 127.0.0.1:6379> ZINCRBY visits 1 prag "10000" 127.0.0.1:6379> ZRANGE visits 0 1 1) "gog" 2) "7wks" 127.0.0.1:6379> ZRANGE visits 0 -1 WITHSCORES 1) "gog" 2) "9" 3) "7wks" 4) "500" 5) "prag" 6) "10000" 127.0.0.1:6379> ZREVRANGE visits 0 -1 WITHSCORES 1) "prag" 2) "10000" 3) "7wks" 4) "500" 5) "gog" 6) "9" 127.0.0.1:6379> ZRANGEBYSCORE visits 9 10000 1) "gog" 2) "7wks" 3) "prag" 127.0.0.1:6379> ZRANGEBYSCORE visits (9 (10000 1) "7wks" 127.0.0.1:6379> ZRANGEBYSCORE visits -inf inf 1) "gog" 2) "7wks" 3) "prag"
- 和
127.0.0.1:6379> ZADD votes 2 7wks 0 gog 9001 prag (integer) 3 127.0.0.1:6379> ZUNIONSTORE importance 2 visits votes WEIGHTS 1 2 AGGREGATE SUM (integer) 3 127.0.0.1:6379> ZRANGEBYSCORE importance -inf inf WITHSCORES 1) "gog" 2) "9" 3) "7wks" 4) "504" 5) "prag" 6) "28002"
- 有効期限
- カウントダウンは EXPIREAT (絶対時間)
- EXPIRE は相対時間
127.0.0.1:6379> SET ice "I'm melting..." OK 127.0.0.1:6379> EXPIRE ice 10 (integer) 1 127.0.0.1:6379> EXISTS ice (integer) 1 127.0.0.1:6379> EXISTS ice (integer) 1 127.0.0.1:6379> EXISTS ice (integer) 1 127.0.0.1:6379> EXISTS ice (integer) 0 127.0.0.1:6379> SETEX ice 10 "I'm melting..." OK 127.0.0.1:6379> TTL ice (integer) 4 127.0.0.1:6379> SETEX ice 10 "I'm melting..." OK 127.0.0.1:6379> PERSIST ice (integer) 1 127.0.0.1:6379> EXISTS ice (integer) 1
- データベースの名前空間
127.0.0.1:6379> SET greeting hello OK 127.0.0.1:6379> GET greeting "hello" 127.0.0.1:6379> SELECT 1 OK 127.0.0.1:6379[1]> GET greeting (nil) 127.0.0.1:6379[1]> SET greeting "guten tag" OK 127.0.0.1:6379[1]> SELECT 0 OK 127.0.0.1:6379> GET greeting "hello" 127.0.0.1:6379> MOVE greeting 2 (integer) 1 127.0.0.1:6379> SELECT 2 OK 127.0.0.1:6379[2]> GET greeting "hello" 127.0.0.1:6379[2]> SELECT 0 OK 127.0.0.1:6379> GET greeting (nil)
% telnet telnet> open localhost 6379 Trying ::1... Connected to localhost. Escape character is '^]'. SET test hello +OK GET test $5 hello SADD stest 1 99 :2 SMEMBERS stest *2 $1 1 $2 99
% (echo -en "ECHO hello\r\n"; sleep 1) | nc localhost 6379 $5 hello % (echo -en "PING\r\nPING\r\nPING\r\n"; sleep 1) | nc localhost 6379 +PONG +PONG +PONG
- 出版/購読
127.0.0.1:6379> SUBSCRIBE comments Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "comments" 3) (integer) 1
127.0.0.1:6379> PUBLISH comments "Check out this shortcoded site! 7wks" (integer) 1
127.0.0.1:6379> SUBSCRIBE comments Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "comments" 3) (integer) 1 1) "message" 2) "comments" 3) "Check out this shortcoded site! 7wks"
- サーバ情報
127.0.0.1:6379> info # Server redis_version:3.0.5 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:78b12a45f78ec0e redis_mode:standalone ...
- 永続性
- SAVE
- BGSAVE
- スナップショット
- 追記型フィールド
- めちゃくちゃ遅い
- セキュリティ
- パラメータの調整
% redis-benchmark -n 100000 [252/576] ====== PING_INLINE ====== 100000 requests completed in 3.33 seconds 50 parallel clients 3 bytes payload keep alive: 1 0.86% <= 1 milliseconds 83.00% <= 2 milliseconds 99.95% <= 7 milliseconds 99.96% <= 8 milliseconds 100.00% <= 9 milliseconds 100.00% <= 9 milliseconds 30012.00 requests per second ...
- マスタスレーブレプリケーション
% redis-server redis-sl.conf 37908:S 24 Oct 21:38:41.265 * Increased maximum number of open files to 10032 (it was originally set to 256). _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 3.0.5 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6380 | `-._ `._ / _.-' | PID: 37908 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 37908:S 24 Oct 21:38:41.268 # Server started, Redis version 3.0.5 37908:S 24 Oct 21:38:41.268 * The server is now ready to accept connections on port 6380 37908:S 24 Oct 21:38:41.268 * Connecting to MASTER 127.0.0.1:6379 37908:S 24 Oct 21:38:41.269 * MASTER <-> SLAVE sync started 37908:S 24 Oct 21:38:41.269 * Non blocking connect for SYNC fired the event. 37908:S 24 Oct 21:38:41.270 * Master replied to PING, replication can continue... 37908:S 24 Oct 21:38:41.270 * Partial resynchronization not possible (no cached master) 37908:S 24 Oct 21:38:41.271 * Full resync from master: d5f7d1c8d4640c774e1c747b7cec1bd169e092c9:1 37908:S 24 Oct 21:38:41.397 * MASTER <-> SLAVE sync: receiving 400726 bytes from master 37908:S 24 Oct 21:38:41.400 * MASTER <-> SLAVE sync: Flushing old data 37908:S 24 Oct 21:38:41.400 * MASTER <-> SLAVE sync: Loading DB in memory 37908:S 24 Oct 21:38:41.451 * MASTER <-> SLAVE sync: Finished with success
- ブルームフィルタ
- セットに存在しない項目をチェックする確率的データ構造
- Ruby の神童 Ilya Grigorik
- SETBIT と GETBIT
127.0.0.1:6379> SETBIT my_burger 1 1 (integer) 0 127.0.0.1:6379> SETBIT my_burger 2 1 (integer) 0 127.0.0.1:6379> GETBIT my_burger 3 (integer) 0 127.0.0.1:6379> GETBIT my_burger 1 (integer) 1
- ポリグロット永続亜kサービス
- ノンブロッキングコード
- 時間のかかるプロセスの終了を待たずにメインコードを実行し続けること
- Ruby: EventMachine
- Python: Twisted
- Java: NIOライブラリ
- C#: Interlace
- JavaScript: Node.js
- Redis の強み
- Redis の弱み
- スナップショットをとる前にシャットダウンするとデータが失われる
- 追記型ファイルを設定しても期限切れの値を扱うリスクがある
- 使用可能な RAM より大きなデータセットは扱えない
第9章 まとめ
- データの保存方法は大きく5つに分類
- リレーショナル
- キーバリュー
- カラムナー
- ドキュメント
- グラフ
- リレーショナル
- データが変わりやすかったり、データ階層が深いものには適していない
- キーバリュー
- カラムナ-
- 水平スケーラビリティが高いので、ビッグデータの問題に最適
- データ使用パターンが事前に決定できていないければ適していない
- ドキュメント
- 変化の大きなドキュメントの問題に適している
- 事前にデータがどのようになるか正確に分からない場合
- インピーダンスミスマッチが少ない
- 結合に該当するものがないので正規化できない
- グラフ
- レコメンテーションエンジン
- アクセスコントロールリスト
- ジオグラフィックデータ
- ネットワーキングアプリケーション
- オブジェクト指向にも完璧に対応
- ネットワーク分割には適さない
- データベースの選択はドメインのデータに適したデータベースの分野を考えるより複雑
7つのデータベース7つの世界
- 作者: Eric Redmond,Jim R. Wilson,角征典
- 出版社/メーカー: オーム社
- 発売日: 2013/02/26
- メディア: 単行本(ソフトカバー)
- 購入: 3人 クリック: 56回
- この商品を含むブログ (15件) を見る
第7章まで。
第7章 Neo4j
- グラフデータベース
- データをグラフとして保存
- ホワイトボードフレンドリー
- ウォーキング
- 全てがリレーションシップ
- Gremlin
- Groovy で書かれたグラフ探索言語
- パイプ
- パイプの連続 パイプライン
- jQuery を使っているなら Germlin のコレクション指向探索に親しみを覚えるだろう
- Cypher 言語
- グラフクエリ言語
- スキーマレスソーシャル
- ドメイン特化ステップ
- RESTインターフェイス
- Gremlin プラグイン
- ビッグデータを扱える
- ファンシーアルゴリズム
- ランダムウォーク
- 中心性公園
- 外部アルゴリズム
- 分散型高可用性
- 高可用性
- 一瞬だけ整合性が失われる危険性がある
- Neo4j HA は読み取り性能を大きく向上させるソリューション
- HA クラスタ
- 希少なグラフデータベースにおけるオープンソース実装のトップ
- Neo4j の強み
- Neo4j の弱み
- 難しい用語体系はコミュニケーションの妨げなっている
- サブグラフのシャードはできない
- グラフの規模には制限がある
- ラインセンスの問題
7つのデータベース7つの世界
7つのデータベース7つの世界
- 作者: Eric Redmond,Jim R. Wilson,角征典
- 出版社/メーカー: オーム社
- 発売日: 2013/02/26
- メディア: 単行本(ソフトカバー)
- 購入: 3人 クリック: 56回
- この商品を含むブログ (15件) を見る
NoSQLを使う場面とは?ということに悩んだので、読んでみた。 正直、PostgreSQLさえあればなんでも出来そうって気になってきた。 第6章まで。
第1章 イントロダクション
- リレーショナルデータベース
- キーバリューストア
- Raik
- Redis
- 列指向データベース
- HBase
- ドキュメント指向データベース
- MongoDB
- CouchDB
- グラフデータベース
- Neo4j
- ポリグロット(混合型)
- 複数のデータベースの長所を組み合わせてエコシステムを構築
第2章 PostgreSQL
- 普及の要因
- データの安全性(ACID準拠)
- マインドシェア
- クエリの柔軟性
- 正規化による柔軟な問い合わせ
- PostgreSQL
- 数学的リレーション
- リレーション(テーブル)
- 属性(列)
- タプル(行)
- CRUD
- Create
- Read
- Update
- Delete
- インデックスで高速検索
- Bツリーインデックス
- ハッシュインデックス
- 集約関数
- グループ化
- MySQL では GROUP BY にない列を SELECT できる
- いずれかの結果を返すので信頼性がない
- PostgreSQL も v9.1 から PostgreSQL 9.1 の新機能 — Let's Postgres http://lets.postgresql.jp/documents/technical/9.1/1
- MySQL では GROUP BY にない列を SELECT できる
- ウィンドウ関数
- 複数の行に対して集約関数を実行
- 行をグループ化することなく集約関数を使える
- トランザクション
- ストアドプロシージャ
- 恐怖のベンダーロックイン
- コードはアプリケーションに依存するのか?データベースに依存するのか?
- トリガー
- ビュー
- ルール
- クロス集計
- あいまい検索
- LIKE、ILIKE
- 正規表現
- レーベンシュタイン
- トリグラム
- TSVevtor, TSQuery
- 汎用転置インデックス GIN
- メタフォン
- 多次元ハイパーキューブ
- PostgreSQL の強み
- リレーショナルモデルと同じく膨大
- 長年の研究
- あらゆる計算分野における利用実績
- 柔軟なクエリ
- 高い整合性と永続性
- 実践で使い込まれた各言語用のPostgres用のドライバ
- PostgreSQL の弱み
- 分割がうまくできない
- スケールアップ、スケールアウト
- データが柔軟過ぎる場合
- 分割がうまくできない
第3章 Raik
- 分散型キーバリューデータベース
- プレインテキスト・JSON・XML・画像、動画などHTTPインターフェイス経由でアクセスできればなんでも
- 耐障害性
- アドホッククエリを十分にサポートしていない
- 低レイテンシーで大量のリクエストをさばくDCに最適
- Amazon の Dynamo 論文から着想
- データの検索方法 mapreduce
- Erlang が必要
- cURL
- リンク
- キーと別キーを関連付けるメタデータ
リンクウォーキング
MIME タイプ
- バイナリデータには MIME タイプで情報を付加
- mapreduce
- ストアドファンクション
- キーフィルタ
- 整合性と永続性
- アーキテクチャレベルで単一障害点を排除
- Riak リング
- 書き込みに永続性がない(デフォルトでは)
- DW という永続性が高い書き込み設定を用意している
- ベクタークロック
- 事前/事後コミットフック
- 全文検索
- HTTP Solr インターフェイス
- Riak の強み
- 大規模
- 可用性
- 言語サポート
- Riak の弱み
- 単純なクエリ
- 複雑なデータ構造
- 厳格なスキーマ
- 水平スケーリングが不要
HBase
- RDBMS の双子の悪魔
- 他のDBにない機能
- バージョニング
- 圧縮
- GC
- インメモリテーブル
- Apache Hadoop の contrib パッケージとして生まれたが、今はトップレベルプロジェクト
- Facebook、Tiwtter でも利用
- 本番の品質で運用するには最低5台以上のノードが必要
- 3つのモード
- HBaseシェル
- 列ファミリーを変更する操作はコストが高い
- 新しい設定の列ファミリーを作って、すべてそこにコピーするから
- 列ファミリーを使うことにより細かなパフォーマンスチューニングが可能となる
- 圧縮
- Gzip(GZ)
- Lempel-Ziv-Oberhumer(LZO)
- Community 推奨だがライセンスに問題がありバンドルされていない
- 高性能圧縮が必要なら
- ブルームフィルタ
- 消費領域を抑えることができるが、飽和率に応じて一定の誤検出が発生する
- コストの高いディスク読み取りをする前にデータが存在するかどうかを決定する高速な方法
- スパースデータストア
- Thrift
- バイナリプロトコル
- HBase のスキーマ設計は、テーブルや列のパフォーマンスを決定する
- HBase の強み
- 堅牢なスケールアウトアーキテクチャ
- バージョニング
- 圧縮機能
- ギガ、テラで役に立つ
- ラックウェア
- Community が素晴らしい
- HBase の弱み
- スケールダウンできない
- 最低5台が必要
- 管理が難しい
- 小さな問題の解決には向いていない
- 初心者用のドキュメントも手に入らないので学習曲線は急勾配
- 行キー以外にソートやインデックスの機能を提供していない
- データ型も存在しない
- HBase と CAP定理
- CP
- 使うときは怪我をしないように
第5章 MongoDB
- パワードリル
- 様々な用途に使える
- 仕事の大小を問わない
- JSON フォーマットのドキュメントデータベース
- スキーマレス
- サーバサイドでの結合をサポートしていない
- 自動採番
- あらゆるところに JavaScript を使っている
- スペルミスに注意
- 柔軟性にはコストがつきもの
- ドキュメントの集まりはコレクション
- インデックス
- Bツリー
- 2次元インデックス
- GeoSpatial
- 大きなコレクションにインデックスを作ろうとすると時間とリソースを浪費
- オフピーク時に
- 集約クエリ
- group() 関数の弱点
- 結果ドキュメント数の上限が10,000
- コレクションをシャードするとうまく動かない
- 特別な要素
- レプリケーション
- シャーディング
- レプリカセット
- スケールアウトを目的に作られている
- 単独で実行するものではない
- ノードが奇数であることを期待する
- マルチマスターを許可しないことがコンフリクト対策
- 奇数にできない場合は調停者を設ける
- arbiterOnly プロパティ設定
- スケールアウトを目的に作られている
- シャーディング
- mongos サーバは mongoconfig コンフィグサーバに接続して保存されたシャーディング情報を追跡する
- 地理空間情報クエリ
- GridFS
- 独自の分散ファイルシステム
- MongoDB の強み
- MongoDB の弱み
- 非正規系
- スキーマレス故のスペル間違え問題
- 設計や管理が手間
第6章 CouchDB
- スケールアップもダウンもできる
- 様々な規模や難しさの問題空間に適している
- JSON と REST ベースの典型的なドキュメント指向データベース
- ウェブとそれに関する膨大な不備・欠陥・障害・問題を念頭に置いて設計されたもの
- 他DBとは比べものにならないほどの堅牢性
- ほとんど接続がなくても平気
- 様々な開発シナリオをサポートしている
- シャットダウンするにはプロセスを殺すしかない
- データが破損することがほとんどない
- ストレージと通信用に JSON を使っている
- 呼出は REST インターフェイス経由
- レプリケーションは一方向または双方向
- データの構造・保護・分散における柔軟性が高い
- 寝心地のいい Futon
- ウェブインターフェイス
- 一時的なビューは開発用途のみ使用すべき
- プロダクション環境ではデザインドキュメントに mapreduce 関数を保存してビューを永続化
- マルチマスター
- コンフリクトの解消
- ドキュメントをマージするのはアプリケーション固有の問題
- CouchDB の強み
- 堅牢で安定した NoSQL DB
- データストレージに分散化の手法が採用されている
- データベースでありAPIである
- of the Web, for the Web
- CouchDB の弱み
Effective Ruby
第5章、メタプログラミング。
正直、理解もそうだが、使いどころも難しい。あとでわからなくなりそう。
こっちを読んで学んだ方が良いかも。
- 作者: Paolo Perrotta,角征典
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/10/10
- メディア: 大型本
- この商品を含むブログを見る
第一版しか読んでないけど。
Refinements については、前田さんの言うとおりになっていればこのようには言われていなかったであろう。
以下はその前田さんによる記事。
carrierwave で新規ファイル保存
ファイルをアップロードするのではなく、例えばサーバ側で rubyXL を用いて新規ファイルを作ってそれを carrierwave の仕組み上で管理したい。
carrierwave 用に mount_uploader した変数に ActionDispatch::Http::UploadedFile を渡せば良いのだろうけど、やり方がわからない。
ActionDispatch::Http::UploadedFile
rubyXL で新規にデータを作った場合はまだファイルになっていない。
StringIOの状態。
そこで、ささたつさんのサイトに答えが。よくこんなのわかるなぁ。すごい。
tempfile を作って、ActionDispatch::Http::UploadedFile インスタンスを渡せばよい。
tempfile を作るときに、carrierwave 側で拡張子で制限を行っている場合は new の際の第一引数配列の二つ目が suffix なので、拡張子を指定すること。