次の2つを比較した場合どちらが速いかについてのご質問だと思います。
- ネットワーク接続のインメモリデータベース
- ローカル接続のストレージ型データベース
回答としては、一概には答えられないので「速い場合と遅い場合がある」という感じになってしまいます。
例えば昔のOracleの記事によると、通常のDBMSはデータがディスク上にある前提で設計されているため、1件処理するのに、どんなにチューニングしてもミリ秒単位かかるのが、インメモリだと数十マイクロ秒まで速くなるそうです。
ただ、ネットワークのデータ転送時間が、インメモリDBの効果を上回るケースが考えられるので、このような単純な比較では一概には言えないと思います。
具体的な例でいえば「複雑な条件で抽出して件数を数える」ような場合は速くなる事が期待できます。理由は複雑な条件の抽出が早くなる点、並び替えや集約、結合などで発生するストレージへの負荷がメモリに置き換わることで高速化される点、出力結果が「件数」なのでデータ転送量が少ない点、等が挙げられます。
逆に「GB単位のデータを1件返す」ような場合は、遅くなると思います。インメモリDBによってデータの読み込みは速くなったとしても、それ以上にネットワークのデータ転送に時間がかかるためです。
インメモリDBはリアルタイムのデータ集計などに向いてます。
よく言われるのは「ダッシュボード」です。ダッシュボードは複数の集計が行われ、かつ実行回数が多く、並列度も高いため、インメモリDBによって高速化、ボトルネック解消が期待できます。
またシステムの設計次第ですが、日次、月次で集計してレポート化するような業務は、リアルタイムで集計できるので、日次や月次の集計用のバッチプログラムが不要になるという利点もあると思います。
DBに詳しいわけではありませんが必要なテーブルをメモリ上に常駐させる設定にすると条件上はインメモリと同じになるのではないかと思います。
そうすると通信分だけ遅くなりそうですね。
ディスクやSSDとインメモリの比較ではインデックスの効き次第で単純比較はできないので速くなる要素はあるけれど定数的にどのくらい、も言えないように思います。
数量化2類で最適化したデータだとインメモリが力を発揮することを期待できるかと。
DB技術者さんの回答を待ちましょう。
僕もメモリテーブルを時々使うので知りたいです。
データであるからには最終的にファイルとしてHDDやSSDに保存されていると言うのはその考えで全く正解です。
データベースは基本的には保存や検索に特化するためにデータを探しやすような構造でファイルを構成するように作られることが多いと思います。
ファイルの単位も単純にテーブルで一つという話ではなくて、良く使うものや過去にどんな検索がされてどんな結果がよく利用されたのか?とか、そういった物をどの程度キャッシュしておくのか?等、各DBの腕の見せ所と言ったところですね。
そこから先は興味があればDBのファイル構成的な形で調べて見ると良いと思います。
DB毎に細かい所でこだわりがあって差が出る部分ですので。
そして社内で使う程度の使い方であれば同じハードウェア上で実行しても構いませんが、多数に対してサービスとして提供するような、例えばホスティング等の用途ですと大抵はハードウェア、もしくは仮想で別で準備して特化させるようにすることが多いですね。
これも安い、高いでも差が出てくる部分ですので。
お尋ねはハードウェアに関してですね。半分YESで半分NOです。
大きなサーバーシステムにおいて、データベースを収める専用システムはDASDと呼ばれます(驚いた事に大昔から今でもDASD(ダスド)と呼ぶのです!)。今だとSSDが中心ですね。ちょっと前まではHDDが中心でした。それらをRAIDという冗長構成x並列構成で組みます。バックアップのためにストリーマーテープも使用されます。
演算システムとは光ファイバーで接続され、RAIDコントローラや電源、I/Oインターフェースなども冗長化されて、大抵がホットプラグ交換式になっています。
少し大きめのデータだと、PCなどの1桁~3桁は早く読み書きできるでしょう。
専用のハードウェア、こういうのがありました。
Oracleのエクサデータです。
残ってるのはコレくらいでしょうか。テラデータです。
なぜか「ペタデータ」は存在しない模様です。
それは「なぜUnix系OSはrootでrm -rf /とタイプするだけで惨劇が起きるような仕様なのでしょうか?」という質問と似ていますね。
- 言語仕様としては一貫性が重要で、記述量が小さいほうが良い。
- 更新系クエリでWHEREをつけ忘れるとアラートを出すCLIの設定は存在する。(MySQLなら
--safe-updates
) - 昔のRDBMSはトランザクションが前提(自動コミットしない)だったので、もしミスが発生したとしてもロールバックできた。
しかし、そもそも本番環境上でCLIから手動でデータを更新するようなコマンドを投げる運用は原理的にこういうミスを避けられないので見直すべきです。
熟練のインフラ屋からすると「走っているプログラムのメモリ状態を手動で書き換えたらクラッシュした」と文句を言ってるようなものに感じられます。
むしろ全レコード削除はいいほうで、UPDATEでWHEREをつけ忘れても同じことが起きますが、こちらのほうがデータの一貫性が失われ、システムが動いている間にインシデントが起きると他のテーブルのデータにまでデータの汚染が波及する可能性があり、もっと悲惨です。
手動でのデータ変更はトラッキングできず、再現性がありません。
これを許した瞬間、「git上にあるコードだけがデータを変更している」ことを信用できなくなり、じわじわと運用コストが上がっていきます。もはやコードを追うだけでは何が起きたのかを再現できなくなるからです。
開発メンバーが2人以上いるプロジェクトでは、手動でのデータ変更は原則禁止とし、
- データマイグレーションはバッチスクリプトを書いてコミットし、通常のコードレビューを経由してからプログラムとして実行する。
- とはいえ実験的作業など高速なイテレーションが必要な場合もあるので、ペアで作業しているときだけ例外を認める、その場合でも作業記録はgitに残す。
という運用がおすすめです。
なぜ手動でのサーバ設定を認めない方向にトレンドがシフトし、Dockerやプロビジョニングツール、 Immutable Infrastructure とか Infrastructure as code (IaC) が流行っているのかを今一度、よく考えてみてください。
手動で変更したシステムの汚染って、最初は小さなシミでも、じわじわと広がって、変更しにくい、アップグレード不可能なシステムになっていくんですよ。
そういう業界に近年まで居た者です。
SSDの代わりになる、というか用途で競合するものは色々開発されてます。でも実用的になるのは未だ先で、出てきてもSSDを置き換えるというよりも SSDの上に立つ、という位置でしょう。 SSDがHDDの上に立ってるように。
ちょっと古いですが、こんな感じです:
この図で、DRAMとNAND/SSDの間に入る新しい記録媒体が開発中です。
理解すべきは、色々な記録媒体が、それらの得意分野があるので当面の間(何十年も)全てが共存します。
”SSDがHDDを置き換える!” と以前叫んでいた人達は判ってない人達でした。SSDは増えるけれど全てのHDDを置き替える事は有り得ません。それは経済的でないからです。パフォーマンスは必要無く只データとして記録されてればいい、という中長期保存データの保管にはSSDは向かないし、コストが合いません。それにはHDDかホントに長期保存アーカイブであれば今でもテープ保存です。
それから世界でのデータ保存必要量は年々加速的に増えており(上のピラミッドの拡大)、世界中の半導体工場をSSD用のNAND生産に充ててもキャパ足りません。つまりそんなHDDの分をも取り込むだけのSSD生産能力自体が世界にありませんし、半導体メーカーはそんな投資しません。
HDD自体も色々変化あります。一つは 2.5インチのディスク(ガラス製)は廃れていきます。これはSSDやNANDにとって代わります。ノートパソコン用のドライブは今では殆どがSSDですね。3.5インチディスク(アルミ製)はこれからも需要ありますが、それを薄いガラス製に置き替える事が検討されてます。3.5インチHDDの箱内に何枚もディスク(現在 Max 10枚入り)入れてドライブ自体のキャパ上げるのに、枚数上げる為にディスクを薄くする必要あるのです(ガラス製の方がアルミより強度があって薄い)。
これが現在Max容量のHDDドライブです(22TB:ディスク当り 2.2TBx10枚)
上のではないですが、一般的なHDD構造を:
それからHDDの記録媒体(ディスク上の磁性膜)にどう書き込むか、も変わってきています。2010年以前は横書き、それ以降は縦書き、最近ではドット式とか熱・電磁波加熱式とか、更に半オーバーラップ書き、など色々と面積当たりの記憶容量を上げる試みがされています。HDDの進化は未だ続きます。
私も Shunichi Arai さんの意見と同じで、最初のステップとしてはExcel感覚の延長で使えるGoogle Sheetsがベストだと思います。
しかし、もう少し踏み込んだ使い方をしたいなら、Airtableが良いと思います。テーブル間のジョインもできるので、本物のデータベースっぽい使い方ができます。
Airtable: Organize anything you can imagine
ちょうど$52MのシリーズBをクローズしたところで、この手のツールのなかでは筆頭格ではないでしょうか。
いきなり自前データベースを構築する時代はもう終わったと思います。
私自身はサーバのインフラからモバイルアプリまで作れるフルスタックエンジニアなので何でもゼロから自分で作れますが、自分の時間がもったいないので内部で使うシステムは自分では作りません。
自分と同じような問題を抱えている人はたくさんいるはずだ、ならばその問題を解決するWebアプリも探せば山のように転がってるはずだ、と考えます。そして全力で自分の要求に近いツールを10個ぐらい探し出してきて、比較します。
自分の開発力・技術力は、本業である自分たちが顧客に提供するサービスの開発に100%費やします。
これは比較優位の議論をしたところと通じるところがありますね。本業に集中するために、100点満点でなくとも、細かいところは妥協してでも外部のツールを選定してきて使うということです。
外部のツールを使うことで、自分の組織の仮想的な規模を一気に拡大できます。
そのツールを開発・メンテする専属チームを格安で雇っているようなものだ(こちらの期待した通りに作ってくれないこともあるけど、それは人を雇っても同じだ)、と考えます。
現代では、良いツールを探し出す嗅覚と、その良し悪しを判断する目利きは、技術力と同等か、それ以上に大切になってきていると思います。
メリットは、(削除フラグの位置づけから明らかですが)アプリケーションでデータを削除しても、そのあと削除したデータを確認できることですね。この動作を論理削除と呼ぶ場合があります。
削除フラグを使用して論理削除を実装した場合の弱点を以下に記載します。
まず、当然ですが、削除フラグで表現できること以外は表現できないことです。具体的には、削除日がわからないこと、削除以外のステータスを管理できないことなどが挙げられます。
これが問題となる場合は、削除フラグの代わりに、
- 削除や無効化に相当するXXX日列を設け、適宜UPDATE(例:社員の退社 → 退社日列をその日でUPDATE)
- ステータス管理用の列を設け、ステータスが変化したらUPDATE(例:社員ステータス列を'退社'にUPDATE、これ以外に'休職'などのステータスが存在)
などの代替方法を用いる必要があるでしょう。
また、通常のデータ(未削除のデータ)と削除済みのデータが1つのテーブルに混在するため、これが問題となるケースがあります。具体的には、一意制約が設定できない(DBMS製品によっては回避策あり)、削除したデータ量が増えるとそれに伴い検索性能が劣化する可能性があるなどです。
これが問題となる場合は、
- 削除対象の行データを別テーブルに移動(SQLとしてはDELETE+INSERT、あまりオススメできない、詳細は後述)
- あきらめて行データをDELETE(オススメできない。詳細は後述)
などの代替方法を用いる必要があるでしょう。
なお、業務システムなどの実世界の振る舞いをシステムに記録するいわゆるSoR的なシステムにおいては、一旦格納した行データをDELETEすること(物理削除)することは原則的にありません(古い取引的なデータを消すぐらい?とはいえ、この場合でもデータベース外部にはデータを保管しておくはず)。
データベース内のデータは相互に関連性を持っていますので、単純に行データをDELETEすると、他の過去のデータとの整合性が取れず、アプリケーションが正常に動作しなくなる恐れがあります。(あるユーザーを削除したら、そのユーザーの過去の行動履歴が閲覧できなくなったら、それは想定される動作でしょうか?)
若干質問からズレますが、システム開発において「削除」という言葉が出たとしても、テーブル設計およびSQL開発においては「無効化」や「不可視化」と捉えて、それを踏まえたテーブル設計およびSQL開発を行うことが大事です。「削除」=「DELETE」と考えるとトラブルの種になります(もちろんDELETEが望ましいケースも場合によってはありますが)。
論点を質問に戻すと、削除フラグの導入だけでシステムの要件に応えられるか?は確認する必要があります。あとで削除日が必要になることはないのか?とか、削除とは実は無効化の一種で、一部の操作ができなくなるだけであり、残りの操作は以前と変わらずできるようにする必要があるのでは?など、削除フラグを導入することで安心するのではなく、システムの要件を慎重に検討してください。
HDDを30本くらい常時使ってますけど,年間3,4本交換してますね.もともと中古で買ったやつも多いのですけれど.SSDは一番早く5年前に購入したやつが飛びました.ハードディスクは故障してもなんとか一部でもデータ救い出せるイメージですけど,SSDは全くアクセスできず,どうにもなりませんでした.私の主観では不具合が起こりにくいのはSSDですが,データ破損した場合は手のうちようがなくバックアップ必須.ということです.HDD 30本はバックアップが主目的です.
長期保存とは10年以上の保存と仮定します。また、保存とあるので、ストレージは取り外して大切に棚などで保管すると仮定します。
この仮定が成り立つならば、HDDの一択で他の記憶媒体にはいろいろと問題があります。
HDD 電源を入れて回さないならば、多くのHDDは20年たっても読めます。接続インタフェースがIDE/SCSIからSATA, SASに変化していますが変換アダプタを入手すれば20年前のモノでも接続できます。ただし、1個だけだと失われる可能性があるので、同じもののコピーを2,3個もつと良いと思います。
SSD 素子の構造上長期間たつと電源を入れなくても記憶内容が壊れます。新しいSSDであればあるほど安全な時間が短くなっていると思います(MLPとか)
TAPE 二つ問題があります。まず、テープの長期保存による伸び縮みで読めなくなる。定期的なテープ間コピーが必要です。次に、その規格が読めるテープデッキが無くなる。1/2インチやカートリッジテープのデッキは最近見たことがありません。
元々それが「データベース」だからです。
最初プログラムとデータは「1つ」でした。
しかし「プログラムが変わるたびにデータも変わる」というのは面倒だ。
「データとプログラム関係ないじゃん、データはデータで使いまわしたい」
ということでプログラムとデータを分けたのがデータベースが生まれた理由です
データをプログラムにくっつけろというのは「先祖返り」ですよ。
バックアップを設計する上で大事な2つの指標があります。
この指標を元にディスカッションしてみるのが良いと思います。
・RPO(Recovery Point Objective)
過去のどの時点のデータまで戻せる必要があるか?です。
RPOを考えることで、バックアップする頻度や対象、保存期間といったものが明確になります。
もし、データベースに書き込まれたデータを完全にリカバリする必要がある場合は、REDOログ・アーカイブログ(Oracle)やバイナリログ(MySQL)といったロールフォワードに必要なデータが障害時に失われないよう考えておく必要があるでしょう。
・RTO(Recovery Time Objective)
どれぐらいの時間でリカバリ作業を終える必要があるか?です。業務を止められる最大限の時間と言い換えても良いでしょう。
RTOによって、バックアップの形式、バックアップの保存場所といったものが明確になります。
形式でいうと、一般的に物理バックアップのほうが、論理バックアップよりリカバリ時間は短くなります(しかり物理バックアップは物理破損に対して役割を果たせないといった側面もあります)。
一般的にバックアップはデータベースのストレージとは別のストレージに保存されることが多いです。同じストレージに置いておくと、故障したときにバックアップも一緒に消えてしまいますからね・・・
しかし、別のストレージからのコピーには(データが大きいと)時間がかかります。
もし、すぐにリカバリする必要があるのであれば、データベースと同じストレージ と 別のストレージ、両方にバックアップを置く必要があるかもしれません。
非常に短いRTOが要求される場合、バックアップからのリカバリでは要件が満たせないかもしれません。そういった場合は、例えば、フラッシュバック機能(Oracle)や遅延させたスレーブ(MySQL)といったバックアップ以外の手段も必要になってきます。
RPO/RTO 以外にも、どのような障害(HW故障なのか、オペミスなのか etc)を想定するのか、リカバリする単位(データベース単位、テーブル単位 etc)なのか、等いろいろな考慮ポイントがあります。
全てのケースに対応できる、完璧なバックアップ方法はありません。常にトレードオフです。自分たちが優先して対応すべきリスクを明確にしてバックアップ計画を立てるのが良いと思います。
授業の雑談で、
「昔、良き時代のプログラムは本物のプログラマしか書かなかった」
「今は素人も書くのでフェイルセイフが言語に必要」
という話をしたことがあります。
そのときの例が「SQLのDELETEはWHEREを書き忘れるとデータが全部消えるんだよ!!!」でした。感動的な仕様かもしれません。
インメモリなDBを単にそのまま使える環境ならたしかにそのほうがいいだろうと思いますね。
しかしインメモリではデータの永続性はそのままでは保てないので、必要ならなんらかのかたちでデータを保存してリカバリする仕組みが必要になりますね。またデータのサイズはメモリのサイズが上限になるので、そこにおさまらないサイズになったときの対処も考えないといけません。
そのへんも込みでうまくいくようなシステムはもちろん構築しようと思えばできるでしょうけど、それよりは単に普通のRDBMSを使うほうが簡単だし単純である、ということが言えるだろうと思います。
ところで、RDBMSのすべてのデータをメモリに乗せるようにするという内容は高速化としてはバカげているなあと思いますね。それができるならたしかにインメモリDBでもいい可能性はあります。現実的にはそんなことはムリです。しかしある特定のクエリに必要なデータ(インデックスなど)が全部メモリに乗るかどうかはかなり性能に関係します。ですからなるべく「いま必要とされている」データが全部メモリに乗るようにする、という話なんではないかなあと思いますよ。
おおよそそのようなシステムは既にあります。
サーバ機材で用いられるシステムで、メモリスロットに取り付けるストレージです。
処理速度はケースバイケースで、何が原因でシステム全体の処理速度が遅いのか、と言うポイント次第なので、ストレージによる影響を殆ど受けないアプリケーションにおいては関係ない話です。 そのようなストレージは、データベースや科学処理用のデータを配置するなどの用途で使われています。 安価な実装としてIntel Optane等もあります。
また、データの消えないメモリというのは既に昔から色々あります。
と言うか、書いたら消せないROMはデータの消えないメモリです。 消せないけど書換も出来ないか、手間がかかります。 自由に書き換えられることを意図するとすれば、電気を流しておけば消えないSRAM、電気以外の形にして素子に記録して電気が無くても消えないMRAM等ありますが、基本的には現用のメモリに比べて容量が小さいか、高いか、遅いか、あるいはその複数なので、メモリを全てそれに置き換えたところでデータを保存する(処理)コストが減っても、製品サイズや材料コストの問題で搭載できるメモリの量が減って性能が低下したり、単純に遅い問題で直接の処理性能は低下します。
さらに、全部をそのようなメモリ(主記憶)にすると、リセットで回復させる、と言うのが面倒になります。 エラーが起きたら電源リセットすれば治る、これは、ストレージとメモリが分離されているので、電源を切ってメモリを全部消して、電源を切っても消えないストレージから読み直して処理する事で、おかしな状態を改善すると言う方法です。 全部が同じメモリになると、これをやるとメモリが消えなければ状況は改善せず、あるいはメモリを全部消す処理を入れると装置は空っぽ! 直るどころか、OSとかの導入からやり直し、データも全部消えてしまいます。 つまり、PCでのSSD初期化操作を行ってしまった状態になり、超めんどくさい!
「データの更新が無ければ」データベースのスケールアウトは簡単です。データの更新が無ければ、誤って古いデータを返す危険性、編集途中のデータを返す危険性はありませんので、データを複数のノードに複製すればスケールアウト完了です(少なくとも概念的には)。
残念ながら( ;-P )、たいていの用途でデータベースにはデータを更新できることが求められますから、誤って古いデータを返してしまうようなこと、編集途中のデータを返してしまうようなことを防ぐ仕組み、端的にいうとデータ整合性を維持する制御の仕組みが必要になります。この仕組みを実装すること、また、この仕組みを高速に動作させることは一般に困難であり、これがデータベースのスケールアウトが難しい理由です。
なお、Oracle Databaseでは、データベースのデータキャッシュでデータ整合性を維持する制御の仕組みを実装しています。仕組みをCache Fusionと呼び、この仕組みを使ったスケールアウト構成をOracle RAC (Oracle Real Application Clusters)と呼んでいます。
https://www.oracle.com/technetwork/jp/articles/yagi-cache-fusion-098964-ja.html
(厳密には分散ロックも必要で、Oracle Databaseでも実装されていますが、説明は
… (もっと読む)分かりやすく、とのことなので、あまり専門用語を使わずに解説してみます。
データベースというのは、全てのデータをまとめて一箇所で管理するというものです。
もし預金データであれば、つねに一つの正しい値になっていなければ困りますよね。
二つのサーバがあって、Aさんの預金が100だったり200だったりと別の値になっていたら困ってしまいます。
そのため、Aさんの預金を書き換えるときは、必ず全てのサーバで同じ値になるように書き換えなければなりません。(これをReplicationと呼びます)
そのため、書き換えに関しては、サーバを増やしても処理能力が増えないのです。それどころか通信や同期処理のために、実際の速度は1台の場合より遅くなります。
じゃあ、AさんとBさんの預金データを別のサーバに置けばいいと考えるかもしれません。(これをPartitioningと呼びます)
しかしこの場合も問題が生じます。Aさんの口座から100円をBさんに振り込む場合、Aさんのデータを-100して、Bさんのデータを+100する処理が必要です。
この途中でどちらかのサーバが故障して停止したりしたらどうなるでしょうか? そのときにデータが壊れないようにするためには、かなり複雑な仕組みが必要になります。
また、全ての預金データから集計したりする場合の処理はどのように処理すれば良いでしょうか。集計時にサーバ間の通信が増えてしまうと、著しく遅く
… (もっと読む)InnoDBストレージエンジンによりトランザクション対応するまでは(してからも?)「疑似リレーショナルデータベース(Pseudo Relational Database)」と揶揄されるMySQLですが、現在最新のMySQL 8.0では、まぁそんなことをいわれることもなく、本当にリレーショナルデータベース(管理)システムといっても、問題ないと思います。
ただ「本当」というのが、コッドの12の規則を満たすかどうか、PRDBMSかTRDBMSか、ということになると、現状みなさんが利用しているRDBMSはすべて本物ではない「疑似(Pseudo)」ということになりますが、原理主義者以外にこの分類は役立たないと思います。
まだ出ていない観点で言いますと、SSDに使用されているNANDフラッシュメモリは、データの上書きができないので、データを上書きするには一度その領域を消してからデータを書く、という面倒なことをしなければなりません。
また、データを記憶するセルには書き込み回数に制限がありますから、SSDなどのフラッシュメモリデバイスでは、ユーザーから見える容量以上の領域を準備し、順繰りに使いまわしながら一つのセル当たりの書き換え回数が少なくなるように頑張ります。
そのため、何も考えずにNANDフラッシュメモリにじかにデータを読み書きすると、あほみたいに遅くて使い物になりません。そもそも消去してから書かないといけませんし、上記の使いまわし領域にデータを退避する状態になればさらに時間がかかるわけです。
これを改善するために、SSDなどでは大容量のRAMをキャッシュやバッファとして使っています。ユーザーから見たらこのキャッシュに普段は読み書きしていて、実際のNANDフラッシュメモリへの更新は、暇な時にやる、というイメージです。
ですから、SSDの壊れた状況によって、例えば使いまわしの処理の最中に壊れたりすると、データを移動させていた作業が中途半端になってデータの整合性がとりづらくなったりします。また、RAMキャッシュにたまっていた重要な管理領域の更新情報等も消失します。そういった事が、SSDのサルベージを難しくする要因です。
とはいえ、SSDの信頼性も年々上がっては来ていますし、HDDだってダメな時はダメですから、運次第なのですが、結局はバックアップに勝るものはない、というところかと思います。SSDにバックアップしていたら何にもなりませんが(笑)。
インメモリDBはデータをただメインメモリーに乗せるわけではありません。
圧縮してメインメモリに載せます。インデックスのさらにインデックスのような工夫です。
だから、読むのがメチャ速い。その反面、ACIDが苦手です。
ディスクを従にするなら、永続化をそのぶん犠牲にせねばなりません。
RDBMSのキャッシュはインメモリーですが、大事なのは圧縮よりも選択です。
データの一部をどう選ぶかが最大のポイントです。
そのため全部キャッシュに乗せると意味がない。効率の悪いインメモリDBになります。
「インメモリDBはACIDが苦手」の補足です。
「そんなDBに意味があるの?」と思うかも知れませんが、意味はあります。
たとえば参照オンリーのBI用途だったり(データはバッチ的に準備します)
高負荷だとACIDを保証できないよと注意喚起したり(デモやPoC用途なら速くて便利)
お金で解決したり(ERPを買わなくても、単独でDBMSとして使えます)
https://www.sap.com/japan/products/technology-platform/hana/what-is-sap-hana.htmlMySQLだったと思いますが、そういう事例は聞いたことがありますよ。それだけが理由ではないと思いますが、RDSだと高いから自前で運用することにしたと言っていました。
パフォーマンスを発揮するためのRDBMSの初期設定は結構大変で、MySQLならMySQLの割と深いところの知識が必要になります。RDSを使えばかなり楽になるバックアップ、パフォーマンスおよび死活監視、障害発生やパッチ適用、バージョンアップのためのメンテナンス構成などを考えると、RDSが一概に割高とも言えないんですよね。
RDS任せきりであれば、RDBMSまあまあ詳しいレベルの開発者だけで保守できますが、EC2で運用となると実際に運用経験のあるインフラエンジニアかDBAクラスの人を雇わないと難しいんじゃないかと思うんですよね。がんばって勉強するといっても、保守に関わる問題を事前に回避しておくのって、経験がないと難しいことが多いので。
これはあくまで想像ですが、EC2で構築したそのスタートアップはその時点でも結構成長していたので、インフラエンジニアがすでにいたか雇うかしたんじゃないかと思います。自社のエンジニアに自前運用の能力が十分あり、体制も備わっていて(一人しか対応できないと障害が起きたとき困ります)、RDSのランニングコストよりも自前運用の方が低コストだと判断したんでしょう。
特に初期のスタートアップは開発者以外を雇う余裕はほとんどないことが多く、ひたすら機能実装のサイクルを回すこと(と資金調達、営業をすること)に注力します。RDSのようなマネージドサービスを利用すれば、保守に関するノウハウも労力もかなりアウトソース出来るので、よほどコストアップしない限りは使った方が安上がりです。
この分野でサーバーという言葉には2つの意味があります。1つはコンピューターのHWのことであり、もう1つはプログラムのことです。
Webサーバーとデータベース(DB)サーバーは基本的には別のプログラムです。そして同じコンピューター上で起動してもいいですし、異なるコンピューター上で動いてもいいです。
また、大量のリクエストに対処するために同じWebサーバーやDBサーバーのプログラムを複数のコンピューター上で同時に動かすということもよくあります。Webサーバーは基本的にはステートレスなので単純に同じプログラムを各コンピューター上で独立に起動すればいいですが、DBサーバーは同期を取る必要があるので複数のコンピューター上で協調的に動作させる必要があります。その方法自体はMySQLやMongoDBなどでそれぞれ独自の方式があります。
初学者なら何冊か読んでみましょう。
その2冊を両方買って、読み比べるのをお勧めします。
RDBというかSQLは問い合わせ言語で、ユーザーに対して警告や注意喚起を与えることができません。
クライアントツールにはWHERE句がないDELETEに強めの警告を与えるような工夫がありますよ。
あと、車の運転と同じで、うっかり防止って、別の事故の要因になるので難しいですわ。
マーケターでデータ操作ができる人に解放するなら、毎晩バッチでデータベースを複製して、システムとは隔離した安全な環境を作って、データの更新ができないアカウントで操作させるなどすれば良いと思いますよ。
リレーショナルデータベースを前提に回答します。主キーとは、リレーショナルモデルのテーブルにおいて、テーブルに格納された行を一意に識別する識別子です。以下に主キーが重要な理由を列挙します。
- リレーショナルモデルには主キーが事実上必須であるため : リレーショナルモデルのテーブルには行を格納しますが、行の格納順序は一般に不定であり、行を特定する識別子は自動的に付与されません。
この状態では、一般に行(データ)を特定できませんから、データベースの意味がありません。 - データモデルの分析において、データを一意に特定する識別子を認知することが重要であるため:データベースはデータを管理するために使用します。一般に、データを管理するにはデータを一意に特定できる必要があります。新しいシステムを構築するときなど、実世界をデータモデルに落とし込む分析作業を行いますが、その分析作業において、データを一意に特定する識別子を見つけること/新しく識別子を付与することは、データモデルを作成する上で極めて重要な作業です。
- アプリケーションからSQLを用いてデータ(行)を取得する際に、主キーを指定する必要があるため:アプリケーションがSQLを用いてデータベースから1件のデータ(行)を取得する場合、通常WHERE句に<主キー列>=<値>という条件を指定します。このため、主キーがどの列に設定されているかを理解すること、テーブルのどの列に主キーを設定するかは重要です。
なお、フレームワークによっては主キーが数値列でなければならないなどの制約が課せられる場合もあります。
回答になるかわかりませんが私の場合は「必要な容量のドライブに交換する」が一択です
過去20年間そのようにしていました
データーベースマネジメントシステム自体、さまざまな側面がある総体なので、この理由もいくつかの方向から論じることができます。
- プログラム言語ごとに、安全性にかかわる機能や、並列処理にかかわる処理に差異がある。たとえばある言語では非同期処理をasyncで書く、ある言語ではマルチスレッドで書く、といったときに、複数のプログラムから構成される分散システムにおける、データ安全性保証のポリシーを一貫させることができなくなる。
- 大量データ、高速処理、アイソレーションレベル、永続性、並列処理、排他制御、分散トランザクション、クラスタリングにシャーディング、マルチAZ構成に可視性やアクセス権限制御、監査、運用性(バックアップ製品の完備やクラッシュリカバリ)など、1プログラミング言語実行系の実装でカバーしきれないほど、単独プログラミング言語が負うには過大すぎる責務を持った存在であること。
- 多種多様な別プロセスが関連する分散システムの構成要素であるためにDBプロセスはアプリケーションプロセスから分離させ、1言語に縛られない存在とすること。
- 複数のプロセスからDBMSがアクセスされる構図において、アプリケーション開発言語とは独立の言語でスキーマ定義やクエリ、ミューテーションの定義を行なう「言語独立のデータベース処理」という層が「プロセスごとに違う言語で書ける」ことを保証している。C言語プロセスから呼び出すテーブル定義はCで書き、型もCの型に従い、Pythonから呼び出すテーブル定義はPythonで書き、という状況を避ける。どの言語でもない中立な表現により、言語選択の自由度が高まる。
- プログラミング言語の表現や実行モデルと、リレーショナルデータの表現に乖離があること(インピーダンスミスマッチ)。たとえば、DBMSの速度や格納効率は、「同種のレコードは稠密に並べる」ことでインデックスで二分探索したりの効率を稼いでいるが汎用プログラミング言語におけるデータ配置戦略で一般にそういう実装をすると効率がわるい。
そんなこんなもありで別プロセスにするのが主流です。もっとも個別に見ていくと、それぞれ別解がある場合もあって、たとえばライブラリとしてアプリに組み込むSqliteなどの組込みDBも別にめずらしくはないし、並列処理と排他制御のみを実現するためにはソフトウェアトランザクショナルメモリ
とかもあり、インピーダンスミスマッチを減らしたオブジェクト指向DBなどもあります(ありました)。脚注
リレーショナルデータベースが「現時点でのデータ」しか持たないのは関係代数という数学に基づく論理の上に実装されていること、が大きな要因だと思います。関係代数的に過去の状態は必要ありません。空想の話になりますが、ベースとなる論理に差分記録が必須であったなら、差分記録を行うデータベースが一般的だったかも知れません。
この回答だと身も蓋もないので、近いモノが無いか、というとそうでもありません。
差分を保存する事と過去の状態を保存する事は、論理的には、ほぼイコールと考えられます。内部的に過去の状態を保存しているデータベースはあります。MVCC(Multi Version Concurrency Control)と呼ばれ、トランザクション実装に利用されています。オープンソースデータベースではPostgreSQLやSQLiteがMVCCを利用しています。
MVCCアーキテクチャーのデータベースの場合、過去の状態を維持することはそれほど難しくありません。しかし、スペース効率やパフォーマンスを考慮すると全てのデータ状態を保存することはあまり現実的ではありません。
ISO 27000が定義する情報セキュリティの主要要素の一つに「否認防止/責任追跡性」があります。情報セキュリティ対策の観点から過去の操作が追跡できて便利なのでは?と思われたのだと思います。しかし、監査目的の場合はデータ状態(値)の推移が判ってもあまり意味がありません。「否認防止/責任追跡性」を保障する為には「誰が行った操作か?」も記録する必要があります。
リレーショナルデータベースは複数サーバーを利用してスケールアウトすることが難しいシステムでもあります。「誰が行った操作か?」もデータベース状態として記録すると更に遅くなります。
リソース的な問題以外にも仕様的問題もあります。データベースアプリケーションの多くはデーベースユーザーとアプリケーションユーザーは1対1の関係にありません。このためデータベース操作を行ったデータベースユーザーを記録しても意味がないアプリケーションが大半です。「ユーザー」という概念自体がないSQLiteのようなデータベースもあります。
「あれば便利かも」と思う人は居ても、リソース的制約/仕様的制約から実際に実装する意味がないと判断する人がほとんどだと思います。
リレーショナルデータベース以外なら岡部 健 (Ken Okabe)さんの回答 の通り実用的に使われているシステムもあります。リレーショナルデータベースでなければ差分を記録して操作を記録するデータベースを構築することは現実的です。グラフデータベースやKVSデータベースなどに実装すると意外な用途/需要があるかも知れません。
最後にタイムシリーズデータベース(Time series database - Wikipedia)と呼ばれるデータベースもあります。これは時間を軸としたデータを取り扱う為のデータベースシステムです。もしかすると質問の背後にある「操作を追跡したい」とする用途に適合するデータベースかも知れません。
0 件のコメント:
コメントを投稿