to 野鬼-- mysql 可以保证你死在上面

宏哥 发布于 2012/07/13 09:56
阅读 843
收藏 3

@中山野鬼 ,

这个东西是专门给野鬼说的,有其业务背景. 其他的mysqler就不要进来捣乱了.

词汇表: 数据库 -- 除mysql以外的mssql,sybase,oracle,postgresql等.

Mysql不是数据库 -- 这是非常严谨而且审慎的说法. 原因如下:

1: 基于mysql的所有应用,本质上都是单表数据. 内生的问题,导致关联计算速度极慢,根据情况, 速度慢100倍到100万倍(根本无法查询) 之间. 所以应用的设计不得不做数据冗余. 直白的说, 你只能做单表的CRUD操作, 而且有很多情况,表都完全锁住. 这个和直接操作一个简单B+树,或者说操作一个文本几乎没有什么区别. Mysql只支持 Master->Detail的关系.而且必须分次查询.

仅此一点,就能让你在无穷无尽的数据一致性维护的黑洞当中无法自拔. 开发成本也极高. 无法建立关联的数据,将导致应用开发无法完成复杂的业务逻辑. 事实也证明,msyql上没有任何的复杂业务软件.

2: 事务. 即便innodb, 都无法支持ACIM级别事务. 任何的多个修改组成的一组操作,在并发下形成的竞争,都能导致你整个应用挂起,或者表锁住, 或者表文件损坏. 在任何 有价值 数据上,都应该严格禁止使用mysql. 

以上两点足够让你死在上面. 产生的成本以及问题你将无法承受.

如果mysql是一个数据库,它绝对是最昂贵的数据库.

客户根本不在乎你用什么数据库, 但是他们非常在乎数据, 绝对无法接受数据被锁,或者损坏, 或者无法查询. 这个问题远远超过数据库License 是否昂贵的问题而是致命的问题.

对于start from scratch 的项目, 必须严格禁止使用mysql.

以下情况可以例外:

1: 你想用discuz建立一个BBS或者类似osc的简单社区, 即便这种情况,所有涉及到账户, 资金的信息,都应该尽量用独立应用来管理. 将信息分离出去到数据库当中,并且,其他的所有业务都应该分离出这个bbs. 

2: 你只需要一个b+ 树,和其他信息没有任何关联, 只是做key->value的查询,并需要支持sql.

3: 你建立的是一个垃圾信息网. 信息不具备价值,信息直接不存在关联.你追求访问量.

决策:

1: 如果成本优先, postgresql是最好也是唯一的选择.

2: 根据业务模式, 首先商业数据库. 不仅提升产品价值, 而且让你减少很多麻烦. 商业数据库,如果考虑成本,mssql是首选. 考虑技术领先,毫无疑问,oracle.

3: 做出选择, 不要考虑数据库兼容. 数据库本质就是不兼容的.尽管它们很相似. 一开始锁定数据库,减少支持的数据库类型. 不同数据库,意味软件将有不同版本. 我现在写的sql,90%以上是无法在mysql当中执行的,如果我要兼容mysql, 几乎所有代码重写, 并且代码量需要上升一个数量级, 产品质量要下降N个数量级,或者说,完全不可用. 连oracle都不兼容,因为没有能力去支持不同数据库.

4: Postgres和oracle非常相近,但是仍然有巨大差异. Postgres在GIS应用有广泛成功案例.

加载中
0
mark35
mark35
简而言之,如果一个项目可以轻易放弃且不会有不可承受损失,那用mysql完全可以。否则使用mysql作为核心数据库那么就要做好被折腾的准备:表坏了修复表,库崩了找最近备份回复,数据完整性不正确了得大海捞孤儿,一个更新大量数据行的SQL执行到一半终止了……得,我可不能把你放到如此痛苦的世界中啊
1
zcfox
zcfox

看了两段关于oracle和mssql评论,有点被吓到了,感觉:1、兼容数据库的代价太昂贵了,犯得上这么干吗;2、好的程序绕不开平台特性,好的程序员也真的绕不开底层的东西……

数据库还是很重要的,数据库独立/中立在我看来都是鬼扯。只要你使用了update语句或者insert语句,你就已经和数据库绑定了。因为就算是insert和update在oracle和sqlserver中的实现都不一样。Oracle中查询是绝对不会有任何的锁的,inset和update也只有行级锁,而且只是锁DML语句,不会阻塞查询。SQLServer中是不同的。

sqlserver是基于短事务的,事务越快提交越好。而oracle是基于长事务的,事务越大越久提交就越好,频繁的提交事务会造成数据库压力过大。sqlserver的游标是基于锁表的,锁是很稀缺的资源。oracle的游标是基于历史版本的,锁是便宜的资源可以疯狂的使用而开销十分小。由于有这些不同,使得你得你同样的表结构在SqlServer中很好,但是在oracle中却慢得让人吃惊,反之亦然。

这不是能不能的问题(Oracle同样也能 在select 后面加for update 加锁)而是数据库默认行为的不同。数据库默认行为的不同是数据库内部的实现机制不同造成的。Oracle默认不加锁,而你去加锁是有问题的。SQL server默认是加锁,而你不加锁也必定会有问题的。这些数据库的行为会深深的影响你的应用的设计。

Oracle查询的时候不锁表是因为Oracle对每一行都是通过scn版本管理的。所以在查询的时候,你打开游标,你查到的只是那一个时刻的数据,之后的update和insert你在这个事先打开的游标中都查不到,所以没必要加锁。这种机制决定了某些机制,比如说众所周知Oracle是没有自动增长列的。而是通过sequence,就是受这个机制的影响。

还有比如说你要写一个ID生成器,其他的某些数据库的做法是先select然后update,这个做法在Oracle行不通!你必须要明确声明锁。但是如果你这么做了,你还是错了。如果你这样做,Oracle效率非常低。正确的做法还是通过sequence。

对于事务,Oracle里面提交一个有十万个inset update的事务,和提交一个只有一条update记录的事务开销基本相等,因为哪怕你没有提交这些数据就已经写到了硬盘上去了,commit和rollback只是给日志打个标记而已,而事物没有提交之前的查询呢?就是靠scn的版本管理来实现的。这样就决定了Oracle的事物应该保持,越晚提交越好。频繁的提交小事务只会造成cpu的开销过大。

Oracle里面不应该建临时表去用作查询的中间表(这样会产生严重的性能问题),而应该使用物化视图……

你会发现,我们现在还没用一个存储过程,没有用一个数据库函数,我们就已经如此容易地和数据库绑定了……

0
中山野鬼
中山野鬼

哈。多谢多谢。不过我仍然不碰oracle,如果碰数据库也只碰mysql。

mysql有mysql的不足,这个是肯定的。但mysql也有他好的一面,对于mysql的使用,首先不会让其去关联业务逻辑。而更多的当作存储引擎,以及操作些简单的数据库操作。

复杂的系统,基本直接在内存用C模块摆平。如果必要可以考虑多设备,分布并发计算。同时我们的态度,更多是考虑非动态的业务需求(如果涉及数据库)。

各个业务可能不太一样,哈。当然不排除跑出来个BI或者其他的ERP或OA系统,那后台该挂什么挂什么。。。

0
宏哥
宏哥

引用来自“中山野鬼”的答案

哈。多谢多谢。不过我仍然不碰oracle,如果碰数据库也只碰mysql。

mysql有mysql的不足,这个是肯定的。但mysql也有他好的一面,对于mysql的使用,首先不会让其去关联业务逻辑。而更多的当作存储引擎,以及操作些简单的数据库操作。

复杂的系统,基本直接在内存用C模块摆平。如果必要可以考虑多设备,分布并发计算。同时我们的态度,更多是考虑非动态的业务需求(如果涉及数据库)。

各个业务可能不太一样,哈。当然不排除跑出来个BI或者其他的ERP或OA系统,那后台该挂什么挂什么。。。

如果是 key--> value, 你可能需要的是 http://fallabs.com/tokyocabinet/.

等吃了苦头就知道了.

宏哥
宏哥
回复 @中山野鬼 : 我提到的这个cabinet 不仅可以嵌入使用,而且可以服务方式提供. 尺寸非常小. 非常健壮.支持hash, B+ tree, Fixed length,On memory 几种模式. 宏哥一贯作风,验证过才说.
中山野鬼
中山野鬼
回复 @mark35 : 哈。。。你咋这么了解我呢。我只想做nosql..
宏哥
宏哥
回复 @mark35 : 这个tokyocabinet 实现的key->value对非常高级,可以支持好几种模式,比mysql强多了.
mark35
mark35
感觉mysql高不成低不就,技术上比不过pg,现在key/value上面又面临nosql的竞争
0
StormFour
StormFour

引用来自“zcfox”的答案

看了两段关于oracle和mssql评论,有点被吓到了,感觉:1、兼容数据库的代价太昂贵了,犯得上这么干吗;2、好的程序绕不开平台特性,好的程序员也真的绕不开底层的东西……

数据库还是很重要的,数据库独立/中立在我看来都是鬼扯。只要你使用了update语句或者insert语句,你就已经和数据库绑定了。因为就算是insert和update在oracle和sqlserver中的实现都不一样。Oracle中查询是绝对不会有任何的锁的,inset和update也只有行级锁,而且只是锁DML语句,不会阻塞查询。SQLServer中是不同的。

sqlserver是基于短事务的,事务越快提交越好。而oracle是基于长事务的,事务越大越久提交就越好,频繁的提交事务会造成数据库压力过大。sqlserver的游标是基于锁表的,锁是很稀缺的资源。oracle的游标是基于历史版本的,锁是便宜的资源可以疯狂的使用而开销十分小。由于有这些不同,使得你得你同样的表结构在SqlServer中很好,但是在oracle中却慢得让人吃惊,反之亦然。

这不是能不能的问题(Oracle同样也能 在select 后面加for update 加锁)而是数据库默认行为的不同。数据库默认行为的不同是数据库内部的实现机制不同造成的。Oracle默认不加锁,而你去加锁是有问题的。SQL server默认是加锁,而你不加锁也必定会有问题的。这些数据库的行为会深深的影响你的应用的设计。

Oracle查询的时候不锁表是因为Oracle对每一行都是通过scn版本管理的。所以在查询的时候,你打开游标,你查到的只是那一个时刻的数据,之后的update和insert你在这个事先打开的游标中都查不到,所以没必要加锁。这种机制决定了某些机制,比如说众所周知Oracle是没有自动增长列的。而是通过sequence,就是受这个机制的影响。

还有比如说你要写一个ID生成器,其他的某些数据库的做法是先select然后update,这个做法在Oracle行不通!你必须要明确声明锁。但是如果你这么做了,你还是错了。如果你这样做,Oracle效率非常低。正确的做法还是通过sequence。

对于事务,Oracle里面提交一个有十万个inset update的事务,和提交一个只有一条update记录的事务开销基本相等,因为哪怕你没有提交这些数据就已经写到了硬盘上去了,commit和rollback只是给日志打个标记而已,而事物没有提交之前的查询呢?就是靠scn的版本管理来实现的。这样就决定了Oracle的事物应该保持,越晚提交越好。频繁的提交小事务只会造成cpu的开销过大。

Oracle里面不应该建临时表去用作查询的中间表(这样会产生严重的性能问题),而应该使用物化视图……

你会发现,我们现在还没用一个存储过程,没有用一个数据库函数,我们就已经如此容易地和数据库绑定了……

想实现跨数据库平台的都是脑残。想实现跨数据库平台的平台只是简单的CRUD的集合,没什么技术含量。
中山野鬼
中山野鬼
哈。过来人。。。。。本来大家就应该用数据库来解决实际问题。但凡琢磨如何用抽象出来的各个工具的统一接口去解决问题的,都没有什么好下场。最终最好的结果也会导致工具和解决方案的耦合度太低。
0
mark35
mark35

引用来自“中山野鬼”的答案

哈。多谢多谢。不过我仍然不碰oracle,如果碰数据库也只碰mysql。

mysql有mysql的不足,这个是肯定的。但mysql也有他好的一面,对于mysql的使用,首先不会让其去关联业务逻辑。而更多的当作存储引擎,以及操作些简单的数据库操作。

复杂的系统,基本直接在内存用C模块摆平。如果必要可以考虑多设备,分布并发计算。同时我们的态度,更多是考虑非动态的业务需求(如果涉及数据库)。

各个业务可能不太一样,哈。当然不排除跑出来个BI或者其他的ERP或OA系统,那后台该挂什么挂什么。。。

个人看法,所谓mysql好的那面只停留在美好的愿望和痛苦的回忆中 。当应用运行相当长一段时间、数据量增加相当数量之后,mysql的弱点将会让你非常痛苦。

以disczu为例,正好这段时间我对其有研究及hack。数据的逻辑完整性只在php应用层上面实现,数据库(dz只支持mysql myisam)上无法实现。其结果是随着功能的增加逻辑bug越来越多,且导致数据层面的逻辑错误也增加。最后就会出现一堆开发人员很难重现但使用者却又经常遇到的bug。 参考这个: http://www.discuz.net/forum.php?mod=viewthread&tid=2934412

 

 

 

mark35
mark35
回复 @宏哥 : mysql果然很贵~
宏哥
宏哥
回复 @mark35 : 项目前后投入的人力,资源, 应该有好几十万.
宏哥
宏哥
回复 @mark35 : 国内最大的F L 网老大是我的朋友.他们就是用mssqler + asp. 后来听某个mysqler说lamp速度快. 就上了一个新项目,想要做切换, 结果, 一上就挂掉. 那个mysqler被fire掉了. 他们是用dvbbs改的.最早的版本.
mark35
mark35
回复 @宏哥 : 不过说回来用mysql跑个web,数据量几万或者一百万以下到真没啥问题。此应用没啥价值,表坏了无所谓,数据库崩了打不了不做这个重新建个新站啦~ 如果用户几十万,上千万帖子的论坛,用mysql跑着还是得很小心的。
宏哥
宏哥
@中山野鬼 , 这位是真的吃过苦头的. 不是我的托!
0
宏哥
宏哥

引用来自“mark35”的答案

简而言之,如果一个项目可以轻易放弃且不会有不可承受损失,那用mysql完全可以。否则使用mysql作为核心数据库那么就要做好被折腾的准备:表坏了修复表,库崩了找最近备份回复,数据完整性不正确了得大海捞孤儿,一个更新大量数据行的SQL执行到一半终止了……得,我可不能把你放到如此痛苦的世界中啊

"如果一个项目可以轻易放弃且不会有不可承受损失,那用mysql完全可以"

-- mysql 最合适 的应用场景.

0
宏哥
宏哥

回复 @中山野鬼 :  这个才是你要的.

0
一千年前的人
一千年前的人

哈哈    宏哥 来推广一下pg, 把mysqler都收了吧, 怎么样。。。

0
宏哥
宏哥

引用来自“一千年前的人”的答案

哈哈    宏哥 来推广一下pg, 把mysqler都收了吧, 怎么样。。。

数据库这个东西,和mysqler去说,鸡同鸭讲, 没有必要浪费力气.
返回顶部
顶部