Using PostgreSQL Arrays The Right Way
blog.heapanalytics.com
blog.heapanalytics.com
Last time I tried writing stored procedures I went into a deep depression from the lack of a proper IDE/editor/debugger/tester/anything.
Is there any process out there besides time consuming trial and error? Or does everyone who writes these knows them by heart and I should just stick to programming languages?
The pg docs unfortunately weren't much beyond selecting some data. Trying to write any logic is something that left me struggling (in my case, I needed a hash table that could store a key value pair of numbers).
From my own experience a few years ago, however, go look at the stored procedures in PostGIS. There are many, many of them methodically written and you could probably learn most of what there is to know from detailed inspection.
I'd pay (one upvote) for a blog post with a better way to do this. If one doesn't exist, this might call for a postgres extension.
Honestly I don't understand how anyone can do more than a basic query in the command line for PostgreSQL. I've been using EMS's PostgreSQL Manager (www.sqlmanager.net) for years. Has auto-complete, even from local aliases. Named, numbered, parameters. Provides base templates for your BEGIN and END, and lots of other goodies. I could work without it, but it would be much more time consuming. I do however, practice most things in the SQL Editor first. Though it does have good built in analysis, sometimes it's nice to just try different things before committing them to a function.
Edit: Honestly, I wish they had better screenshots, but this should give you an idea:
Functions: http://www.sqlmanager.net/en/products/postgresql/manager/scr...
Debugging: http://www.sqlmanager.net/en/products/postgresql/manager/scr...
Triggers: http://www.sqlmanager.net/products/postgresql/manager/screen...
Query Builder: (used this much more when I was younger) http://www.sqlmanager.net/en/products/postgresql/manager/scr...
Full list: (though don't know how current) http://www.sqlmanager.net/en/products/postgresql/manager/scr...
I would be really interested in how you maintain your database code if you are up for another write up or have some time to chat.
I have seen other ways to deploy stored procedures but these often require being very careful about function API:s and delta scripts.
- For plpgsql functions that are required by app queries, we just roll them out when we write them / when they change (via ansible).
- For plpgsql functions used in jobs, the job just reloads the relevant plpgsql functions on the relevant DBs before they start doing anything. (It's a little wasteful, but not in a way that matters for now.)
- The UDFs we've written in C don't change too often, but we deploy them manually when they do.
What are some of the headaches you've had in managing stored procs? How often is your app code changing / requiring new ones?
We solved it with a small wrapper around the calls to plpgsql functions — we set up a build process to generate unique names that were called by version. During deploy, we'd have two or more versions of the 'same' function running in parallel. The last deploy step dropped the now-outdated functions.
It worked relatively well.
Once you get beyond normal queries and enter the realm of real database development you likely want someone who is a genuine database developer.
I'm worked with several database developers plus my wife is a database developer. They are a different breed, and they really develop applications in the data layer.
I can say from experience that once you add a database developer you'll never look at the data layer the same. Often, there is a substantial amount of work that can be performed better by the database (whether it's Oracle, SQL Server, Postgres or whatever) since they have 30+ years of tuning for specific data operations.
In particular, to compute where a user drops off in a funnel, I need to scan one array from left to right, and I don't need to do any joins. This shards very well, since all of a user's data lives on one shard, and most of the queries are aggregations, which are simple to reassemble from subqueries.
Postgres is robust, feature-filled, and scalable. You dont have to want all three to extract value from it.
Because even a shitty RDMBS is more robust, more secure and faster than any NoSQL wankery for this kind of use case.
There are even cases where performance has been found to be better than e.g: mongo: source: http://obartunov.livejournal.com/175235.html
There is a lot of momentum behind the improvements/additions. We will be seeing much more NoSql in 9.4, 9.5, and beyond.
And yet appending a single event (you dedupe for each event, right?) takes half a second. That's an eternity!
Even so, there are a few factors to consider:
- Half second dedupes are for users with 100k+ events, which is <<1% of them.
- We batch events for ~5s before adding them to the cluster, so we aren't deduping for every event -- only once per ~5s of events per user.
If this becomes an issue, we can remove the deduping from normal operation and only call it when we're backfilling / updating events. Even so, we still need this function to exist, and the 100x performance improvement is very helpful.