为什么我觉得MySQL就是一个玩具

         原文地址http://grep.be/blog/en/computer/cluebat/mysql_toy_argument

         A commentor on my previous post asked why I think MySQL is a toy.

         之前我发的一篇blog的评论中有人问我为什么觉得MySQL是一个玩具。

 

         I've actually blogged about that a number of times, but when wanting to point that out, I found that most of those posts point out just one thing, rather than having one post that enumerates them all. So let's remedy that, shall we?

         实际上我已经很多次在blog中提到这个话题了,但要具体来说,大部分文章只是指明了一点,而没有能集中在一篇文章枚举全部内容,所以让我以这篇文章来改善这个局面,好砝?

 

         There are many things wrong with MySQL, including, but not limited to:

         MySQL在很多地方都有缺陷,包括但不限于:

 

         In my personal opinion, the whole storage engine thing is a bad idea. It leads to dilution of effort (the MySQL developers need to implement stuff more than once), and makes users choose between disjoint feature sets, which will almost always result in suboptimal results. It also neatly allows PR people to claim that MySQL is 'fast' and 'ACID compliant', without mentioning that you can't combine both.

         在我个人看来,采用全局的储存引擎不是一个好主意。它导致开发者的效率降低(MySQL开发者需要不止一次的实现一些东西),让用户在不相交的功能集之间选择,几乎总是导致欠佳的结果。并且它整齐划一的公开地宣称MySQL是“快速”和“ACID兼容”的,但没有提及你不能将两者结合。(译者按:一开始不知道他在表达什么意思,现在终于大概明白了:不能针对不同的表进而灵活的采用不同的储存引擎,有的引擎快速,有的引擎兼容ACID,但就是不能同时使用这两个特性)

 

        One of MySQL's default settings is to truncate string values if they are longer than the field in which they're supposed to fit. This eats data. Hint: it's a database. While truncating strings might be appropriate in extreme corner cases, making it the default is so wrong it's not even funny.

         MySQL的默认设置之一是当插入字符串的长度超过字段原有的长度时,会删除超过部分,使之看上去刚好合适。这导致数据被吞噬。提示:对于一个数据库来说,更为恰当的做法是截断字符串应该发生在极端的角落,使它默认如此显得十分之可笑。

 

        One of MySQL's default settings is to use MyISAM as a storage engine, which doesn't do transactions. This means you don't have atomicity, which eats data. Hint: it's a database. While telling a user "if the system crashes, I might write your entire data set to disk, or I might write just half of it, or I might corrupt the data set and I'm not going to tell you until you try to read again" might be appropriate in extreme corner cases, making it the default is so wrong it's not even funny. Update: as many people pointed out to me in the comments, apparently one of the first things Oracle did when they took over MySQL is to change the default from MyISAM to InnoDB, making this point no longer valid. I still think the replaceable storage engine thing is a bad idea, but with InnoDB as default, it's not as much of a pain anymore.

         MySQL的另一个默认设置是使用MyISAM作为存储引擎,不支持事务。这意味着你没有原子操作可用,使数据丢失(译者按:原文This means you don't have atomicity, which eats data.不解这里是什么意思)。提示:对于一个数据库来说。假如它告诉用户“当系统崩溃时,我可能已经把所有的数据写进磁盘,也可能只写了一半,也可能是数据结构已经损坏但我没有告诉你,当你重新读取的时候就能发现错误了。”这个引擎可能适用于极端的不常发生的情况,但是数据库默认采用这种引擎就太可笑了。更新:很多人在评论中指出,显而易见的Oracle接手MySQL之后第一件事就是把MySQL默认的MyISAM换成了InnoDB,因此这一点已经不再是MySQL的缺陷之一了。我仍然坚持认为替换引擎不是一个好主意,但至少InnoDB作为默认的引擎不会比MyISAM更让人痛苦

 

         If those two weren't enough 'mysql eats your data' arguments, note that most distributions routinely run a data recovery tool at MySQL startup, because not doing so caused problems in the past.

         如果以上两条不能充分解释MySQL破坏数据的争论,那么请注意不要在mysql启动的时候使用数据恢复工具进行常规工作,因为在以前这样会带来很多问题。

 

         I've seen MySQL crash and burn and segfault reproducibly when it encountered a corrupt table. Now I'm not saying that the database should be able to read data as if nothing happened from a corrupt file, but it should not crash and burn and segfault; instead, it should produce an error message.

         我已经见识过MySQL在遇到了一个损坏的表时发生的冲突,损毁,或者再现段错误。现在,我不是说数据库必须要能够从损坏的文件中读取数据就像什么都没发生过一样,但它不应该出现冲突,损毁,或者再现段错误;相应的,它应该产生一条错误信息。

 

         Fetching a result set can be done in two ways: either you call mysql_use_result() before calling mysql_fetch_row() which tells MySQL you'll be fetching the result one row at a time, or you call mysql_store_result(), which will read the entire result set into memory. So far so good. The problem, however, is that if you use mysql_use_result(), you're locking the tables from which you're fetching data, and no other client will be able to update any data in those tables until you're finished. On the other hand, if you need to process a large amount of data that can't be processed on the server for some reason, you may need to run a query that returns more data than you have memory. In that case, running mysql_store_result() is plain impossible. This isn't just a theoretical thing; I've seen cases in data warehouse situations where a database client needed to process multi-gigabyte query results. Trying this on MySQL is a pain.

         获取结果集有两种方式:要么你在调用mysql_use_result()之前调用mysql_fetch_row(),这等于告诉MySQL你要一次一行的获取结果,或者你调用mysql_store_result(),将整个结果集整个读到内存中。到目前为止,一切都好。不过有一个问题,就是如果使用mysql_use_result(),你读取数据时会把表锁起来,此时其他线程无法操作表里面的数据,直到你完成读取并释放锁。另一方面,由于某些原因,你无法在服务器上处理大批量数据。你可能需要运行一个查询但返回的数据比服务器的内存还要大。在这种情况下,执行mysql_store_result()是完全不可能的。这不是一个理论,我遇到过数据仓储方面的案例:数据库客户需要处理很多GB的查询结果。在MySQL上尝试这样做非常之痛苦。

 

         When compared to PostgreSQL, the MySQL feature set is immature. For instance, here's a number of useful[1] features which PostgreSQL has but MySQL, to the best of my knowledge, does not (corrections are welcome):

       跟PostgreSQL相比, MySQL的功能集是不成熟的。例如,这里有一些有用[1]的功能。是PostgreSQL有但据我所知MySQL没有的(欢迎改正) :

 

        

        table inheritance

        表继承

 

         asynchronous notification

        异步通知

 

         full ACID compliance, in all cases. (MySQL only offers full ACID compliance if you pick a particular storage engine)

         在全部情况下,完全ACID兼容。(MySQL只有在特定的储存引擎中才提供完全ACID兼容)

        

         asynchronous command processing.

         异步命令处理。

 

         Very flexible authentication system, and real actual users. For instance, PostgreSQL supports Kerberos authentication, and understands that users may actually log in from different hosts (gasp!)

       非常灵活的身份验证系统,和真正的实际用户。例如, PostgreSQL支持Kerberos身份验证,并且意识到用户信息实际上可能会记录在不同的主机(哇!)

 

         SELinux extensions, calledSE-PostgreSQL.

SELinux扩展,即SE-PostgreSQL。

 

         Server-side languages are implemented using a plugin scheme, allowing stored procedures to be writtenbascially in any possible language. Someone wrote a PL/LOLCODE which, while not very useful, shows the flexibility; MySQL only supports one language for stored procedures and triggers—if the storage engine supports triggers, which not all do.

         服务器端语言使用一个插件来实现,在根本上允许任何可能的语言编写存储过程。有人写了一个PL / LOLCODE ,虽然不是非常有用,但是展示了其灵活性; MySQL只支持一种语言编写存储过程和触发器,但也不是所有的储存引擎都支持触发器的。

 

         Sequences (an AUTO_INCREMENT column is a reasonable workaround, but still not a sequence)

       序列(一个自增列是一个合理的解决办法,但仍然不是一个完整意义上的序列)

 

         window functions

         窗口函数

 

         extensible data type system; of those, MySQL only supports enumerated types.

         可扩展的数据类型,MySQL只支持枚举类型。

 

         Against that list, MySQL can only pit "multi-master clustering". While I'm sure that's useful for some use cases, I remain unconvinced that it's a useful enough feature to have to deal with the administrative overhead that MySQL's multi-master clustering imposes upon you, or that it is worth losing all the above over.

         相对于以上列出的,MySQL仅仅在“多主集群”方面有竞争力。当然我也知道在一些用例下这功能非常牛逼,但我仍不相信这个有用的功能可以牛逼到处理其自身的管理开销,或者牛逼到使你放弃前面列出的全部特性。

 

         So it's my opinion that any database which fails to store data correctly in its default settings can't be anything but a toy; or that a database which has a comparatively small feature set can't be anything but a toy. But maybe that's just me.

         所以综上所述,我的观点就是:如果一个数据库的默认设置不能正确的储存数据,那么它除了玩具什么都不是;如果一个数据库的只有比较小的功能集,那么它除了玩具什么都不是。可能这么多人中只有我会坚持有这个观点吧~

 

你可能感兴趣的:(数据库)