Oracle迁移MySql开发注意事项

转至元数据结尾
转至元数据起始

问题1:Oracle与MySQL的数值类型匹配

 

number(1) = int(1) 正确,但不合理,number(1) = Tinyint(2)
number(5) = int(5) 正确,但不合理,number(5) = Smallint(5)
number(12) = int(12) 错误,number(12) = Bigint(12) 

 

解答:

Oracle数值类型 number(M)的含义:M是可存储的数值长度

测试结果如下:

create table t_num (num1 number(1));

SQL> insert into t_num values (1);

1 row created.

SQL> insert into t_num values (10);
insert into t_num values (10)
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column

create table t_num2 (num1 number(2));
insert into t_num values (10);

SQL> insert into t_num2 values (10);

1 row created.

SQL> insert into t_num2 values (1);

1 row created.

SQL> insert into t_num2 values (100);
insert into t_num2 values (100)
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column

 

通过测试可以发现 number(1),只能存放1个长度的数值,与存储范围无关。

Mysql的数据类型含义:

Tinyint(m):Tinyint代表了取值范围(-128-127),而m代表了显示宽度,无其它意义,只有在[UNSIGNED][ZEROFILL]同时满足时才起作用,长度不够,用0来填充

mysql> create table m_num (num1 tinyint(1));
Query OK, 0 rows affected (0.01 sec)

mysql> insert into m_num values (1);
Query OK, 1 row affected (0.84 sec)

mysql> insert into m_num values (10);
Query OK, 1 row affected (0.00 sec)

mysql> insert into m_num values (100);
Query OK, 1 row affected (0.00 sec)

mysql> insert into m_num values (127);
Query OK, 1 row affected (0.00 sec)

mysql> insert into m_num values (128);
ERROR 1264 (22003): Out of range value for column 'num1' at row 1

mysql> select * from m_num;
+------+
| num1 |
+------+
| 1 |
| 10 |
| 100 |
| 127 |
+------+
4 rows in set (0.00 sec)

 

通过实验可以发现tinyint(1),只能存储(-128-127)范围的数值,其中tinyint(1)中的1,没有起到什么作用,对于存储不会造成任何影响。

对于数值类型建议采用无符号型,这样数值范围不会从负值开始,范围扩大一倍:如:age tinyint(3) unsigned

 

关于Mysql int(M)的问题解答:

关于Mysql数值类型:如 int(M):其中M仅表示显示宽度,如数值宽度没有达M时,则用0来填充,超过了M时,则不做处理,不会影响数据存储。因此M值建议与数据最大范围值宽度相同即可,但是如果不设置零填充式(ZEROFILL),Mysql将会忽略那个字符宽度

测试结果如下:

mysql> create table m_num2 (id int(8) UNSIGNED ZEROFILL);
Query OK, 0 rows affected (0.00 sec)

mysql> insert into m_num2 values (1);
Query OK, 1 row affected (0.00 sec)

mysql> select * from m_num2;
+----------+
| id |
+----------+
| 00000001 |
+----------+
1 row in set (0.00 sec)

mysql> insert into m_num2 values (10000000);
Query OK, 1 row affected (0.01 sec)

mysql> insert into m_num2 values (1000000000);
Query OK, 1 row affected (0.00 sec)

mysql> select * from m_num2;
+------------+
| id |
+------------+
| 00000001 |
| 10000000 |
| 1000000000 |
+------------+
3 rows in set (0.00 sec)

 

 

问题2:Oracle与MySQL的字符类型匹配

2种数据库都支持两种基本字符类型,但存储方式却完全不同
Char
Varchar

 

Oracle字符类型的使用:

oracle  varchar2(20) 标识字段最多可以容纳20个字节,汉字的占用字节需要依赖具体的数据库编码确定

测试结果如下:

drop table t_char purge;
create table t_char (name varchar2(12));
insert into t_char values ('陈好陈好');

1 row created.

insert into t_char values ('陈好陈好1');
ERROR at line 1:
ORA-12899: value too large for column "SCOTT"."T_CHAR"."NAME" (actual: 13,maximum: 12)

结论:当前字符集是中文字符集,一个汉字3个字节,所以varchar2(12)只能存储3个汉字,因此关于varchar2(M),其中M设多大,是根据要存储的字符数与字符集占用字节换算得来 。

 

mysql字符类型的使用::
mysql varchar(20) 表明字段可以容纳20个字符的字符串,汉字字母均为一个字符;

测试结果如下:

create table t_char (name varchar(12));


insert into t_char values ('陈好陈好');

Query OK, 1 row affected (0.00 sec)
insert into t_char values ('陈好陈好陈好陈好');

Query OK, 1 row affected (0.00 sec)

mysql> insert into t_char values ('陈好陈好陈好陈好陈好陈好');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t_char values ('陈好陈好陈好陈好陈好陈好1');
ERROR 1406 (22001): Data too long for column 'name' at row 1

mysql> select * from t_char;
+--------------------------------------+
| name |
+--------------------------------------+
| 陈好陈好 |
| 陈好陈好陈好陈好 |
| 陈好陈好陈好陈好陈好陈好 |
+--------------------------------------+
3 rows in set (0.00 sec)

结论:当前字符集是UTF8字符集,varchar(12)限制只能存储12个汉字,varchar(M),M值是要存储的字符数(不分中文字符和西欧字符),但最大存储限制是受到varchar的最大65535长度的限制,对于UTF8而言,最大也只能存储21845个汉字。

 

问题3:Oracle与MySQL的日期类型匹配

 

Oracle date、timestamp类型与Mysql datetime类型相对应

测试结果如下:

oracle:
alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; 
create table test(order_date date); 
insert into test values('2015-09-16 10:00:00');

SQL> select * from test;

ORDER_DATE
-------------------
2015-09-16 10:00:00


mysql:
create table test(order_date datetime); 
insert into test values('2015-09-16 10:00:00'); 
mysql> select * from test;
+---------------------+
| order_date |
+---------------------+
| 2015-09-16 10:00:00 |
+---------------------+
1 row in set (0.00 sec)

 

Oracle timestamp类型与Mysql timestamp类型则不相对应

Mysql TimeStamp类型的范围:1970-01-01 08:00:01 至2038-12-31 23:59:59,并与时区有关,会出现时区转换。

 

数据库表字段类型设计的原则:

1.采用正确的字段类型,如是否采用timestamp类型

2.采用合适的字段类型,如字段表示人的年龄,则Tinyint类型最为合适(只用一个字节来存储,性能与空间都很优),因为没有人能活到256岁,除非是神仙。

请使用浏览器的分享功能分享到微信等