TODO this is a draft
RxDB is client-side, offline first Database for JavaScript applications. While RxDB could be used on the server side, most people use it on the client side together with an UI based application. Therefore RxDB was optimized for client side applications and had to take completely different tradeoffs than what a server side database would do.
When you ask people which database they would want for browsers, the most answer I hear is something SQL based like SQLite. This makes sense, SQL is a query language that most developers had learned in school/university and it is reusable across various database solutions. But for RxDB (and other client side databases), using SQL is not a good option and instead it operates on document writes and the JSON based Mango-query syntax for querying.
// A Mango Query
const query = {
selector: {
age: {
$gt: 10
},
lastName: 'foo'
},
sort: [{ age: 'asc' }]
};
SQL is made to be used to run operations against a database server. You send a SQL string like SELECT SUM(column_name)...
to the database server and the server then runs all operations required to calculate the result and only send back that result.
This saves performance on the application side and ensures that the application itself is not blocked.
But RxDB is a client-side database that runs inside of the application. There is no performance difference if the SUM()
query is run inside of the database or at the application level where a Array.reduce()
call calculates the result.
SQL is string
based and therefore you need additional IDE tooling to ensure that your written database code is valid.
Using the Mango Query syntax instead, TypeScript can be used validate the queries and to autocomplete code and knows which fields do exist and which do not. By doing so, the correctness of queries can be ensured at compile-time instead of run-time.
By using JSON based Mango Queries, it is easy to compose queries in plain JavaScript.
For example if you have any given query and want to add the condition user MUST BE 'foobar'
, you can just add the condition to the selector without having to parse and understand a complex SQL string.
query.selector.user = 'foobar';
Even merging the selectors of multiple queries is not a problem:
queryA.selector = {
$and: [
queryA.selector,
queryB.selector
]
};
Like other NoSQL databases, RxDB operates data on document level. It has no concept of tables, rows and columns. Instead we have collections, documents and fields.
Because of the document based approach, TypeScript can know the exact type of the query response while a SQL query could return anything from a number over a set of rows or a complex construct.
- Does not work with offline-first
- Does not work with multi-tab
- Easier conflict handling on document level
-- Instead of transactions, rxdb works with revisions
- Does not work with easy replication
- migration of data on clients is hard
- Why jsonschema