负责的项目要迁移到Sybase,本身工期就紧,而数据库迁移的事情谁都不提。公司的DBA即没有Sybase的经验,又没有时间搭理我们。手下几个兄弟都在忙着赶工,于是决定自己干,NND!

项目原有的架构中对数据库的访问是用Hibernate对JDBC进行了封装。所以程序方面需要处理一下问题:

1.       Hibernate映射文件(.hbm.xml)

2.       建表SQL

3.       代码和原始数据插入脚本

首先说映射文件,最初是数据类型这个不难只是要多加注意,下面给出用到的对应关系表

Oracle数据类型(不分大小写) Sybase数据类型(均为小写)
Char Char
Varchar2 Varchar
Number(m,n) Numeric(m,n)
Date Datetime
Timestamp(6) Datetime
Integer Int

另外Oracle的主键是依赖sequence的,Sybase跟mySQL一样是依赖自增列做主键的。所以把映射文件中id.class属性改成native(后面有关sequence的配置可以不改,这样就可以适用与所有数据库了)。

建表SQL是从映射文件由程序生成的,把映射文件改好后,建表SQL就有了,但这里注意需要人工在最后一句drop table语句后和文件末尾增加go命令,和SQL99中Commit一个效果。这里注意:DDL语句在Oracle中是自动提交的,但是在Sybase中是存在在一个事务里面。

原始数据脚本的修改更让人感觉可笑,Sybase是用回车作为SQL的结尾,而Oracle是’;’,所以原始数据脚本中出现回车断行的统统都要改成1行,谢天谢地,还有正则表达式帮忙,一个替换全部搞定(也许有更好的办法,偶也是刚刚接触Sybase,所以如果有还望不吝赐教)。另外就是Sybase不支持从字符串类型到数字类型的隐式转换(愤怒,简直笨死了)。

大体的思路就是如上,由于我们是开发,所以数据库配置管理、调优什么的统统不管,能玩就行。下面我想说说我在今天一天的痛苦经历中总结的经验和遇到的问题:

1.                  IDENTITY_INSERT问题,如果您用M$的产品,那么可以跳过这条看后面去了。Sybase默认对identity的字段是不允许insert和update的,所以需要设置IDENTITY_INSERT选项,这个选择虽说是针对某个表设置的,但如果你对表A打开设置后,你就不能再对表B设置它了,这点要切记。在M$的文档帮助下(就是微软的文档,这里不得不感叹微软文档写得好啊。PS:Sybase和M$数据库产品都是使用一样的SQL语言叫Transact-SQL),终于解决此问题,下面给出SQL样本:

SET IDENTITY_INSERT table_name ON

Insert into table_name values ……

Update table_name set ……

SET IDENTITY_INSERT dbo.Tool OFF

2.                  中文字符集的问题,测试表结构和数据都准备好了,然后兴致冲冲的启动Tomcat,发现从数据库中读出的中文都是乱码,那个叫汗。最后,还要感谢万能的互联网,感谢无私的汪涛,具体解决方案,看这里。当然,在这里我也做了一些扩展,自己制作了cp936的nocase排序,解决了Sybase对表名、列名大小写的区分,呵呵,具体方法?原谅我卖个官子,万能的互联网吧,很简单的:)

使用Sybase开发要注意的几个问题:

1.                  虽然Sybase对DML语句不区分大小写,但是对数据类型是区分大小写的,而且是只认小写。

2.                  Sybase和Oracle差不多都是按数据库、用户管理表、数据、存储过程和各种用户对象的,但由于其提供的用户角色实在太少,而且很不方便,所以建议一个用户单独建立一个数据库,并为设置其为该数据库的owner,这样在开发过程中能省去不少麻烦。

3.                  分配足够的数据库空间,本身开发数据库不会像生产数据库那样硕大无比。目前还没有弄清楚数据库空间自增如何配置,这点确实没有oracle方便,但是一旦数据库满了,就把所有事情都阻塞了,但是只是给出警告说日志段空间接近不足,某些事务可能被阻塞。

4.                  重视自动化测试,一旦数据库移植完成,立刻跑测试,能发现很多问题。

最后,刚刚接触Sybase,欢迎大家提出意见,也希望有机会多多交流,共同进步。