再见 MongoDB,你好 PostgreSQL(2)

一致性是重要的在于它有助于帮助我们对系统设定明确的期望。如果数据总是按照同样的方式存储,那么系统可以很方便的使用这些数据。如果在数据库层面要求表的莫一列必须存在,那么在应用层面就不用检查这列数据是否存在。数据库即使实在高压情况下,也必须保证每一次操作的完整性。没有什么事情比单纯的插入数据,过了几分钟后却找不到数据的事更让人沮丧了。

可见性包含了两点:系统本身以及从中获取数据的容易程度。如果一个系统出错那么应该易于调试。反过来,用户应很容易查到想要查询的数据。

正确性是指系统的行为如我们所期望的那样。如果某个字段定义为一个数值型,没有人可以像其中插入文本。这方面MySQL是臭名昭著,一旦你这样做你将得到伪结果。

可扩展性不仅针对性能而言,而且也涉及金融方面和系统能够多么好地应对不断变化的需求。一个系统在没有大量资金成本或减缓系统所依赖的开发周期情况下,很难表现得非常好。

搬离MongoDB

上面的需求牢记于心后,我们就开始寻找一个取代MongoDB的数据库。上面提到的特性通常是传统RDBM特征的一组核心集,所以我们锁定了两个候选者:MySQL和PostgreSQL
本来,MySQL是第一候选,因为我们的一些关键数据已经在使用它存储。然而,MySQL也有一些问题。例如,当将一个字段定义为int(11)时,你却可以轻松地向该字段插入文本数据,因为MySQL会试图对它进行转换。下面是一些例子:

mysql> create table example ( `number` int(11) not null );
Query OK, 0 rows affected (0.08 sec)
 
mysql> insert into example (number) values (10);
Query OK, 1 row affected (0.08 sec)
 
mysql> insert into example (number) values ('wat');
Query OK, 1 row affected, 1 warning (0.10 sec)
 
mysql> insert into example (number) values ('what is this 10 nonsense');
Query OK, 1 row affected, 1 warning (0.14 sec)
 
mysql> insert into example (number) values ('10 a');
Query OK, 1 row affected, 1 warning (0.09 sec)
 
mysql> select * from example;
+--------+
| number |
+--------+
|    10 |
|      0 |
|      0 |
|    10 |
+--------+
4 rows in set (0.00 sec)

值得注意的是,MySQL在这些情况下会发出警告。但是,仅仅是警告而已,它们通常(若非总是)会被忽略。

此外,MySQL的另一个问题是,任何表的修改操作(例如:添加一列)都会导致表被锁,此时将无法进行读或写操作。这就意味着,使用这种表的任何操作都不得不等待修改完成之后才能进行。对于包含有大量数据的表,这可能会花费几个小时才能完成,很可能会导致应用程序宕机。这已经导致一些公司(例如SoundCloud)不得不自己开发工具(例如lhm)来解决该问题。

了解到上面的问题后,我们开始调查PostgreSQL。PostgreSQL可以解决很多MySQL不能解决的问题。例如,PostgreSQL中你不能将文本数据插入一个数字字段:

olery_development=# create table example ( number int not null );
CREATE TABLE
 
olery_development=# insert into example (number) values (10);
INSERT 0 1
 
olery_development=# insert into example (number) values ('wat');
ERROR:  invalid input syntax for integer: "wat"
LINE 1: insert into example (number) values ('wat');
                                            ^
olery_development=# insert into example (number) values ('what is this 10 nonsense');
ERROR:  invalid input syntax for integer: "what is this 10 nonsense"
LINE 1: insert into example (number) values ('what is this 10 nonsen...
                                            ^
olery_development=# insert into example (number) values ('10 a');
ERROR:  invalid input syntax for integer: "10 a"
LINE 1: insert into example (number) values ('10 a');

PostgreSQL 还具有在许多方式中不需要每一个操作都上锁就可以改写表的能力。例如,添加一列没有默认值却可以设置为null的列并能够快速完成无需锁定整个表。

还有其他各种有趣的功能,如在 PostgreSQL 可以:trigram 为基础的索引和检索,全文检索,支持JSON查询,支持查询/存储键-值对,支持发布/订阅等更多。

最重要的是PostgreSQL在性能,可靠性,正确性和一致性之间能够权衡。

迁移到PostgreSQL

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/9d736be4646bbdba14026cab50a81511.html