使用socket io和rethinkdb构建一个聊天应用程序

A lot of tutorials can be found that teach you how to build a chat app with Socket.io. However, have you ever wondered how to best persist those chat messages?

可以找到很多教程,它们教您如何使用Socket.io构建聊天应用程序。 但是,您是否曾经想过如何最好地保留这些聊天消息?

Enter RethinkDB, a realtime schema-less database. You can store and handle documents easily, just like in MongoDB, but it has reactivity built into it. That means you can subscribe to queries and get notified when data changes, making it the perfect choice when it comes to storing chat messages.

输入RethinkDB,这是一个实时的无模式数据库。 您可以像在MongoDB中一样轻松地存储和处理文档,但是它内置了React性。 这意味着您可以订阅查询并在数据更改时得到通知,这使其成为存储聊天消息的理想选择。

In this article, you will learn how to create a simple chat app with Socket.io and persist the messages in RethinkDB. To show the usefulness of a reactive database, we will also add a simple bot that reacts when you address it.

在本文中,您将学习如何使用Socket.io创建一个简单的聊天应用程序并将消息保留在RethinkDB中。 为了展示React型数据库的有用性,我们还将添加一个简单的机器人,当您处理它时会做出React。

You can also try the running app, or check out the code repository.

您也可以尝试运行的应用程序 ,或签出代码存储库

应用程序设置 (Application setup)

We will build a Node.js app, so you need to have node and npm installed. If you want to deploy your app to Heroku, you will also need a Heroku account, as well having their CLI installed. To run your app locally, you need to install and run a RethinkDB instance.

我们将构建一个Node.js应用程序,因此您需要安装nodenpm 。 如果要将应用程序部署到Heroku,则还需要一个Heroku帐户 ,并安装其CLI 。 要在本地运行您的应用,您需要安装并运行RethinkDB实例

To create the application, run the following in a terminal.

要创建该应用程序,请在终端中运行以下命令。

$ mkdir rethink-chat && cd rethink-chat
$ npm init -y
$ npm install rethinkdb express morgan http socket.io lorem-ipsum

This will initialize a Node.js app and install all required dependencies.

这将初始化Node.js应用并安装所有必需的依赖项。

准备一个Heroku应用 (Prepare a Heroku app)

In order to deploy the application to Heroku we need to create a Heroku app:

为了将应用程序部署到Heroku,我们需要创建一个Heroku应用程序:

$ git init
$ heroku create

We will also need a RethinkDB instance to store and subscribe to the chat messages sent between users. You can do this via the RethinkDB Cloud add-on as follows:

我们还将需要一个RethinkDB实例来存储和订阅用户之间发送的聊天消息。 您可以通过RethinkDB Cloud插件执行以下操作:

$ heroku addons:create rethinkdb

The RethinkDB Cloud add-on is currently in alpha. Request an invite for your Heroku account email.

RethinkDB Cloud附加组件当前处于Alpha状态。 请求邀请您的Heroku帐户电子邮件

构建服务器 (Building the server)

To begin, let us set up the Node.js server. Create an index.js file and add the following server skeleton. We use an Express.js server to handle http traffic and Socket.io to handle WebSocket connections with clients.

首先,让我们设置Node.js服务器。 创建一个index.js文件,并添加以下服务器框架。 我们使用Express.js服务器处理http流量,并使用Socket.io处理与客户端的WebSocket连接。

// index.js


// Setup Express and Socket.io servers
var express = require("express");
const app = express();
var http = require("http").createServer(app);
var io = require("socket.io")(http);


// Logging middleware
var morgan = require("morgan");
app.use(morgan("combined"));


// Serve frontend
app.use(express.static("public"));


// Keep track of room subscriptions in RethinkDB
const watchedRooms = {};


// Lazy RethinkDB connection
// ...


// Route to access a room
// ...


// Socket.io (listen for new messages in any room)
// ...


// HTTP server (start listening)
const listenPort = process.env.PORT || "3000";
http.listen(listenPort, () => {
  console.log("listening on *:" + listenPort);
});

This skeleton serves a static frontend from the public folder. We will create the frontend code later. In addition our server needs to do three things:

这个骨架供应来自静态前端public文件夹。 稍后我们将创建前端代码。 另外,我们的服务器需要做三件事:

  1. Handle connections to the RethinkDB database

    处理与RethinkDB数据库的连接
  2. Create an Express.js route that will give a user access to the chat room

    创建一个Express.js路由,该路由将使用户能够访问聊天室
  3. Configure the Socket.io server to listen to incoming chat messages

    配置Socket.io服务器以侦听传入的聊天消息

RethinkDB连接 (RethinkDB connection)

We manage our RethinkDB connection lazily, i.e., we only create the (re-)connection when it is actually needed. The connection parameters are parsed from environment variables, or the defaults are used.

我们懒惰地管理我们的RethinkDB连接,即,仅在实际需要时才创建(重新)连接。 连接参数是从环境变量解析的,或者使用默认值。

// index.js
// ...


// Lazy RethinkDB connection
var r = require("rethinkdb");
let rdbConn = null;
const rdbConnect = async function () {
  try {
    const conn = await r.connect({
      host: process.env.RETHINKDB_HOST || "localhost",
      port: process.env.RETHINKDB_PORT || 28015,
      username: process.env.RETHINKDB_USERNAME || "admin",
      password: process.env.RETHINKDB_PASSWORD || "",
      db: process.env.RETHINKDB_NAME || "test",
    });


    // Handle close
    conn.on("close", function (e) {
      console.log("RDB connection closed: ", e);
      rdbConn = null;
    });


    console.log("Connected to RethinkDB");
    rdbConn = conn;
    return conn;
  } catch (err) {
    throw err;
  }
};
const getRethinkDB = async function () {
  if (rdbConn != null) {
    return rdbConn;
  }
  return await rdbConnect();
};

On Heroku, the RethinkDB Cloud add-on will set the environment variables. For a locally running instance of RethinkDB, the defaults should work.

在Heroku上,RethinkDB Cloud插件将设置环境变量。 对于本地运行的RethinkDB实例,默认值应该起作用。

前往检修室的路线 (Route to access room)

As mentioned earlier, the frontend is static. We do however need a route to access a chat room. The route will return the message history of a given room, as well as a WebSocket handle to access it.

如前所述,前端是静态的。 但是,我们确实需要进入聊天室的路线。 该路由将返回给定房间的消息历史记录,以及用于访问它的WebSocket句柄。

// index.js
// ...


// Route to access a room
app.get("/chats/:room", async (req, res) => {
  const conn = await getRethinkDB();


  const room = req.params.room;
  let query = r.table("chats").filter({ roomId: room });


  // Subscribe to new messages
  if (!watchedRooms[room]) {
    query.changes().run(conn, (err, cursor) => {
      if (err) throw err;
      cursor.each((err, row) => {
        if (row.new_val) {
          // Got a new message, send it via Socket.io
          io.emit(room, row.new_val);
        }
      });
    });
    watchedRooms[room] = true;
  }


  // Return message history & Socket.io handle to get new messages
  let orderedQuery = query.orderBy(r.desc("ts"));
  orderedQuery.run(conn, (err, cursor) => {
    if (err) throw err;
    cursor.toArray((err, result) => {
      if (err) throw err;
      res.json({
        data: result,
        handle: room,
      });
    });
  });
});

This is where the RethinkDB magic happens. The first time this route is called for a particular room (when the first person joins), we subscribe to a RethinkDB query to get notified whenever a new chat message is available. We send new chat messages via Socket.io to any clients listening for the room’s handle.

这就是RethinkDB魔术发生的地方。 第一次为特定房间(当第一个人加入时)调用此路由,我们订阅RethinkDB查询以在有新的聊天消息可用时得到通知。 我们通过Socket.io将新的聊天消息发送给所有监听房间句柄的客户端。

收听新消息 (Listen for new messages)

The last puzzle piece of the server is to listen and save all incoming chat messages. Whenever a message comes in via the chats handle of the Socket.io connection, we save it to the chats table in RethinkDB.

服务器的最后一个难题是监听并保存所有传入的聊天消息。 每当通过Socket.io连接的chats句柄传入消息时,我们会将其保存到RethinkDB中的chats表中。

// index.js
// ...


// Socket.io (listen for new messages in any room)
io.on("connection", (socket) => {
  socket.on("chats", async (msg) => {
    const conn = await getRethinkDB();
    r.table("chats")
      .insert(Object.assign(msg, { ts: Date.now() }))
      .run(conn, function (err, res) {
        if (err) throw err;
      });
  });
});

Saving a value in the chats table will trigger the subscription we added above, causing the message to be sent to all clients listening to this room, including the sender of the message.

chats表中保存一个值将触发我们在上面添加的订阅,从而导致该消息被发送给所有监听此会议室的客户端,包括该消息的发送者。

前端 (Frontend)

For our frontend we will use an embedded Vue.js app. This makes the frontend simple, but gives us access to all of Vue’s awesome features. The frontend consists of a layout file as well as JavaScript and CSS assets.

对于我们的前端,我们将使用嵌入式Vue.js应用程序。 这使前端变得简单,但使我们能够使用Vue的所有出色功能。 前端由布局文件以及JavaScript和CSS资产组成。

  • The layout file only serves as a mount point for the Vue app in addition to importing the dependencies.

    布局文件除了导入依赖项外,仅用作Vue应用程序的安装点。
<!-- public/index.html -->


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>RethinkDB Chat with SocketIO</title>
    <link href="/css/main.css" rel="stylesheet" />
  </head>


  <body>
    <div id="app">
      <router-view></router-view>
    </div>
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script src="/js/app.js" language="javascript"></script>
  </body>
</html>
  • The CSS asset contains the styling of the frontend. It is long, not very interesting, and can be found here.

    CSS资产包含前端的样式。 它很长,不是很有趣,可以在这里找到。

  • The JavaScript asset app.js contains the actual Vue app.

    JavaScript资产app.js包含实际的Vue应用程序。

// public/js/app.js


// Create random username
let username = Math.random().toString(36).substring(2, 8);


// Setup Socket.io
var socket = io();


// Main view
// ...


// Room view, holds a chat room component
// ...


// Chat room component
// ...


// Setup routes
const router = new VueRouter({
  routes: [
    { path: "/", component: MainView },
    { path: "/:roomId", name: "room", component: RoomView },
  ],
});


// Mount Vue app
var app = new Vue({
  router,
}).$mount("#app");

The Vue app contains two routes. The/ path points to the main view and the /:roomId path points to the room view.

Vue应用程序包含两条路线。 /路径指向主视图, /:roomId路径指向房间视图。

主视图 (Main view)

The main view lets you choose a username (default is a random string) and allows you to join a room with a given name.

主视图允许您选择用户名(默认为随机字符串),并允许您使用给定名称加入房间。

// public/js/app.js
// ...


// Main view
const MainView = Vue.component("main-view", {
  data() {
    return {
      room: "lobby",
      user: username,
    };
  },
  methods: {
    gotoRoom() {
      username = this.user;
      this.$router.push({ name: "room", params: { roomId: this.room } });
    },
  },
  template: `
<div class="main">
    <form class="main" v-on:submit.prevent="gotoRoom">
    <label>Username: <input v-model="user" type="text" /></label>
    <label>Room: <input v-model="room" type="text" /></label>
    <button>Join</button>
    </form>
</div>
    `,
});

Whenever you join a room, the Vue router will load the chat room view.

无论何时加入会议室,Vue路由器都会加载聊天室视图。

聊天室 (Chat room)

The chat room, a room view containing a chat room component. makes a request to the Express route to join the given room when it is created. It also registers a Socket.io handler that listens for incoming chat messages and adds them to the list of messages.

聊天室,包含聊天室组件的房间视图。 创建指定房间时,它会向Express路由发出请求以加入该房间。 它还注册一个Socket.io处理程序,该处理程序侦听传入的聊天消息并将其添加到消息列表中。

The chat room allows the user to type and send a message which will then be sent to the server via the WebSocket handled by Socket.io.

聊天室允许用户键入并发送一条消息,然后该消息将通过Socket.io处理的WebSocket发送到服务器。

// public/js/app.js
// ...


// Room view, holds a chat room component
const RoomView = Vue.component("room-view", {
  template: `<chat-room :roomId="$route.params.roomId"/>`,
});


// Chat room component
const ChatRoom = Vue.component("chat-room", {
  props: ["roomId"],
  data() {
    return {
      chats: [],
      message: "",
      username: username,
      handle: null,
    };
  },
  async created() {
    const url = new URL(document.location.protocol + "//" + document.location.host + "/chats/" + this.roomId);
    const chatsResp = await fetch(url);
    const { data, handle } = await chatsResp.json();
    this.chats = data;
    this.handle = handle;
    socket.on(this.handle, (msg) => {
      this.chats.unshift(msg);
    });
  },
  beforeDestroy() {
    socket.off(this.handle);
  },
  methods: {
    sendMessage() {
      socket.emit("chats", {
        msg: this.message,
        user: this.username,
        roomId: this.roomId,
      });
      this.message = "";
    },
  },
  template: `
<div class="chatroom">
    <ul id="chatlog">
        <li v-for="chat in chats">
            <span class="timestamp">
                {{ new Date(chat.ts).toLocaleString(undefined, {dateStyle: 'short', timeStyle: 'short'}) }}
            </span>
            <span class="user">{{ chat.user }}:</span>
            <span class="msg">{{ chat.msg }}</span>
        </li>
    </ul>
    <label id="username">Username:
        {{ username }}
    </label>
    <form v-on:submit.prevent="sendMessage">
        <input v-model="message" autocomplete="off" />
        <button>Send</button>
    </form>
</div>
    `,
});

Now we have a working server and frontend. The last thing we need is to make sure the chats table actually exists in the RethinkDB database when we run the app.

现在我们有一个工作的服务器和前端。 我们需要做的最后一件事是在运行应用程序时确保chats表确实存在于RethinkDB数据库中。

数据库迁移 (Database migration)

The app does not work without a chats table. We thus need a database migration that adds the table.

没有chats表,该应用程序将无法运行。 因此,我们需要添加表的数据库迁移。

// migrate.js


var r = require("rethinkdb");


r.connect(
  {
    host: process.env.RETHINKDB_HOST || "localhost",
    port: process.env.RETHINKDB_PORT || 28015,
    username: process.env.RETHINKDB_USERNAME || "admin",
    password: process.env.RETHINKDB_PASSWORD || "",
    db: process.env.RETHINKDB_NAME || "test",
  },
  function (err, conn) {
    if (err) throw err;


    r.tableList().run(conn, (err, cursor) => {
      if (err) throw err;
      cursor.toArray((err, tables) => {
        if (err) throw err;


        // Check if table exists
        if (!tables.includes("chats")) {
          // Table missing --> create
          console.log("Creating chats table");
          r.tableCreate("chats").run(conn, (err, _) => {
            if (err) throw err;
            console.log("Creating chats table -- done");
            conn.close();
          });
        } else {
          // Table exists --> exit
          conn.close();
        }
      });
    });
  },
);

This migration checks if the chats table exists, and if it is missing, it creates it.

此迁移检查chats表是否存在,如果缺少,则创建它。

一个简单的聊天机器人 (A simple chat bot)

As we saw, one of RethinkDBs great features is the baked in reactivity that allows us to subscribe to queries. This feature also comes in handy when creating a simple chat bot. The bot simply needs to subscribe to changes in the chats table and react to them whenever appropriate.

正如我们所看到的,RethinkDB的强大功能之一是响应式烘焙,它使我们能够订阅查询。 创建简单的聊天机器人时,此功能也很方便。 机器人只需要订阅chats表中的更改,并在适当的时候对它们做出React。

Our Lorem bot will reply with a random section of Lorem Ipsum whenever prompted with @lorem. The bot subscribes to the chats table and scans the beginning of the message. If it starts with@lorem, it will reply with a message in the same room.

每当有@lorem提示时,我们的Lorem机器人将随机回复Lorem Ipsum部分。 该漫游器订阅chats表并扫描消息的开头。 如果以@lorem ,它将在同一房间回复并显示一条消息。

// lorem-bot.js


const LoremIpsum = require("lorem-ipsum").LoremIpsum;
const lorem = new LoremIpsum({
  sentencesPerParagraph: {
    max: 8,
    min: 4,
  },
  wordsPerSentence: {
    max: 16,
    min: 4,
  },
});


// Run Lorem bot
const runBot = function (conn) {
  console.log("Lorem bot started");
  r.table("chats")
    .changes()
    .run(conn, (err, cursor) => {
      if (err) throw err;
      cursor.each((err, row) => {
        const msg = row.new_val.msg.trim().split(/\s+/);
        // Is the message directed at me?
        if (msg[0] === "@lorem") {
          let num = 10;
          if (msg.length >= 1) {
            num = parseInt(msg[1]) || num;
          }
          r.table("chats")
            .insert({
              user: "lorem",
              msg: lorem.generateWords(num),
              roomId: row.new_val.roomId,
              ts: Date.now(),
            })
            .run(conn, function (err, res) {
              if (err) throw err;
            });
        }
      });
    });
};


// Connect to RethinkDB
const r = require("rethinkdb");
const rdbConnect = async function () {
  try {
    const conn = await r.connect({
      host: process.env.RETHINKDB_HOST || "localhost",
      port: process.env.RETHINKDB_PORT || 28015,
      username: process.env.RETHINKDB_USERNAME || "admin",
      password: process.env.RETHINKDB_PASSWORD || "",
      db: process.env.RETHINKDB_NAME || "test",
    });


    // Handle close
    conn.on("close", function (e) {
      console.log("RDB connection closed: ", e);
      setTimeout(rdbConnect, 10 * 1000); // reconnect in 10s
    });


    // Start the lorem bot
    runBot(conn);
  } catch (err) {
    throw err;
  }
};
rdbConnect();

将应用程序部署到Heroku (Deploy the application to Heroku)

To deploy our working application and bot to Heroku we need to create a Procfile. This file basically tells Heroku what processes to run.

要将我们的工作应用程序和机器人部署到Heroku,我们需要创建一个Procfile 。 该文件基本上告诉Heroku要运行哪些进程。

// Procfilerelease: node migrate.js
web: node index.js
lorem-bot: node lorem-bot.js

The release and web processes are recognized by Heroku as the command to run upon release and the main web app respectively. The lorem-bot process is just a worker process that could have any name.

Heroku将releaseweb进程识别为分别在发行版和主Web应用程序上运行的命令。 lorem-bot进程只是一个工作进程,可以使用任何名称。

Deploy the app to Heroku with

使用将应用程序部署到Heroku

$ echo "node_modules/" > .gitignore
$ git add .
$ git commit -m 'Working rethink-chat app'
$ git push heroku master

You will need to manually enable the lorem-bot process in your Heroku app. You can do so on the Resources tab.

您将需要在Heroku应用中手动启用lorem-bot进程。 您可以在“资源”选项卡上执行此操作。

结论 (Conclusion)

In less than 15 minutes we managed to create and deploy a chat application with a simple bot. This shows the power and ease of use of RethinkDB. The ability to subscribe to queries makes it easy to build a reactive app and a natural fit to interact with Socket.io. Further, Heroku makes deployment a breeze, and with the RethinkDB Cloud add-on you will never have to do the tedious work of managing a database server yourself.

在不到15分钟的时间内,我们设法用一个简单的机器人创建并部署了一个聊天应用程序。 这显示了RethinkDB的强大功能和易用性。 订阅查询的功能使构建响应式应用程序变得容易,并且自然可以与Socket.io进行交互。 而且,Heroku使部署变得轻而易举,并且有了RethinkDB Cloud附加组件,您将不必亲自进行管理数据库服务器的繁琐工作。

Originally published at https://www.rethinkdb.cloud on August 17, 2020.

最初于 2020年8月17日 发布在 https://www.rethinkdb.cloud

翻译自: https://medium.com/swlh/build-a-chat-app-with-socket-io-and-rethinkdb-df10c5c27bb1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RethinkDB 设计用来存储 JSON 文档的分布式数据库,可通过简单操作实现多机分布式存储。支持表的联合和分组查询。什么是RethinkDB?RethinkDB 是从头打造的第一个开源、可扩展的JSON数据库,用于搭建实时网页。全新的访问模型颠覆了传统的数据库结构:开发者只需告诉RethinkDB,实时连 续地将查询更新结果推送到应用就可以了,不用每次都去poll一遍。RethinkDB的实时推送结构为搭建可扩展实时应用节省了大量时间精力。除了为实时应用提供了全新的设计之外,RethinkDB 还提供了一种灵活的查询语言、直观的操作和监控API,安装学习起来也非常容易。你可以查看这篇 Advancing the realtime web 得到更多RethinkDB计划的技术细节。什么时候RethinkDB一个好的选择?当你的应用很大程度上有赖于数据的实时反馈时,RethinkDB 就会成为一个很棒的选择。“查询-响应”式的数据库访问模型在web上的确很有用,它可以直接映射到HTTP的“请求-响应”。而现代应用则需要将数据直接实时地传送到客户端。能够最大化得益于RethinkDB实时推送架构的例子包括:协作网站和移动应用数据流分析应用多人在线游戏实时交易场所设备联机举个例子:在协作设计一个app的时候,其中一个用户改变了某个按钮的位置,服务器就必须在第一时间通知所有在完成同一项目的其他用户。网页浏览器 能够通过WebSockets和http持久连接来支持这一功能,但数据库系统要迎合实时需求仍然是一个大的工程难题。而RethinkDB作为第一个开 源、可扩展的数据库,就是特别为实时推送数据到应用而设计的。哪些人在用 RethinkDB?RethinkDB 的用户包括上百个科技创业公司、咨询工作室和世界五百强企业。这里是其中的一些:Jive Software 和 Mediafly 使用RethinkDB搭建强大的响应式网页和移动应用Pristine.io 和 Narrative Clip 使用RethinkDB搭建用于设备连接的云架构Platzi 和 Workshape.io 使用RethinkDB进行实时分析CMUNE 和 NodeCraft 使用RethinkDB构建大规模可扩展多人游戏RethinkDB 拥有超过十万开发者的活跃社区和上百个来自世界各地的代码贡献者。RethinkDB是基于现有技术的吗?高效实现实时推送架构需要重新设计绝大部分的数据库成分,包括查询执行引擎、分布式系统、超高速缓存子系统和存储引擎。因为架构影响到每一个数据库 组成部分,RethinkDB不得不从C 开始一步步写起来。RethinkDB 是由数据库专家组成的团队花了五年时间做出来的,还得到了来自世界各地上百个代码贡献者的帮助。RethinkDB和realtime sync不同在哪里?和Firebase, PubNub 或者Pusher 这类实时同步API相比,RethinkDB主要不同在以下三个方面:首先,实时同步API是云服务,而RethinkDB 是开源项目。RethinkDB也有云端,可以通过我们的合作伙伴 Compose.io 和 Amazon AWS获得。它还可以部署在你自己的架构中,没有任何限制。其次,同步实时API只局限于同步文档,而RethinkDB一个有着更普遍应用范围的数据库系统。 在RethinkDB中你可以运行任意query,包括table joins, subqueries, geospatial queries, aggregation, 还有map-reduce。实时同步服务有更多查询功能上的限制。最后,实时同步API的设计是直接从浏览器访问。这使得基本的app能够快速地跑起来,然而一旦app扩展了,灵活性就会受到限制。 RethinkDB的设计是从应用服务器进行访问,这一点上更像是传统的数据库。可能会要多花一点设置代码,但拥有足够的灵活性去适应应用的成熟。RethinkDB和MongoDB又不同在哪里?RethinkDB所基于的架构和MongoDB非常不同。开发者只需告诉RethinkDB,实时连续地将查询更新结果推送到应用就可以了,不用 每次都去poll一遍。你同样可以在RethinkDB上用传统的“查询-响应”范式来书写应用。然后在你开始为app添加实时功能时再去订阅实时数据 流。举个例子,这是你让RethinkDB查询一个文件时的命令:r.table('users').get('coffeemug').run()然后这是你从RethinkDB订阅更新流时用到的语句,在任何时候文档发生了变化就会推送:r.table('users').get('coffeemug').changes().run()RethinkDB的实时架构可以和MongoDB的oplog相提并论,但前者提供了更高层次的抽象。RethinkDB的数据流与查询计算引擎无缝整合,并允许你订阅查询结果的变化,而不仅仅是把数据复制过来。这种架构大幅度地减少了搭建实时app所需的时间和精力。除了实时推送架构,RethinkDB 还有许多胜过 MongoDB的地方:一种高级的查询语言,能够支持table joins, subqueries 和大规模并行式分布计算。融合了查询语言的操作和监控API,大幅度降低了RethinkDB扩展的难度。简洁美观的UI 易于复制转发,拥有在线文档支持和查询语言建议。可以看看这篇 technical comparison of RethinkDB and MongoDB 里面的评论比较中立一些。想听听个人观点的,请看@coffeemug 的what makes RethinkDB different.什么时候RethinkDB一个不好的选择?当你需要用到完整ACID支持或者更强大的架构实施,RethinkDB就不大好用了。在这种情况下你最好用一些传统的MySQL或者PostgreSQL数据库。如果你需要做深度、密集型计算分析的话,你最好用Hadoop或者类似于Verticaa的面向列的存储工具。在某些情况下RethinkDB会在一定程度上牺牲书写可用性(write availability)来保证数据一致性(data consistency)。如果高要求的书写可用性对你来讲很重要,那你也不要纠结了,像Riak这样的Dynamo式系统可能更适合你。想要更多地学习RethinkDB?阅读 ten-minute guide 开始学习RethinkDB。对于熟悉分布式系统的程序员可以直接阅读 architecture overview 。走捷径用 cookbook,你可以看到许多常用的 RethinkDB查询例子。 标签:分布式数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值