Ayende Rahien, founder of RavenDB, writes about database internals, .NET, performance, and programming language design including Zig and Odin.
HN commenters link his rebuttal on using mmap in databases, his notes on Zig error handling, and describe him as a rock solid engineer.
> .NET developers love using the standard libs
I may not be a typical .Net developer, but my personal feeling is that this is too general and somewhat glib.
If you're inexperienced you will (and should!) choose the default option, if there's one available, and the most commonly used option if there isn't a default. So, if you wanted an ORM, then before EF there was NHibernate. But after a while you become able (from painfully gained experience) to determine what you want from a tool and what trade-offs you want to make, so you might use something like Dapper or no ORM at all.
Personally, I have found some of the MS provided implementations - shall we say - less than optimal. The Unity Framework. EF (which I dearly wish I have never had to suffer using). MSTest. Enterprise Library (oh god ugh).
So I make other - informed - choices about what to use. Some things I keep using because they are 'good enough' and I have a library of utilities and a mental map of how they work - log4net, NUnit - and some things I find I just don't need any more (mocking libraries, for one).
MS still support their provided implementations - as they should - but even their own projects can and do use third-party frameworks rather than the MS provided implementation (for example, Bot Framework used AutoFac (back when I was using it, anyway) [1]) - because their developers have been released from the requirement to exclusively use MS provided frameworks, and are making their own choices about what…
Yes (it helped) and speed, i.e. querying and indexing performance, for sure is only an USP if you also have relevance.
I'm confident the relevance is as good as or better than Lucene. I especially like my phrase queries and how they seem more relevant compared to that of a Lucene phrase query. The scoring is a half-way implementation of word2vec (in a lot of ways similar to the scoring mechanics of Lucene's tf-idf scheme). I'm aiming for full word2vec implementation in vNext.
I have only my own benchmark tests to tell me I'm faster than Lucene. Which is why I'm contemplating writing a formal proof both of ResinDB's performance and of it's relevance.
My test data has been the English verison of Wikipedia plus Project Gutenberg. I suppose I could publish those indices to the world, as a demo search engine. I don't think a soul would care about a proper searchable Project Gutenberg though. Looking into common crawl now.
I'm a part-time father of two, employed doing tedious unmotivating work, focusing completely on my spare time project. I need some advise as to what the next step should be, if I wanted to make this into a business that I could spend all of my time with, not only nights and weekends. Formal proof? Demo?
Side note: one of the most approachable people in the database building community is Oren Eini, creator of RavenDB. He's reviewing ResinDB on his blog. I've read a preview of the entire series of posts, implemented solutions for the best parts of the…
I think AGPL is a fairly good choice for anything that's potentially used as a hosted service. All the big enterprises I've worked with so far have a policy that forbids AGPL'd software and rather purchase commercial licenses. SMEs & Startups may make different choices but depending on your product they may not represent the relevant majority of the market anyway.
Ayende from RavenDB (which is a great no-nonsense document DB) has written an interesting blog series [0] on how they approach OSS while still making money from it and keeping their interests aligned with users and customers. TL;DR they license the full server and all modules as AGPL, offer free community (commercial) license that don't skimp on core features (clustering, authn/z), treat support as a cost-center.
Appears to work well for them and I personally find their mode of operation sympathetic.
[0] https://ayende.com/blog/posts/series/186113-A/making-money-from-open-source-software
I'm not familiar with PG but I am planning on using it in my current project, which is why I'm interested in understanding whether these are really DBMS issues.
In the .NET world, for all the database adapters I've used (MSSQL, SQLCE, Oracle, MDB), individual statements are implicitly wrapped in transactions when no explicit transaction has been specified - not sessions/connections.
I agree the "implicit transaction per session/connection" design is confusing and likely to result in bugs. While the standard .NET approach limits bugs, the downside is poorer performance when an unaware developer uses numerous implicit transactions for multiple statements where a single explicit transaction would suffice.
Experts in the area appear to recommend always using explicitly managing transactions (e.g. http://ayende.com/blog/3775/nh-prof-alerts-use-of-implicit-transactions-is-discouraged ), and this is the approach I follow in my own work now.
This is a very long and very good blog series that I highly recommend. (One note, it's from 2013.)
The funniest part is this post, which complains about code duplication: https://ayende.com/blog/162853/reviewing-lightning-memory-mapped-database-library-a-thoughtful-hiatus
In the last two screenshots, there is a subtle difference with the indentation, which breaks MDB_PREV_DUP. It wasn't noticed until over a year later: https://github.com/LMDB/lmdb/commit/bfe297da47beb31debee48f016222b63d94271fd
I'm still a big fan of LMDB. It's been hugely inspirational for me, and I think it's the best low-level key-value store out there. There is still lots of room for improvement though!
EDIT:
Paste this hacky snippet into your browser's console to save all of the links into your clipboard:
(() =>
{
let result = [...document.querySelectorAll('td a')]
.map((link) =>
link &&
!link.href.includes('ycombinator') &&
!link.href.includes('javascript:void')
? link.href
: ''
)
.filter(Boolean);
result = [...new Set(result)];
result.sort();
copy(result.join('\n\n'));
})();
Just to help, here's a compiled-list of all of the links shared here so…