数据库迁移
最近在做oracle到mysql數據庫遷移的工作,找了很多工具都不是很給力,因為原數據庫設計的不好,字段命名也不規范遇到了很多問題,最后拿出最終兵器kettle來解決。雖然使用麻煩了,但它使人工干預遷移工作成為了可能。然后還需記住一些數據庫特性上的區別,轉載如下
?
1、數據庫遷移需要做的工作
1.1?建表腳本修改
1.2?數據導入(編碼、數據類型設置)
1.3?項目中的SQL修改
1.4?數據庫連接(驅動)
1.5?連接項目中的程序,測試并修改程序
2、常用數據庫中在開發方面的不同
2.1?數據類型
2.2?自增
2.3?分頁
2.4?內置函數
2.5?模糊查詢
3、ORM工具與遷移
使用hibernate、ibatis,在數據庫遷移中的不同效率
4、各數據庫的不同數據類型比較及參考資料
4.1、MySQL中的建表SQL
4.2、Java到SQL數據類型影射表
4.3、?MySql與Oracle數據類型的相互轉化
4.4、ORACLE與SQLSERVER、MYSQL的數據類型對照表
?
1、數據庫遷移需要做的工作
1、1?數據庫建表腳本的修改
1.1.1?由于各種數據庫的數據類型并不相同,需要更改部分數據類型。
1.1.2?在MySQL腳本里暫不能給日期數據設置當前時間,字段如:registertime(注冊時間);需在程序中設置當前日期,再保存進數據庫或將registertime設置為時間戳(timestamp)
1.1.3?在MySQL里的表和字段的注釋,見【5】中的建表語句。
1、2?將數據導入到目標數據庫的中(其中可以需要修改數據類型)
1.2.1設置數據庫的編碼,防止中文亂碼
1)、最簡單的修改方法,就是修改mysql的my.ini文件中的字符集鍵值,
如:default-character-set?=?utf8
(character_set_server?=?utf8)
修改完后,重啟mysql的服務,service?mysql?restart
2)、還有一種修改字符集的方法,就是使用mysql的命令,如:
mysql>?SET?character_set_client?=?utf8?;mysql>?SET?character_set_connection?=?utf8?;
mysql>?SET?character_set_database?=?utf8?;mysql>?SET?character_set_results?=?utf8?;mysql>?SET?character_set_server?=?utf8?;mysql>?SET?collation_connection?=?utf8?;mysql>?SET?collation_database?=?utf8?;?mysql>?SET?collation_server?=?utf8?;
如果:沒有設置前兩條,可以通過以下方式實現編碼:
a?建數據庫時?設置數據庫支持的編碼:create?database?datmart?charset=utf8;?b?使用數據庫datmart?use?datmart;?c?插入中文數據時,需要先設置:set?names?utf8;?d?將?數據導入?source?d:/datmart.sql
(每個見表語句后加:ENGINE=MyISAM??DEFAULT?CHARSET=utf8;)
1.2.2?數據類型
即使MySQL中有bit,但SQLServer中的bit類型(取0或1,分別對應了bool的true和false)的變量在MySQL中,不能順利導入。需要將其設置為tinyint(1),才能順利導入。
12.3導入數據
?采用第三方工具,如Navicat?8,通過微軟提供的ODBC連接數據源,并導入數據或者自己寫一個通用程序,將全部數據讀入在寫進新的數據庫中。
1、3?修改項目中的SQL,使得SQL在目標數據庫里也可以使用
1.4?數據庫連接(下載驅動)
SQLServer的數據庫連接:
datamart_driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
datamart_url=jdbc:sqlserver://172.16.6.23:1433;DatabaseName=datamart
MySql的數據庫連接:
datamart_driver=com.mysql.jdbc.Driver
datamart_url=jdbc:mysql://172.16.6.23:3306/datamart
Oracle的數據庫連接:
datamart_driver=oracle.jdbc.driver.OracleDriver
datamart_url=jdbc:oracle:thin:@172.16.6.26:1521:datamart
用戶名和密碼都是:
datamart_username=root
datamart_password=sd100301
2、常用數據庫中在開發方面的不同
2.1?分頁、2.2內置函數、2.3自增??2.4存儲過程?2.5模糊查詢
2.1?分頁
Oracle中的分頁:可以采用rownumber實現;SQLServer中的分頁,采用內容函數row_number()?實現;MySQL中采用limit。
Oracle中的SQL:
?select?rn,first_name,salary
?from(select?rownum?as?rn,frist_name,salary
??????from?(select?first_name,salary?from?s_emp?order?by?salary))?
?where?rn?between?11?and?20
SQLServer中的SQL:
select?*?from(?select?row_number()?over(order?by?salary?desc)?as?rownumber,*??????
?????????????from?s_emp??where?salary>3000
???)?as?tb?
where??rownumber?between?11?and?20
MySQL中基本的SQL:
select?*?from?apiinfo?where?id<41
order?by?enname?desc
limit?5,200
2.2?內置函數
數據庫中有許多內置函數,不少是用于處理字符串、日期等的。
SQLServer的len(),相當于MySQL的length(),相當于Oracle的Len().
2.3?自增
2.3.1?自增關鍵字?
Oralce:?SQLServer:?identity?MySQL:auto_increment
2.3.2?Oracle中的自增(序列號):
定義:CREATE?SEQUENCE?emp_sequence????????
INCREMENT?BY?1???--?每次加幾個????????
START?WITH?1?????--?從1開始計數????????
NOMAXVALUE???????--?不設置最大值????????
NOCYCLE??????????--?一直累加,不循環????????CACHE?10;
使用:emp_sequence.CURRVAL??????emp_sequence.NEXTVAL??
2.3.3?自增帶來的問題及其解決
問題:(oracle中的自增字段,如果它的值不是連續的,并且您將其做為主鍵,那么遷移到其它數據庫時候,那些不連續的值發生了改變。而其它表是與該字段關聯的,這樣程序就會出錯)
解決方式:在目標數據庫中建立統一的表,并有同樣的字段但不自增;導入數據后,再修改表的結構,使得該字段自增。
2.3.4?自己實現id字段的自增的SQL語句
insert?into?orderApi?(id,ordernumber,apiid)
select?distinct?IFNULL((select?max(id)+1?from?orderApi),1),#ordernumber#,#apiid#?
from?orderApi??group?by?id
2.4?存儲過程
不同的數據庫存儲過程相差的比SQL間的差異到大,所以項目中的存儲過程需要改不少地方?;蛘?#xff0c;如果對性能影響不大,可以不用存儲過程。
2.5?模糊查詢
在SQLServer中,模糊查詢可以使用?
select?*?from?apiinfo?where?cnname?like?#key#+'%';
但在MySql中,則需改為:
select?*?from?apiinfo?where?cnname?'%$key$%'
or
select?*?from?apiinfo?where?cnname?like?REGEXP?'^['+#key#+']'
注:#key#,是方法中傳入的值;MySQL中的SQL使用了REGEXP,是正則表達式
?
3、ORM工具與遷移
使用hibernate、ibatis,在數據庫遷移中的不同效率
ibatis:sql需要自己寫?hibernate:sql自動生成;
Hibernate的特點:?Hibernate功能強大,數據庫無關性好,O/R映射能力強,如果你對Hibernate相當精通,而且對Hibernate進行了適當的封裝,那么你的項目整個持久層代碼會相當簡單,需要寫的代碼很少,開發速度很快。
iBATIS的特點:?iBATIS入門簡單,即學即用,提供了數據庫查詢的自動對象綁定功能,而且延續了很好的SQL使用經驗,對于沒有那么高的對象模型要求的項目來說,相當完美。iBATIS的缺點就是框架還是比較簡陋,功能尚有缺失,雖然簡化了數據綁定代碼,但是整個底層數據庫查詢實際還是要自己寫的,工作量也比較大,而且不太容易適應快速數據庫修改。
易遷移行比較:對于數據庫遷移來說,常用的數據庫操作,如增刪改查等,在hibernate中基本不需要改動;而ibatis中是自己寫的針對特定數據庫類型的SQL,所以需要改不少內容。
?
4、各數據庫的不同數據類型比較及參考資料
4.1?MySQL中的建表SQL:
CREATE?TABLE?`apiindicator`?(
??`id`?int(11)?NOT?NULL,
??`apiid`?int(11)?DEFAULT?NULL?COMMENT?'關聯api信息表(apiinfo)id',
??`cnname`?varchar(100)?DEFAULT?NULL?COMMENT?'指標中文名',
??`enname`?varchar(60)?DEFAULT?NULL?COMMENT?'指標英文名?',
??`description`?varchar(1000)?DEFAULT?NULL,
??`datatype`?varchar(15)?DEFAULT?NULL,?`isout`?bit?DEFAULT?'1'?COMMENT??'是否必須輸出?,默認為輸出;0:不輸出?1:輸出',
??`state`?int(11)?DEFAULT?'0',
??`isdelete`?bit?DEFAULT?'0'?COMMENT?'刪除標記:0未刪除;1已刪除',
??PRIMARY?KEY?(`id`)
)?ENGINE=MyISAM?DEFAULT?CHARSET=utf8?COMMENT='Api指標表?';
?
4.2:Java到SQL數據類型影射表
| String | VARCHAR?or?LONGVARCHAR |
| java.math.BigDecimal | NUMERIC |
| Boolean | BIT |
| Byte | TINYINT |
| Short | SMALLINT |
| Int | INTEGER |
| Long | BIGINT |
| Float | REAL |
| Double | DOUBLE |
| byte[] | VARBINARY?or?LONGVARBINARY |
| java.sql.Date | DATE |
| java.sql.Time | TIME |
| java.sql.Timestamp | TIMESTAMP |
?
4.3?MySql與Oracle數據類型的相互轉化
| BIGINT | NUMBER(19,?0) |
| BIT | RAW |
| BLOB | BLOB,?RAW |
| CHAR | CHAR |
| DATE | DATE |
| DATETIME | DATE |
| DECIMAL | FLOAT?(24) |
| DOUBLE | FLOAT?(24) |
| DOUBLE?PRECISION | FLOAT?(24) |
| ENUM | VARCHAR2 |
| FLOAT | FLOAT |
| INT | NUMBER(10,?0) |
| INTEGER | NUMBER(10,?0) |
| LONGBLOB | BLOB,?RAW |
| LONGTEXT | CLOB,?RAW |
| MEDIUMBLOB | BLOB,?RAW |
| MEDIUMINT | NUMBER(7,?0) |
| MEDIUMTEXT | CLOB,?RAW |
| NUMERIC | NUMBER |
| REAL | FLOAT?(24) |
| SET | VARCHAR2 |
| SMALLINT | NUMBER(5,?0) |
| TEXT | VARCHAR2,?CLOB |
| TIME | DATE |
| TIMESTAMP | DATE |
| TINYBLOB | RAW |
| TINYINT | NUMBER(3,?0) |
| TINYTEXT | VARCHAR2 |
| VARCHAR | VARCHAR2,?CLOB |
| YEAR | NUMBER |
?
4.4?ORACLE與SQLSERVER、MYSQL的數據類型對照表
?
| Oracle?數據類型 | SQL?Server?數據類型 | Mysql數據類型 |
| BFILE | VARBINARY(MAX) | ? |
| BLOB | VARBINARY(MAX) | BLOB,?LONGBLOB,?MEDIUMBLOB |
| CHAR([1-2000]) | CHAR([1-2000]) | CHAR |
| CLOB | VARCHAR(MAX) | TEXT,?LONGTEXT,?MEDIUMTEXT |
| DATE | DATETIME | DATE,DATETIME,?TIME,?TIMESTAMP |
| FLOAT | FLOAT | REAL, DECIMAL,?DOUBLE,?DOUBLE?PRECISION |
| FLOAT([1-53]) | FLOAT([1-53]) | |
| FLOAT([54-126]) | FLOAT | |
| INT | NUMERIC(38) | ? |
| INTERVAL | DATETIME | ? |
| LONG | VARCHAR(MAX) | ? |
| LONG?RAW | IMAGE | ? |
| NCHAR([1-1000]) | NCHAR([1-1000]) | ? |
| NCLOB | NVARCHAR(MAX) | ? |
| NUMBER | FLOAT | INT,?INTEGER,?NUMERIC,?YEAR,?MEDIUMINT |
| NUMBER([1-38]) | NUMERIC([1-38]) | SMALLINT,?TINYINT,?BIGINT |
| NUMBER([0-38],[1-38]) | NUMERIC([0-38],[1-38]) | ? |
| NVARCHAR2([1-2000]) | NVARCHAR([1-2000]) | SET,?VARCHAR,?ENUM |
| RAW([1-2000]) | VARBINARY([1-2000]) | BLOB,BIT,?TINYBLOB,?LONGTEXT,?LONGBLOB,?MEDIUMBLOB,?MEDIUMTEXT |
| REAL | FLOAT | ? |
| ROWID | CHAR(18) | ? |
| TIMESTAMP | DATETIME | ? |
| UROWID | CHAR(18) | ? |
| VARCHAR2([1-4000]) | VARCHAR([1-4000]) | TEXT,?TINYTEXT |
?
轉載于:https://www.cnblogs.com/muyuge/archive/2011/04/26/6152560.html
總結
- 上一篇: 手机版python3.6.6的reque
- 下一篇: SQL Server 文件规划 -位置规