質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

4424閲覧

node.jsにてjsonファイルをデータベースとして使うデメリットを教えてください

Izumo1101

総合スコア49

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2021/01/19 00:44

node.jsを使って小規模なシステムを制作(勉強)しています。その際、データを保存する・呼び出す元をjsonファイルとしており、例えばdatabese.jsonをオブジェクトにして加工、jsonファイルに上書き、というような動きを取っています。

jsonの中の連想配列は、一つのアイテムに100程度の項目、それが50個程度と(計500程度のデータ)くらいが現段階での最大数です。そもそも閉じられた環境で使用することを前提としておりセキュリティに重点を置いていませんが、勉強不足で重点を置けていないとも言えます。

nodeのデータベースで勉強をするとすればmongoDB等がすぐにヒットしますが、敷居が高そうに見えてなかなか挑戦できません。そもそも現在データベースとして使っているjsonファイルが簡単だし慣れているのでなかなか前向きな姿勢になれません。

そこで私が今使っている「jsonファイルをデータベースにしたとき」の脆弱性や課題を教えていただけませんか?またはmongo等のデータベースを使うメリットを教えていただけないでしょうか。
そもそも上記環境では大差ないのであれば無駄な学習コストを避けjsonを使い続けようと思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hentaiman

2021/01/19 00:51

閉じた環境で学習用にひとりで想定通りの利用をする前提での脆弱性や課題とは?
Izumo1101

2021/01/19 01:00

閉じられた環境とは言え、一人で利用するシステムではなく複数の利用者がいます。 そのうえで、「処理データが増えるとjsonでは限界がある」だとか「決定的にセキュリティが低い」だとか「しっかりとしたデータベースを利用すると〇〇のようなメリットがある」だとかをご教示いただければと思っております。
hoshi-takanori

2021/01/19 01:03

複数の利用者がいるなら、同時にアクセスして同時に上書きしたらやばいことになりますね。
hentaiman

2021/01/19 01:06

実際書いてみたコードはどんなんです?それに対しての指摘なら多数の回答者がコメント出来ると思いますが。 ファイルでも正しい処理を行えばデータの保存に利用は出来ます。DBも実体はファイルです。
Izumo1101

2021/01/19 01:10

実際のコードは非常にボリュームがあるので避けますが、jsonファイルをデータベースとして動かす、というシステムは複数作っており、特に問題なく動いています。複数とは言っても100人を超えるような同時アクセスはない程度の規模のシステムばかりなので、同時アクセス同時上書きで問題がおこったことはありません。 基本的にはこの感じで様々な小規模システムを作りたいのですが、jsonファイルをデータベースにしていることが正しいことなのか間違っているのかわからないのです。
hentaiman

2021/01/19 01:20

> 複数とは言っても100人を超えるような同時アクセスはない程度の規模のシステムばかりなので、 このマグレ頼りの状態であればjsonファイル直利用は間違っていると断言出来ますね。利用者も超極小なのでマグレ頼りの部分の処理を追加すればそのままでも良いと思いますよ。
guest

回答1

0

ベストアンサー

具体的な所として、
現状で問題がないのであればそのままでも大丈夫です。

しかし衝突に遭遇して「排他制御」が必要と感じたら、
それを実装する時間を使ってデータベースを勉強して使いましょう。

データベースはファイルの読み書きに特化したソリューションですので、
多くのWebエンジニアに歓迎され、受け入れられています。

仮に貴方がWebサービスを開発・運用しているチームに改めて参入した場合
ほぼ確実に何らかのデータベースは導入済みであるでしょう。
その場合はしかたない、学習することになります。

実際のプロジェクトのコード読めばどうやって利用しているのか読めるので、
意外と一瞬で使えるようになるものです。


まずWeb上で情報を預かる場合の責任についてです。

貴方が仮に恋人や友人とLineで会う約束をしていたとします。
しかし当日待ち合わせ場所に来ない……
よく調べてみたら、Lineのシステムの手違いでその約束が消えてて
相手が知らないまま当日を迎えてしまっていて電話で発覚した。
許せますか?

Web上で情報を預かるということは
「例え無料だとしてもそれなりの責任が伴う」事を意味します。

この辺は「データの価値」をどの程度見積もるか評価・設計をしてください。
Lineは会社が潰れるレベルの価値に設定しているかと思います。
なのでそういう問題が起こらないよう、よく設計を練って堅牢なシステムを築いているはずです。

100人のユーザーが訪れて同時に読み書きを要求して来ても
データが消えない事を保証出来なければならない。
更にWebの利用者は目が肥えているので時間の掛かるサービスはすぐに「使えない」と見切ります。
速度も重要視されます。

こういう世界で闘う事になる可能性は覚悟しておきましょう。


Node.jsはシングルスレッドですので1プロセスで動作させている場合は問題は起こらないでしょう。
見た目は並列処理しているように見えても
イベントループの仕組み上、基本的には1個の関数しか同時に動きません。

なのでfs.writeFileSyncのような
同期処理を使って待たせている場合、
破綻することはないでしょう。

ファイルが肥大化すれば処理速度の面で悩まされる事になるでしょう。
一般的に取られる下記のような手段を採用すると牙を向いて襲いかかってくる事になるでしょう。

  • サーバマシンを複数台に増やす
  • fs.writeFileを使う

ディレクトリやファイルを個別に管理したり、ファイルの書き込みを遅延させたり
アイデア次第で結構頑張れると思いますが、それって目的見失ってませんか?
ファイルの整合性の担保が目的じゃないですよね、元々やりたいことがあったのでは?

ファイルの整合性の担保は、
それ自体を責任取って面倒みてくれるデータベースに任せましょうよって話です。

※セキュリティ絡みはまた別問題です。
マシンが乗っ取られて正規の手段でデータベースにアクセスされて情報を持ち逃げされるようなケースがありえます。
権限とかで縛ってマシン単位でアクセスを禁止すればパスワードなんかは守れたりしますけど……


テキストでファイルを管理する場合
問題はファイルの保存時の衝突くらいでしょうか?
解決策は「排他制御」です。

2000年前後のWebではCGIを使ったテキストチャットや掲示板サイトが多く存在しました。
当時はJSONはなく、CSV等のファイル形式で保管していました。
(JSONは{}[]が第一行目と最終行目に来て包む形になりますから、追記が出来るCSVのがファイル管理のサービスに向いているでしょう)

ファイルの書き込みは基本的に上書き、つまり複数の処理が同時に書き込むと後勝ちです。
なので2つの処理が同時に書き込むと、先に書き込んだ方が消えます。

掲示板のケースで話を進めると複数ユーザーが同時に書き込むと、
先に書き込んだユーザーの発言が消えて、後から発言したユーザ1人の書き込みだけが残ります。
それに対抗するため、プログラマ達は「排他制御」を開発します

  • 一時ファイルを沢山作る
  • ファイルをロックする仕組みを作る
  • 書き込みたい状況でロックされている場合は待つ
  • ファイルを複数に分けて頻繁なロック待ちを避ける

しかし、そういう手段を講じてもデッドロック等の不具合が発生して
そもそも書き込めないんだが?みたいな現象に悩まされ続ける事になります。

単純にデータの書き込みだけの為にクッソ頑張る事になるわけで、
コード量も作業時間もどんどん肥大化してヤバい事になりますね。
(そもそもどうやって複数人が同時に書き込んでも大丈夫かを担保するねん?という事でテストもしにくい)

やりたい事は「複数ユーザの意思疎通」が目的の掲示板制作ですよね。
どうしてこうなった?


ここでデータベースが登場します。
データベースは大まかにこの辺を目的・担当にしています。

  • 超高速
  • 既に多数のデータを内包していてもデータ片の読み書き速度が落ちない
  • ファイルの排他制御

特にRDBMSはデータの担保の面で非常に堅牢です。
手軽に導入できるMySQLやPostgreSQLは多くのWebエンジニアから愛されていますし、
金融業界やNTTデータのような大企業でも愛用されるOracleなんてものもあります。

一般的にNoSQLはRDBMSに多少担保の面で劣るものの、
スケールのしやすさ、複数台に増やして動作させる性能が高かったりして注目を集めています。
MongoDBはRDBMSとNoSQLの同居みたいなバランス感覚が絶妙で、
中々使い勝手が良いみたいな話を聞きます。

とまぁ、データベースを使えば衝突や速度を稼ぐという事を責任とってやってくれますので、
メインの業務ロジックに集中できます。


データを預かる事に疲弊したWebエンジニアがデータベースを使わない理由がない。

Webエンジニア達はデータベースの学習コストを甘んじて受け入れる事になりました。
めでたし。
こんな感じの流れです。

複数のWebエンジニアが協業して、
大きなWebサービスを作り上げるとなれば、
まぁ、何らかのデータベースは使う事になります。

一人でも一度データベースを勉強して扱えるようになっておけば
あっちこっちのプロジェクトで排他制御を書きまくるなんてこともせずに済みます。
学習コストを割く価値は十分あると思います。

投稿2021/01/19 01:24

編集2021/01/19 02:59
miyabi-sun

総合スコア21203

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Izumo1101

2021/01/19 01:33

ご回答ありがとうございます。非常に勉強になりました。結構このようなデータベースの概念というか基本情報?がネット上には少なく難儀しておりました。かなり理解できました。 学生でもプロでもありませんが、なんでしょう社内SE的な、またはボランティアプログラマ的な位置づけです。しかし「例え無料だとしてもそれなりの責任」が刺さりましたし、何より一生この規模で満足はできません。 他の方のコメントにもあるように特に「衝突上書き」に問題があることが分かりました。こんな恐ろし事はありませんね・・・。現状問題は表面化していませんが、こんな欠陥商品のようなシステムは人に提供できないので(無料であれボランティアであれ)、データベースの勉強を開始します。
miyabi-sun

2021/01/19 01:42

なるほどー、表面化しなかった原因はNode.jsはシングルスレッドだからでしょうね。 イベント駆動で並列処理させていたとしても、 一度に実行出来る処理はイベントを達成して発火させた関数1個だけになります。 もし興味があれば「イベントループ」で調査してみてください。 fs.writeFileSync等の同期処理でファイルの読み書きを徹底していれば 「衝突上書き」には悩まされないと思います。 速度面でいつか限界を迎えるでしょうけど。 という訳で、Node.jsだからこその恩恵で欠陥でも急務でも無かったみたいですね。 でもまぁ、この規模で満足出来ないなら、いずれ複数台起動とかやるでしょうから、 データベースは覚えるに越したことはありませんね。 がんばってください!
hentaiman

2021/01/19 01:48

> Node.jsだからこその恩恵で欠陥でも急務でも無かったみたいですね。 そこもシングルでの起動方法しか知らなかったというマグレセーフです
Izumo1101

2021/01/19 04:32

fs.writeFileSyncの処理は期せずしてしっかり行っております。そこで >マグレセーフ もしよろしければ教えてください。マグレというのが ①私の無知で「たまたま」欠陥急務に該当しなかった、というマグレ ②シングルスレッドであっても、コンマ秒単位で「たまたま」同時アクセス・上書きが起きなかった、というマグレ 私の認識では①ですが、②もありえるのでしょうか。シングルスレッド処理なのでファイルへのアクセスを随時行うようしっかり書いてあれば衝突は起きませんよね?だとするとひとまず安心なのですが。
hentaiman

2021/01/19 04:57

欠陥急務の意味が分かりませんが、文字通りたまたまシングルスレッドで動作させる方法しか知らなかったからセーフという事です。 nodejsでプロセス管理など、プロセスを安定稼働させる事を考えていれば辿り着く情報の一部としてクラスター化と言うのがあるけど、たまたまそれを知らなかったからシングルプロセスで動いていたと。 なので、たまたまセーフ。 > ②シングルスレッドであっても、 回答に書かれている通り、ありえ無いです。同時アクセスがあったところで処理待ちするだけです。というか同時アクセスを並列処理してたらnodejsはC10K問題の救世主みたいな扱われ方はしてない
Izumo1101

2021/01/19 05:17

ご回答ありがとうございます。おおむね理解通りで安堵しました。 クラスター化にはご推測のとおりまったくたどり着いていませんがきちんとイメージしておこうと思います。
miyabi-sun

2021/01/19 05:20

ですね。 とりあえず、1プロセスで立ち上げており、 fs.readFileSync→fs.writeFileSyncの間に非同期処理が1つも挟まって居なければ問題は出ないでしょう。 逆にあの情報欲しいよねで非同期処理で他の情報を追加で読みに行くとアウトです。 因みにNode.jsの思想や流儀はイベントループを駆使して 高速な疑似並列でアクセスを捌くWebサーバにあります。 なので、クッソ遅いハードディスクへの読み書きをぼけーっと待ってる 「fs.readFileSync」や「fs.writeFileSync」は相性悪いです。 かといってこれを非同期にすると空中分解するリスクが出てくる、 Promiseやasync/awaitを使ってもイベントループの向こう側に追いやる非同期処理には変わりないのでアウト。 この辺の問題があるので、最終的にはやはりfsで読み書きして扱うのは ゆくゆくはやめていきたいよねって感じの結論になるかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問