I don't run this in production only because I would have a hard time convincing everybody to do it or by cargo-culting my fears (depending on the project). But one day I will.
"Another way to look at SQLite is this: SQLite is not designed to replace Oracle. It is designed to replace fopen()."
There are very few instances where I end up in a position where I have to decide whether I need to use postgres or sqlite, they have very different use cases.
They can't say it, but it is designed to replace FoxPro and Access, or more generally: a local ODBC connection.
Just to be clear, I'm not saying every application needs it. If you actually use it as a replacement for local files, that's great. If you use a multi-user app containing sensitive data - "root password (wtf, everybody hate passwords)" this is so wrong. Reminds me of "chmod 777 everything" - wtf, everybody hates dealing with permissions.
Sqlite eliminates almost all of the management overhead that other databases force on you, so its trivial to have one database per application. Indeed, I have never seen anyone bother with a multi-application sqlite db, which could also cause serious performance problems. So that renders you sql injection point moot.
As for permissions, its better to let the OS handle that than some half-baked database permissions system. Root accounts/passwords are a wtf in a production environment because they destroy auditability. If you really want permissions, it is trivial to create system user accounts for the application and assign the correct file permissions, or even isolate particularly sensitive information in its own file. Combine this with AppArmor to further lock down individual applications.
All of this is overkill, but so is a full blown RDBMS in many cases. If you are starting out building a new application, just target sqlite until you actually need something bigger. Odds are, YAGNI.
Multi-user support is what forces that overhead on you.
It's just that SQLite consciously aims to be a single-user system.
> As for permissions, its better to let the OS handle that than some half-baked database permissions system
This is nonsensical. There isn't an isomorphic mapping from the Unix permissions model to SQL's permissions model, particularly when you start introducing stuff like row-level permissions.
If you write an application which uses a DB backend, and you require multi-user capability, you can either delegate some of that to the database, or roll your own. In which case, half-baked permissions systems are back! Especially if you can't isolate database connections (because it renders any app-code permissions system moot if you allow 3rd party code execution, such as plugins).
All that overhead is there for a reason. Those reasons are irrelevant in the single-user case. But they are not irrelevant in the multi-user case.
SQLite's classic use case is where SQL-like access to data would be convenient but a full RDBMS would be tremendously inconvenient, e.g. embedded systems. People seem to be citing inappropriate environments for SQLite as reasons to say it is of no value. You get the same sort of silliness from NoSQL zealots.
Sorry, but that doesn't make sense. For example: if you want your application to be able to add new rows, but not delete them (for audits actually) you cannot do this with OS permissions. Only database-layer permissions will make it possible.
There are many other examples of such use-cases. You simply cannot use OS/apparmor/selinux/whatever external to the database to grant/revoke per-table access.
> Root accounts/passwords are a wtf in a production environment because they destroy auditability.
On this side however - why would anyone know / have access to your root account? Applications should never have it. Servers should never have it (in a form different than the hash). Only people should have it.
The "ATTACH DATABASE" command (http://www.sqlite.org/lang_attach.html) can open any other database that the current user has permissions to.
You could, as you mentioned, set up a new user for each database. At a certain point, the permissions systems in a traditional RDBMS may be easier to manage.
I don't intend to say its no good, btw. It's fantastic! But you have to use it where it is meant. You aren't comparing apples with apples I'm afraid.
If you want an database for your mobile app, or a web app use a full fledged database like MySQL or Postgres.
sqlite is for embedded storage applications, especially in the backend. Where the resource utilization foot print is supposed to be minimum, and where you running into situations where are you are reimplementing SQL like DSL's to query and write to files. Or say you just wish to maintain some structured form of inventory.
Best example I can give you is a web browser. There is a requirement to store a good deal of structured information, in a mechanism which requires little resource utilization, which doesn't require additional software like demons or a server to run or complicated deploy and maintain scenarios. Or even a strict configuration.
If you look at this use case you will see tons of backend application would be better off using a tool like sqlite than play with huge xmls and endless rewrite parts of SQL badly.
Sure SQLite (which I love) is easier to get running, but do not exaggerate issues of traditional RDBMs.
In PostgreSQL 9.3 which will be released in a couple of weeks they will also fix the cases where you may need to use sysctl to iincrease shared memory limits.
Personally I don't like it when projects mix money with opensource.
At work we need to because we are distributing map data that was licensed to use under the condition that we don't ship the data unencrypted to the clients, however nonsensical that is, given that you have to distribute the encryption key the same way.
But for use cases like Lightroom which stores its catalog in an SQLite database or Far Manager which stores the config there I very much doubt they should be encrypted by default.
SQLite has been under development for thirteen years and has hundreds of releases. I don't think the "feature X? you're doing it wrong, we're just a simple replacement for fopen()!" refrain holds a lot of water at this point.
FTR when you work in the financial industry, all kinds of files and databases get encrypted. I agree that encrypting a file or database is not extremely secure since the decryption key is sure to be nearby, but it's still an important need, there are security audits and all kinds of things that call for encryption when available.
That said, it's the financial industry. If the encryption feature is offered as a paid one, that's not so terrible.
Google did an end-run around these restrictions by using the Dalvik virtual machine instead of the JVM where the crucial patents lurked, so Android didn't have to implement the whole of the Java library before they shipped.
And you don't really worry about underlying hardware on those machines.
There was some minor slowdown noticeable around 6AM - 10AM, but besides that, we never had major issues. The bottleneck was usually the network, not the DB.
Edit: Anyone interested in playing with SQLite should give the SQLite Manager plugin for FF a try : https://addons.mozilla.org/en-US/firefox/addon/sqlite-manage...
(I'm not affiliated with the developer, I just like the tool)
You can run something like that with no noticeable performance issues on a classic 120MHz Pentium and flat files (I'm speaking from experience of running a USENET news server handling 30,000 groups for an ISP on a machine like that, which was shared with lots of other functions), so if the bottleneck had been anything other than the network, it'd have been shocking.
The nice thing about Postgres as opposed to SQLite is that we finally got "searching" as a feature. ;)
While a forum that gets 1000 posts/day is quite active, a database that does an INSERT ever 80s is not even moving.
We always limited transactions for UPDATES and INSERTs that involved more than one table.
It was quite the learning experience since you do have to think of different ways of working with data. You get to learn very quickly the difference between what like to store vs. what you actually need to store to get a particular functionality. But that turned to being a boon in the end because we got a much simpler forum as a result. Fewer bells and whistles meant users focused on actual discussion and not ancillary, shiny bits and bobs.
EDIT: And that is without any app specific caching.
Backups were pretty easy. ;)
Now it's an embedded database, which is why leokun's comment is out of place. However you can absolutely drop a queue in front of it, for instance, and serve many "simultaneous" users for a purpose such as a web forum.
Reasons for downvoting is usually due to posts containing no new information, excessive snark, flippant attitude etc... Users and moderators are extra touchy about avoiding the Reddit ambiance here. Basically if it doesn't contribute to the discussion, then it may be downvoted. That said, I didn't downvote you because what you said allowed me to add to the discussion.
I try to follow this when I vote : http://news.ycombinator.com/item?id=1065084
As of version 3.8.0, the SQLite library consists of approximately 84.3
KSLOC of C code. (KSLOC means thousands of "Source Lines Of Code" or,
in other words, lines of code excluding blank lines and comments.)
By comparison, the project has 1084 times as much test code and
test scripts - 91452.5 KSLOC.
No it isn't. I have been using SQL databases which got absolutely horrible query optimizer totally ruining any performance exceptations. I have blogged about that, and I was very frustrated and disappointed with results.
Which is faster if id>100 or simply walking database by using series of selects select ... id=101 ... select ... id=102 ... Turns out that the later method is a much faster. Engineers also then suggested that I could optimize the query by using structure select ... id=101 UNION select ... id=102. That's simply insane. How ever the query was written, query otpimizer / planner should make sure that all these queries are delivered using similar background process. Of course that walk is impossbile to optimizer, because it's series of individual queries. But it's just crazy that select id>100 is slower than that!
Yes, you might have guessed that the SQL database I'm referring to isn't SQLite.
And finally, I love SQLite and use it for most of my (work & hobby) projects as local database.
Were there a lot of qualified rows for id > 100? If there're a million rows qualified for id > 100, which way is faster?
Adding statistics or an index may help. Just understand that if your data distribution changes radically the index or rewritten query may no longer be valid.
This is where explain/execution plans are great. Unfortunately, even these aren't completely documented. SQL Server is not bad, and Postgres is not only well documented but you can read the source. Oracle is often a basket case - there are literally thousands of undocumented parameters that you can set, not to mention underlying data views that also haven't been documented. In fact, there have been whole books trying to unravel the Oracle CBO, but even the most obscure often admit that Oracle fix optimiser bugs which can cause an impact on query plans.
In some cases, you must implement hints, because there is no way of catering for all queries under all loads based on all possible data distributions. Sure, you can add a variety of different types of indexes, histograms and other statistics to try to influence the execution plan, but at the end of the day sometimes you simply have to add a hint to force a particular sort of join, etc.
I guess my main point as I muse on query optimizers/planners is that none of them are perfect. It occurs to me that one of the best so far is actually Postgres, but alas - they don't allow for hints.
What's my main point here? It really comes down to the fact that the ideal for database queries is to allow for a declarative syntax ("give me all rows of product x that are over $100") without having to worry about the mechanics of retrieving the data, it's just not entirely possible. You really need to give developers and database folks the ability to nail down the actual mechanics of data manipulation.
If I were to judge based on my current experience, I'd say more often than they make queries with less than 8 joins. In the stored procedure I'm working on now, there are many queries with up to 20.
SQLite version 22.214.171.124 2013-01-09 11:53:05
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> create table a(id integer);
sqlite> create table b(id integer);
sqlite> create table c(id integer);
sqlite> select a.id, b.id, c.id from a
...> left outer join (b join c on b.id=c.id) on b.id=a.id;
Error: no such column: b.id
Supporting some crude form of stored procedure would be nice too (you can already add SQL functions, why not procedures?), so that a 3rd party can provide semi-native ALTER support (don't worry, I don't want to put ALTER into SQLite itself, I understand it requires rewriting of table data, I'd just like there to be a standard implementation of that approach somewhere).
If you just want to play with it a bit, there's a Firefox extension available : https://addons.mozilla.org/en-US/firefox/addon/sqlite-manage...
It's not very powerful, but you can play around with different schemas. You can even export to different formats and edit manually if you like.
edit: to below posters, I'm fully aware sqlite is embedded, i use it everyday for android. I'm just asking if there's actually a technical reason why sqlite and postgres (and mysql) couldn't be merged. A db that can be both embedded or run as server. This would reduce the duplication of effort in open source db community.
Among its many advantages in that situation: a database is contained in a single file with minimal overhead, the source is shipped as one .c file and encouraged to be statically linked, and the code size is relatively small (compared to something like postgresql).
Some things are better expressed in the DB native language. Help to abstract and share implementation of DBs that are used by different languages.
SQLite is fantastic when you need a data store for mobile or embedded use, you'd like ad-hoc queries over your data with the option of adding indexes to speed up frequently used ones, you want transactional update to the data, and multi-user access is not a problem.
It's basically a much better replacement for the hash table on a disk approach of DBM libraries.
PostgreSQL would just be total overkill for this kind of scenario.
The simplicity comes from largely from not supporting multiple user accounts (authn/authz are left to the owning application), and secondarily (I think) from not being designed to support large numbers of connected processes. If your server need fits that profile, then you can use SQLite and benefit from its simplicity. But if -- as is often the case -- it doesn't, you can't, and its not because no one has merged SQLite with PostgreSQL, its because there is inherent complexity that comes with serving certain use cases.
If postgresql could have a single file, embedded mode, then it could replace sqlite.
The advantages of such a design would be:
1. All the optimisations and transaction guarantees of a full-featured DB
2. All the conveniences of a single file DB
3. Better utilisation of open-source resources as the OP points out.
On the other hand, the postgresql system might be bigger (in terms of code size and heap usage) than sqlite. So it may not be feasible to use in all embedded applications.
Your Firefox browser and Skype client come with SQLite.
I love SQLite ...
Web SQL Database rocks.