3 ms·
transactional DDL => if your application often has schema update and you use a tool like Doctrine for PHP / Alembic for python, when a downgrade or upgrade fail
by allan_s 10y ago
transactional DDL => if your application often has schema update and you use a tool like Doctrine for PHP / Alembic for python, when a downgrade or upgrade fail on MySQL in the middle became the create index was already taken by someone who "hot-fixed" the database and that now you're in an inconsistent state and you have to clean stuff by hand you will regret to not be on PostgreSQL where it will have simply rollback the transaction, leaving you in a consistent state, you fix the migration, you hit again the command and you can go back home
hstore/jsonb/array/composite types https://www.postgresql.org/docs/8.1/static/rowtypes.html https://www.postgresql.org/docs/8.1/static/rowtypes.html : array is often a good option to implement tag system
partial index: imagine you have a lot of "soft deleted" rows (i.e with a flag deleted turned to true), you can create an index that ignore them
index on expression: you often do request like "where date = today" , but you store timestamp precise to the second ? and you don't want to run date_trunc(your_column, 'day') , which it also a function not present in mysql..., everytime, nor you want to create a dedicated column for that only for the sake of performance, index on expression permit you to do that.
integrated full text search: you have a smallteam, and you don't feel like maintaining one more service for indexing and keeping in sync your search engine, here you are (of course it's not perfect but better than the option provided by MySQL)
table inheritance for partionning: you create one table "orders" , and you can easily partion them into "orders_2016" "orders_2015" etc. while still simply selecting things out of "orders"
constraints: your column "event_start" must be before "event_end", you can enforce that at the table level in PostgreSQL
text columns: in PostgreSQL don't worry with varchar(XXX) with XXX being the subject to flamewars (256 ? 500 ? 1000), the type "text" in postgresql is up to 2Go and as efficient as varchar()
uuid support: postgresql support uuid natively as primary keys (without needing to resort to a varchar ofcourse...)
And I've only talking about the advantage of PostgreSQL, not the strange defect of MySQL: for example that you can only have 1 column with a default timestamp, that your autoicrements will overflow silently taking back previous ids , a lot of things are only "warnings" (value not in an enum, fine I will insert null) that you will not see in your application code except if you really look hard for it.
Edit: I've used MySQL extensively and only started for now 2 years to use PostgreSQL, and though I have more knowledge in MySQL optimization and internals, and I don't consider it "bad", it's just 'so so', you will definitely be able to do whatever you want with it and it will not betray you hard, but PostgreSQL is just from an other league and will actively help you.
- dcosson 10y agoGreat list, thanks for the thorough response
- evanelias 10y agoA few things from this list are out of date. For example, MySQL 5.6 (GA release 3.5 years ago) added support for multiple columns with default timestamp. MySQL 5.7 (GA release 1 year ago) added generated virtual columns, which can be indexed, basically supporting index on expression. And for an extreme example, table partitioning was added in MySQL 5.1, 8 years ago. The default SQL mode also changed to be strict in 5.7, preventing silent overflows and other oft-complained-about write behaviors. Using a strict SQL mode has been recommended best practice for quite a long time anyway. MySQL certainly has its flaws, and there are a number of useful features that are present in pg but missing in MySQL. But the gap is smaller than many people realize.
- ngrilly 10y agoA bunch of other relevant features of PostgreSQL: - table elimination/join removal (MariaDB supports it but MySQL doesn't) - asynchronous protocol (the new X Protocol supports it but not the standard protocol) - table functions (for example the generate_series function which is very useful in PostgreSQL) - LISTEN/NOTIFY (a built-in pub-sub mechanism) - WITH (Common Table Expressions) - Window aggregations (very useful for reporting and stats) - Row Level Security (introduced in PostgreSQL 9.5; very useful for multi-tenant applications)