What's Coming in PostgreSQL 9.5
compose.io
compose.io
Example:
Tie a salesperson to an order placed, and use the order table as the primary fact table. For all reporting and visualizations that can be tied to orders, all one has to do is incorporate an association to that table. Worrying about which customers, products, time periods, etc. a salesperson can see are automatically handled by that association.
I am not saying that PostresSQL implements what I am describing, but this example can be expanded by creating an intermediate table with many-to-many associations. E.g., this table might have one row for each salesperson's access and one row for each salesperson under a supervisor. Once again, a centralized location for controlling access throughout the entire analytical data model. It is a very useful tool that I have relied upon extensively.
This doesn't matter in the typical webapp where all accesses to the DB happen through the same database user id, but when actually using the user system of the DB, it allows for fine grained access control to a common data set.
The closest you have without explicit RLS support is to create a view for each user. RLS generates per-user views on demand under a common name.
[0] http://www.postgresql.org/docs/current/static/ddl-schemas.ht...
Instead of storing the whole B-Tree (and spending time updating it) just store summary of ranges (pages).
This for example, would be great for a time series database that is write heavy but not read as often.
I found these benchmarks here explaining the differences:
http://www.depesz.com/2014/11/22/waiting-for-9-5-brin-block-...
---
Creating 650MB tables:
* btree: 626.859 ms.
* brin: 208.754 ms
(3x speedup)Updating 30% of values:
* btree: 8398.461 ms.
* brin: 1398.711 ms.
(4x speedup)Extra bonus:
* size of btree index: 28MB
* size of brin: 64kb
Search (for a range): $ select count(*) from table where id between 600000::int8 and 650000::int8;
* btree between: 9.574 ms
* brin between: 21.090 ms
---I've always felt like Bitmap Indexes were a killer feature, and never understood why they weren't used more in databases. If you have a low cardinality column (anything suitable for an enum), your indexes become incredibly fast and cheap.
http://www.amazon.com/PostgreSQL-High-Performance-Gregory-Sm...
Perhaps this is outdated already but we have to resort to here-documents and other shenanigans to get the initial db and users created. Is there a better way to do this?
Next would be to further improve the clustering, to remove the last reason people continue to use mysql.
What do other databases do? I haven't used others in a while, but at the time of choosing pg I remember it being more fiddly.
I don't think those really help? You need to start a server for that and be allowed to connect. If you have that you can just as well feed a file to psql to do all the setup at once.
> The config files themselves could probably use a good redesign as well.
Hm. I've dealt with postgresql.conf files for a decade now, so maybe I just don't see the problem with the format itself. I think we should make more parameters auto-tuned, but that's something different to the file format itself.
If you're talking about pg_hba.conf: Wholewheartedly agreed. That's the one thing I remember being terminally confused about back when I started using postgres.
(puts tablespace in folder under current directory)
<code>
#!/bin/sh -x
# create and run an empty database
# note: fails miserably if there are spaces in directory names
PGDATA=`pwd`/pgdata
export PGDATA
# make it if not there
mkdir -p $PGDATA
# clean it out if anything there
/bin/rm -rf $PGDATA/*
# set up the database directory layout
initdb
# start the server process
nohup postgres 2>&1 > postgres.log &
sleep 2
# create an empty DB/schema
createdb edrs_test_db
# create a user and password ("demo") to use for connections
psql -d edrs_test_db -c "create user guest password 'guest'"
ps auxww | grep '[p]ostgres'
echo run tail -f postgres.log to monitor database
# vi: nu ai ts=4 sw=4
# * EOF *
</code>
"edrs" is the name of an app - sub in something more applicable. I'm running this on OXS, but should work on Linux as well.
I'll look into that, though, as it sounds like the right thing vs the sleep hack.
(before the file redirection instead of after)
If embedding here-documents inside scripts isn't to your liking, perhaps you should either separate out the seed scripts and cat them in, or have your app-server take on more responsibility for seeding. Systems like Liquibase used by Dropwizard are an example of a more formalized way of performing initial seed, an example of something that might be more what you are looking for if shell scripts are proving difficult to operate.
Another alternative is to make an empty (or test setup) database instance in the "PGDATA" directory, and archive that (while the DB is shut down) for redeployment on another server instance. Unlike Oracle, everything is in one place, as ordinary files and subdirectories.
Yes, and it works for most server software, not just PostgreSQL. Use a configuration management system, like Salt, Puppet, or Chef.
I fully agree though and in thinking about it, a range of CLI level tools would be nice. I guess then the team would have to play catch up with any syntax/api changes for those tools too, so its adding that annoying extra bit (albeit fairly small probably). But I guess its the annoying extra bit getting down in one place, and not hand-crafted by everyone.
I've been wishing for a while though that Rails ActiveRecord would support the atomic partial update operations inside hstore that postgres already does.
That being said it might be difficult to know when you won't get any benefit out of it unless you have control or knowledge of how rows are laid out in the table space. For example, deleting some rows based off of a fairly random criteria may make Postgres insert into those spaces on subsequent writes (after a vacuum), which could "pollute" the block ranges with non-ordinal data and make the block ranges less targeted.
Instead of 4 orthogonal concepts we now have 6 overlapping. Because the majority voted for it. That's progress!
And really, upserts aren't that hard to understand.
Having the ability to tell the database the data to insert together with a conflict resolution rule and then having the guarantee that either the record will be created or the conflict resolution will be applied is very handy.
No more looping, no more deadlocks, no more retrying the same insert multiple times.
Yes, you can do it manually, but it's painful.
See also http://www.depesz.com/2012/06/10/why-is-upsert-so-complicate...
Create with upsert and Delete by upserting "deleted = true" flag.
One extra tip, which I have found useful, is to make the deleted column a time data type (just like created and updated), but nullable. That way, your Boolean check just needs to change to an IS NULL check, but you get the additional 'when' information without using an extra column.
And then I wonder if I should track updates too. There are auditing solutions to record all that, but the ones I know are (rightly) not really designed for building application logic on top of.
The idea of a relational schema having some kind of temporal dimension letting you get at changes is something that's been on my mind a lot lately.
Yes, a big problem with table-level audits is that you lose all kinds of information about the other entities in the system. Sure, now you have an audit log of when a row was changed, but you don't really know anything about the state of all the other pieces of the database at that time, so you can't really usefully reconstruct what the entity looked like at the time it was modified.
In theory you could parse through the whole audit log to reconstruct the state of the DB but in practice it gets very complicated.
This is one place where document stores really shine as you generally keep everything in a single place. When you update a document you don't have to worry about the values of all the foreign keys, you just save the current version which contains all your values.
You may want to check out Datomic. It uses an immutable, time-based model that covers deleted_at and many more scenarios (e.g., it's effortless to ask, "what was the state of this object last month?" without the need for looking at old backups.)
It's really too bad - if they offered paid support and otherwise-sane licensing, I'd be all over it.
If you have 2 tables, A and B, where B references A Ideally I couldn't set deleted on row in A until all the rows in B that reference it have also been set to deleted.
If I wasn't using soft deletes, I'd just use a foreign key from B (a_id) to A (a_id), but with soft-deletion, that constraint doesn't get enforced.
This problem is pervasive, and it's not easy to solve.