開発者向けのMongoDb。 週1

こんばんは、ハブラ。 先週、10genからの「開発者向けMongoDb」コースが開始されました。 レッスンを見たなら、安全に通り抜けることができます。 残りの部分については、ようこそ。



この記事では、研究の最初の週の主要な資料の概要を説明します。 視聴者が関心を示した場合、そのような投稿は毎週の終わりに公開されます。



MongoDBについて簡単に説明し、単純なWebアプリケーションのmongoデータベースとリレーショナルデータベースのデータ構造の違いを比較し、シェルと少しのコードとpythonを使用します。



なぜこの記事ですか? 同様の質問が予想されます。 誰もがコースに登録できなかったわけではなく、誰もが十分な自由時間を持っているわけではなく、話された英語の認識で誰もがうまくいっていません。 さて、グーグルでは、そのような素材は傷つきません。





MongoDbは、JSONドキュメントを格納するための非リレーショナルデータベースです。 Mongoコレクションの抽象インスタンスを考えてみましょう。

{a:3

b:7

fruit:["apple","banana","peach"]}







このドキュメントには、整数キーaおよびbと、配列であるフルーツキーが含まれていることがわかります。 リレーショナルデータベースでは、この動作は不可能です。 このようなデータの表現は、リレーショナルデータベースを操作するときに扱うものよりもコードにはるかに近いことに注意してください。



MongoDbのコレクションは、事前定義されたスキーマに関連付けられていません(スキーマレス)。 たとえば、次のドキュメントは同じコレクションの要素である場合があります。

{a:1,b2}

{a:2,b:4,c:10}







ALTER TABLEを行うために何回歯を磨かなければならなかったかを覚えておいてください。 MongoDbでは、これは過去のものです。



下の曲がりくねった小さな図を見ると、データストレージの世界には、2つの反対の極があることがわかります。 軽快ですが、キー値ストレージ機能(memcachedなど)と非常に機能的なリレーショナルデータベースは劣りますが、パフォーマンスとスケーラビリティに問題があります





MongoDbの基本的なアイデアの1つは、高いパフォーマンスを維持しながら、幅広い機能を提供することです。 もちろん、何かを犠牲にしなければなりません。 そのため、たとえば、Mongoには参加するアナログがありません。2つの異なるコレクションの要素を結合することはできません。 リレーショナルデータベースとの2番目の重要な違いは、トランザクションがないことです。 後者は怖いように聞こえますが、実際には、Mongoでは、リレーショナルデータベースを使用するときにトランザクションが必要な状況では、トランザクションは必要ありません。



言葉から行為へ

続行するには、MongoDbをインストールする必要があります。 ディストリビューションのリポジトリで最新バージョンを見つける可能性があります。そうでない場合、ソースは公式Webサイトで入手できます。 winおよびmac用のバイナリもあります。 32ビットバージョンでは、保存されるデータの量に大きな制限があるため、開発にのみ使用できることに注意してください。 今、私たちにとってこれは重要ではありません。

インストールして実行し、シェルに移動します。



 dirtyhack@dirtyhack-ThinkPad-Edge-E125:~$ mongo MongoDB shell version: 2.0.4 connecting to: test >
      
      







データがない限り、mongoはテストベースを作成し、テストベースを使用します。 最初の要素を入れます。



 > db.users.save({name:"Woody",age:23}); > db.users.find().pretty() { "_id" : ObjectId("508ea7f33cc5578ed9ecbf46"), "name" : "Woody", "age" : 23 } >
      
      





ここには多くの興味深いことがあります。 db.users.save()コマンドを使用して、現在のデータベースのユーザーコレクションにドキュメントを保存する要求を送信しました。 このコレクションは以前は存在していませんでしたが、リクエストに応じて自動的に作成されました。



 > show collections system.indexes users >
      
      





名前と年齢のキーを含む単純なjsonドキュメントをusersコレクションに保存しました。 findコマンドの目的を推測することは難しくありません。1つのドキュメントのみに関心がある場合は、findOne()コマンドを使用する価値があることに注意してください。 pretty()コマンドはロジックに影響を与えません-結果を読み取り可能な形式で表示するだけです-それなしでは、文字列を取得しますが、複雑なオブジェクトを操作する場合は便利ではありません。



より複雑な要素をコレクションに追加し、mongoの無回路性を明確に示します。



 > db.users.save({name:"Bazz",age:23,place_of_birth: {country:"unknown",region:"unknown"},interests:["flying","fighting with evil"]}); > db.users.find({name:"Bazz"}).pretty() { "_id" : ObjectId("508eab333cc5578ed9ecbf47"), "name" : "Bazz", "age" : 23, "place_of_birth" : { "country" : "unknown", "region" : "unknown" }, "interests" : [ "flying", "fighting with evil" ] } >
      
      







追加した2番目のドキュメントは、すでに実際のデータに似ています。 place_of_birth要素とinterests要素の値は、それぞれネストされた辞書ドキュメント(JSONObject)と配列(JSONArray)であることに注意してください。 階層的なネスト-常識により制限され、要素ごとに16メガバイトの制限があります。



ところで、組み込みのJavaScriptインタプリタを使用できます

 > var j=db.users.findOne({name:"Woody"}) > j.age=25 25 > db.users.save(j) > db.users.find({name:"Woody"}).pretty() { "_id" : ObjectId("508ea7f33cc5578ed9ecbf46"), "name" : "Woody", "age" : 25 } >
      
      







おそらく、各要素に識別子_idが割り当てられていることにお気づきでしょう。 少し後で説明しますが、同じコレクション内で一意であることに注意してください。



結果のコレクションは、記事の最後にある小さなアプリケーションで使用します。



設計

単純なWebアプリケーションのデータ構造がMongoとリレーショナルデータベースでどのように見えるかを見てみましょう。



基本的な機能を備えたブログがあると想像してください。 作成者はタグを添付して投稿を公開でき、ユーザーはタグで検索して投稿にコメントを残すことができます。



リレーショナルデータベースを使用する場合、著者、投稿、コメントに関するデータを保存するテーブルが必要です。 また、テーブル間の関係を保存するために追加のテーブルが必要になる可能性が最も高くなります。 もちろん、あなたの現実に応じて、ブログのベースを非正規化することもできますが、基本的な形式では、このようになります。





MongoDbでは、2つのコレクションで同様のデータを保存できます。 エリクソン氏の手書きを願っています。この写真は非常に読みやすいものです。



気付いた場合、著者のコレクションは、ログインを一意の_idとして使用することを提案しています。 はい、識別子を設定できます(もちろん一意性を監視します)。設定されていない場合、システムが自動的に行います。

ご覧のとおり、mongoのデータ構造は非常に単純であり、前述したように、コード内のデータの表現に非常に近いものです。

あなたはおそらくすでに私の注ぎ込みにうんざりしているので、識別子についてもう1つ発言します。

識別子の設定は優先度の高い操作です。 データが実際に保存される前に設定されます。 デフォルトでは、mongoドライバーはデータの保存に関するデータベースからの応答を待機せず、識別子を受信して​​ユーザーに応答を返します。 この動作に慣れていない場合は、セーフモードを使用できますが、パフォーマンスの低下に備えてください。



お母さん、コードを書いてください。



最初の週のレッスンでは、ほとんどのコードはPythonとボトルフレームワークの基本クラスによって提示されました。 次のレッスンでは、ブログのPythonおよびphpのコースプロジェクトで作業し、今のところは、コードからMongoDbを操作することを示す簡単なアプリケーションを作成します。



アクションの基本的な性質のため、抽象化を作成せず、額のすべてを行います(同僚はおそらく病気になったと思うでしょう)。 タオのインターレースの書き方はご存知だと思います。



ユーザーコレクションからユーザーの名前と年齢を表示し、コレクションに新しい要素を追加できる単純なWebアプリケーションを作成します。



Pythonの例を実行するには、pymongoドライバーとボトルフレームワークが必要です。 このサンプルをphpで実行するには、ドライバーも必要です。それをpearから取得できます(mongo.soを拡張機能のリストに追加することを忘れないでください)。



だから例

Python

index.py

 import bottle import pymongo import sys #       #     ,      ,       #    connection=pymongo.Connection("mongodb://localhost",safe=True) #       db=connection.test @bottle.route('/') def home_page(): #    users=db.users.find(); return bottle.template('index',{"users":users}) @bottle.post('/submit') def submit_page(): #      user={'name':bottle.request.forms.get("name"),'age':bottle.request.forms.get("age")} # db.users.insert(user) bottle.redirect('/') bottle.debug() bottle.run(host="localhost",port=8080)
      
      







ビュー/ index.tpl

 <!DOCTYPE html> <html> <head> <title>Hello world</title> </head> <body> <p>   </p><ul> %for user in users: <li>:{{user['name']}} :{{user['age']}}</li> %end </ul> <form action="/submit" method="POST">   <br> <input type="text" name="name" size=40 value=""><br> <input type="text" name="age" size=40 value=""><br> <input type="submit" value="submit"> </form> </body> </html>
      
      







Php

PCPの例にはまれで気取らない



 <? $mongo = new Mongo('localhost'); $database = $mongo -> test; if ($_POST) $database -> users -> insert($_POST); $users = $database -> users -> find(); ?> <!DOCTYPE html> <html> <head> <title>Hello world</title> </head> <body> <?var_dump($users)?> <p>   </p><ul> <?foreach($users as $user){?> <li>:<?=$user['name']?> :<?=$user['age']?></li> <?}?> </ul> <form action="/" method="POST">   <br> <input type="text" name="name" size=40 value=""><br> <input type="text" name="age" size=40 value=""><br> <input type="submit" value="submit"> </form> </body> </html>
      
      







PHPの例に興味がある人への重要な質問。 将来、コードはより複雑になります。YiiまたはZF、または自作のマイクロフレームワークを使用できます-私はあなたの希望を待っています。



それだけです、私が試みた無駄ではないことを願っています。 記事が行商人にアピールする場合は、来週、2週目にレポートを発行します。これはCRUD操作と見なされます。



All Articles