数据库
1、数据库优化
分析:哪些语句或者操作影响SQL的效率,对此改善
(1).从jdbc角度去讲预执行PreparedStatement比Statement性能高,
(2).sql语句全部大写,特别是表名和字段名,这是由于数据库中语句的执行机制是这样的,
(3).增加索引的使用,查询数据库中的表示,通过索引来提高性能
(4).从物理存储角度出发,分区,也就是读写分离,分库分表
(5).使用缓存机制,将第一次查询的数据保存,下次直接从缓存中拿;
(6).SQL语句避免使用”*”,使用字段名或者其他代替,
(7).避免使用<>或者!=
(8). 不要在where条件中使用左右两边都是%的like模糊查询
(9). 尽量不要使用or,会造成全表扫描
(10). 对于连续的数值,能用 between 就不要用 in
(11). 不要在where字句中的“=”左边进行函数、算术运算或其他表达式运算
2、索引的创建及失效
在执行CREATE TABLE语句时可以创建索引,也可以单独用CREATE INDEX或ALTER TABLE来为表增加索引。
修改表索引
ALTER TABLE table_name ADD INDEX index_name (column_list)
ALTER TABLE table_name ADD UNIQUE (column_list)
ALTER TABLE table_name ADD PRIMARY KEY (column_list)
1、ALTER TABLE修改表索引
alter table 表名 add 索引类型 索引名称(字段列表);
2.CREATE INDEX创建索引(表存在)
CREATE INDEX可对表增加普通索引或UNIQUE索引。
CREATE INDEX index_name ON table_name (column_list)
CREATE UNIQUE INDEX index_name ON table_name (column_list)
table_name、index_name和column_list具有与ALTER TABLE语句中相同的含义,索引名不可选。另外,不能用CREATE INDEX语句创建PRIMARY KEY索引。
create index 索引名 on 表名(字段列表);
3、创建表的时候指定索引
CREATE TABLE 表名( […], INDEX [索引的名字] (列的列表) );
何时不使用索引
1.表记录太少;
2.数据重复且分布平均的字段(只有很少数据值的列);
3.经常插入、删除、修改的表要减少索引;
4.text,image等类型不应该建立索引,这些列的数据量大(假如text前10个字符唯一,也可以对text前10个字符建立索引);
5.MySQL能估计出全表扫描比使用索引更快时,不使用索引;
需要建立索引的情况
1、经常用于搜索的列;
2、经常用于连接查询的列;
3、经常需要排序的列;
4、经常用于where子句的列上。
不适合建立索引的情况
1、查询中很少使用的列;
2、对于很少数据值的列,例如性别;
3、对于数据量很大或者很小的列如text, image和bit不适合建索引;
4、修改的性能大于检索的性能时不适合建索引。
5、表记录太少;
索引失效的情况
1、组合索引中不能有列为null,如果存在则该列索引将会失效;
2、select中索引只能用一次,如果再where使用,则order by中就不要用了;
3、模糊查询中,like "%aa%"将会使索引失效,但是后模糊不会例如like “aa%”;
4、索引列上使用表达式或者函数会使索引失效而进行全表扫描(在查询条件中使用正则表达式时,只有在搜索模板的第一个字符不是通配符的情况下才能使用索引。);
5、在查询条件中使用IS NULL或者IS NOT NULL会导致索引失效;
6、类型不一致进行查询会导致索引失效,如字符串不加引号会使索引失效;
7、or连接多个条件会使索引失效,除非or的条件都加了索引或者改成union all连接;
8、如果排序的字段使用了索引,那么select的字段也要是索引字段,否则索引失效。特别的是如果排序的是主键索引则select * 也不会导致索引失效;
9、尽量不要包括多列排序,如果一定要,最好为这队列构建组合索引;
10、查询中使用"!= " 、 “>” 、 " < "会使索引失效,但是对主索引或者整形类型的索引使用的话则不会失效。
3、简述建立索引的作用和索引的分类 ?
**索引的作用:**通过使用索引,大大提高数据库的检索速度,改善数据库性能.
**1.**从逻辑角度分为:
1、主键索引(PRIMARY KEY):主键索引是一种特殊的唯一索引,不允许有空值
2、普通索引(INDEX)或者单列索引
3、多列索引(复合索引):复合索引指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用复合索引时遵循最左前缀集合
4、唯一索引(UNIQUE)或者非唯一索引
5、空间索引:空间索引是对空间数据类型的字段建立的索引,MYSQL中的空间数据类型有4种,分别是GEOMETRY、POINT、LINESTRING、POLYGON。
MYSQL使用SPATIAL关键字进行扩展,使得能够用于创建正规索引类型的语法创建空间索引。创建空间索引的列,必须将其声明为NOT NULL,空间索引只能在存储引擎为MYISAM的表中创建
2. 从物理存储角度
1.聚集索引(clustered index)
在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。 如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。
2.非聚集索引(non-clustered index)
4、SQL注入
SQL注入:发生在Web应用对后台数据库查询语句处理存在的安全漏洞;
通常SQL注入方法有两种:
\1. 后台身份验证绕过漏洞,
利用的就是AND和OR的运算规则,在拼接的数据后输入’or 1=1#
例如,SQL=”select * from user where username=’”+username+”’and password=’”+password+”’”;
Username=’or 1=1#,password 随便写;
select * from users where username=’’ or 1=1#’ and password=balabala
防止SQL注入:PreparedStatement采用预编译语句集,它内置了处理SQL注入的能力,只要使用它的setXXX方法传值即可, 而PreparedStatement已经准备好了,执行阶段只是把输入串作为数据处理,而不再对sql语句进行解析
\2. 通过ASCII码拆半法猜测表名、类名(了解)
5、内连接与外连接
1.内连接查询
1.1隐式内连接
SELECT 字段列表 FROM 表名1,表名2 WHERE 表名1.列名=表名2.列名;
1.2显示内连接
SELECT 字段列表 FROM 表名1 JOIN 表名2 ON 条件;
2.外连接查询
2.1左外连接
SELECT 字段列表 FROM 表名1 LEFT JOIN 表名2 ON 条件;
2.2右外连接
SELECT 字段列表 FROM 表名1 RIGHT JOIN 表名2 ON 条件;
2.3 全外连接 (了解)
SELECT 字段列表 FROM 表名1 full [outer ] JOIN 表名2 ON 条件;
6、数据库的分页
MySQL分页:
select * from 表名 [order by 字段名] limit (当前页码-1)*页面容量,页面容量;
Oracle分页:
select 表名.* from (select 表名.,rownum as r from teacher where r <= pageSizepageNum ) n where n.r > pageSize*(pageNum-1);
7、存储过程的创建和函数的区别
存储过程的语法:
DELIMITER //
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
DECLARE 变量名 数据类型;
…
Sql语句…
END //
DELIMITER ;
#调用存储过程:
CALL 存储过程名();
#删除存储过程:
DROP PROCEDURE IF EXISTS pro_test
;
存储函数的语法
create [or replace] function 函数名(参数列表)
return函数值类型
as
begin
…sql语句
return 返回值
end ;
// PLSQL子程序体(了解);
存储过程和函数区别 in out inout
写法上:存储过程的参数列表可以有输入参数、输出参数、可输入输出的参数;
函数的参数列表只有输入参数,并且有return <返回值类型,无长度说明>。
返回值上:
存储过程的返回值,可以有多个值,
函数的返回值,只有一个值。
函数是可以嵌入在sql中使用的,可以在select中调用,而存储过程不行。
一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。
存储过程,功能强大,可以执行包括修改表等一系列数据库操作;用户定义函数不能用于执行一组修改全局数据库状态的操作。
对于存储过程来说可以返回参数,如记录集,而函数只能返回值或者表对象。函数只能返回一个变量;而存储过程可以返回多个。存储过程的参数可以有IN,OUT,INOUT三种类型,而函数只能有IN类~~存储过程声明时不需要返回类型,而函数声明时需要描述返回类型,且函数体中必须包含一个有效的RETURN语句。
8、什么是存储过程,有什么优缺点(重点)
存储过程(Stored Procedure)是一组为了完成特定功能的 SQL 语句集,是由流程控制和SQL 语句书写的命名语句块,经编译和优化后存储在数据库服务器中,应用程序使用时只要调用即可,可以通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来调用.
1.使用存储过程有以下的优点:
具有良好的安全性:可保证数据的安全性和完整性.通过存储过程可以使没有权限直接访问相应数据库对象的用户受控制的间接地执行数据库相关操作,从而保证数据的安全.
执行速度快,效率高:在运行存储过程前,数据库已对其进行了语法和句法分析,并 给出了优化执行方案.这种已经编译好的过程可极大地改善 SQL 语句的性能.由于执行 SQL 语句的大部分工作已经完成,所以存储过程能以极快的速度执行.
减少网络流量:可以降低网络的通信量.
模块化程序设计:存储过程可以封装业务逻辑,并存入数据服务器中,当业务逻辑发生变化时,无需修改调用存储过程的应用程序,只需修改存储过程即可.
2.使用存储过程的缺点是:
相对而言,调试比较麻烦
移植问题,数据库端代码当然是与具体数据库相关的.
代码可读性差
8.1.存储过程和存储函数的特点和区别?
特点:
(1)、一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。
(2)、对于存储过程来说可以返回参数,而函数只能返回值或者表对象。
(3)、存储过程一般是作为一个独立的部分来执行,而函数可以作为查询语句的一个部分来调用,由于函数可以
返回一个表对象,因此它可以在查询语句中位于FROM关键字的后面。
区别:
(1)、函数必须有返回值,而过程没有.
(2)、函数可以单独执行.而过程必须通过execute执行.
(3)、函数可以嵌入到SQL语句中执行.而过程不行.
其实我们可以将比较复杂的查询写成函数.然后到存储过程中去调用这些函数.
9、存储过程与SQL的对比?
优势:
1、提高性能
SQL语句在创建过程时进行分析和编译。 存储过程是预编译的,在首次运行一个存储过程时,查询优化器对其进
行分析、优化,并给出终被存在系统表中的存储计划,这样,在执行过程时便可节省此开销。
2、降低网络开销
存储过程调用时只需用提供存储过程名和必要的参数信息,从而可降低网络的流量。
3、便于进行代码移植
数据库专业人员可以随时对存储过程进行修改,但对应用程序源代码却毫无影响,从而极大的提高了程序的可移
植性。
4、更强的安全性
1)系统管理员可以对执行的某一个存储过程进行权限限制,避免非授权用户对数据的访问
2)在通过网络调用过程时,只有对执行过程的调用是可见的。 因此,恶意用户无法看到表和数据库对象名称、
嵌入自己的 Transact-SQL 语句或搜索关键数据。
3)使用过程参数有助于避免 SQL 注入攻击。 因为参数输入被视作文字值而非可执行代码,所以,攻击者将命令
插入过程内的 Transact-SQL 语句并损害安全性将更为困难。
4)可以对过程进行加密,这有助于对源代码进行模糊处理。
劣势:
1、存储过程需要专门的数据库开发人员进行维护,但实际情况是,往往由程序开发员人员兼职
2、设计逻辑变更,修改存储过程没有SQL灵活
10、你觉得存储过程和SQL语句该使用哪个?
1、在一些高效率或者规范性要求比较高的项目,建议采用存储过程
2、对于一般项目建议采用参数化命令方式,是存储过程与SQL语句一种折中的方式
3、对于一些算法要求比较高,涉及多条数据逻辑,建议采用存储过程
11、触发器的作用有哪些?
1)触发器可通过数据库中的相关表实现级联更改;通过级联引用完整性约束可以更有效地执行这些更改。
2)触发器可以强制比用 CHECK 约束定义的约束更为复杂的约束。与 CHECK 约束不同,触发器可以引用其它
表中的列。例如,触发器可以使用另一个表中的 SELECT 比较插入或更新的数据,以及执行其它操作,如修改数据或
显示用户定义错误信息。
3)触发器还可以强制执行业务规则
4)触发器也可以评估数据修改前后的表状态,并根据其差异采取对策。
参考资料:http://www.cnblogs.com/yank/p/4193820.html
12、数据库数据去重
创建的表
CREATE TABLE t
(
id
int(10) unsigned NOT NULL,
name
char(255) NOT NULL,
email
char(255) NOT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
select * from t;
1、 通过group by分组的形式去重
select 字段列表 from 表名 group by 字段名[,字段名,字段名…] [ having 聚合函数];
select min(id), email from t group by email having count(1)>1;
– 删除重复数据
DELETE FROM t WHERE id NOT IN (SELECT mn FROM (SELECT min(id) mn FROM t GROUP BY email) AS a )
2、通过distinct关键字去重
select distinct 字段列表 from 表名;
select distinct email from t;
–查询不重复数据有多少条
select count(distinct email) from t;
3、通过Oracle数据库中伪列rowid去重,
对a,b字段都重复的记录,只保留最新的一条
select a,b,max(rowid) from test group by a,b;
SELECT ROWID,EMPNO,JOB FROM EMP
WHERE ROWID!=(SELECT MAX(ROWID) FROM EMP D
WHERE EMP.JOB=D.JOB)
ORDER BY JOB;
举例解释:
假设现在EMP表有三条记录,分别为a(rowid=1),b(rowid=2),b(rowid=3)。(b存在重复)
那么where语句中,
对于记录a来说,只有一条记录,其rowid为1,而关联的D的max(rowid)也为1,由于1=1,所以条件不成立,记录a不会被检出;
对于记录b来说,由于存在2条记录,rowid分别为2和3,而关联的D的max(rowid)也为3(2小于3),所以rowid为2的记录满足条件(2<>3),rowid为2的b记录会被检出,rowid为3的记录不会被检出。
故对于以上,查询结果就是b(rowid=2)。
今天发现一个表中数据出现了几万条的重复数据,想到用rowid来解决数据重复的问题。
查询表中重复的数据:
select * from CCI_PERSON a where rowid !=(select max(rowid) from CCI_PERSON b where a.cci_person_id=b.cci_person_id ) ;
删除重复数据:
delete from CCI_PERSON a where rowid !=(select max(rowid) from CCI_PERSON b where a.cci_person_id=b.cci_person_id );
13、 聚合函数有哪些? (重点)
AVG( ) 返回的平均值
COUNT( ) 返回某列的行数
MAX( ) 返回某列的最大值
MIN( ) 返回某列的最小值
SUM( ) 返回某个列之和
14、事务的特性,传播机制与隔离级别
事务的定义:多组操作必须为一个整体,不能够相互分离。
事务的特性(acid):
1.原子性(atomic):操作不能够分割。
2.一致性(consistent):操作前后,最终的状态一致。
3.隔离性(isolation,*):事务与事务之间的隔离关系
4.持久性(durable):数据保存到数据库中去后,需要稳定持久的存在。
#开始事务:
START TRANSACTION;/BEGIN TRANSACTION;
#回滚事务:
ROLLBACK;#当事务提交之后,是不能回滚的。
#结束事务:
COMMIT;
#查看MySQL软件的默认隔离级别:
SELECT @@tx_isolation;
#修改mysql软件的默认事务隔离级别:
SET GLOBAL TRANSACTION ISOLATION LEVEL 隔离级别;
#当mysql事务的隔离级别为read uncommitted的时候,会引发"脏读"
脏读:读取了别人还未提交的数据。
#解决脏读的方法:将MySQL数据库软件的隔离级别设置为:read committed;
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
read-Uncommitted repeatable-read 隔离级别的时候会引发幻读
幻读:第一个事务对一定范围的数据进行批量修改,第二个事务在这个范围增加一条数据,这时候第一个事务就会丢失对新增数据的修改。
不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
隔离级别由低到高:read uncommitted(读取未提交)、read committed(读取提交)、
repeatable read(重复读)、serializable(串行化)
#特点:隔离性越高,数据库的性能越差。
事务传播机制
Spring事务机制主要包括声明式事务和编程式事务,此处侧重讲解声明式事务,编程式事务在实际开发中得不到广泛使用
Spring声明式事务让我们从复杂的事务处理中得到解脱。使得我们再也无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。再也无需要我们在与事务相关的方法中处理大量的try…catch…finally代码。我们在使用Spring声明式事务时,有一个非常重要的概念就是事务属性。事务属性通常由事务的传播行为,事务的隔离级别,事务的超时值和事务只读标志组成。我们在进行事务划分时,需要进行事务定义,也就是配置事务的属性。
spring在TransactionDefinition接口中定义了七个事务传播行为:
(1)PROPAGATION_REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
Java代码:
//事务属性 PROPAGATION_REQUIRED methodA{ …… methodB(); …… } //事务属性 PROPAGATION_REQUIRED methodB{ …… }
使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。
单独调用methodB方法:
Java代码
main{ metodB(); }
相当于
Java代码
Main{ Connection con=null; try{ con = getConnection(); con.setAutoCommit(false); //方法调用 methodB(); //提交事务 con.commit(); } Catch(RuntimeException ex){ //回滚事务 con.rollback(); } finally{ //释放资源 closeCon(); } }
Spring保证在methodB方法中所有的调用都获得到一个相同的连接。在调用methodB时,没有一个存在的事务,所以获得一个新的连接,开启了一个新的事务。
单独调用MethodA时,在MethodA内又会调用MethodB.
执行效果相当于:
Java代码
main{ Connection con = null; try{ con = getConnection(); methodA(); con.commit(); } catch(RuntimeException ex){ con.rollback(); } finally{ closeCon(); } }
调用MethodA时,环境中没有事务,所以开启一个新的事务.当在MethodA中调用MethodB时,环境中已经有了一个事务,所以methodB就加入当前事务。
(2)PROPAGATION_SUPPORTS 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务管理器,PROPAGATION_SUPPORTS与不使用事务有少许不同。
Java代码:
//事务属性 PROPAGATION_REQUIRED methodA(){ methodB(); } //事务属性 PROPAGATION_SUPPORTS methodB(){ …… }
单纯的调用methodB时,methodB方法是非事务的执行的。当调用methdA时,methodB则加入了methodA的事务中,事务地执行。
(3)PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
Java代码:
//事务属性 PROPAGATION_REQUIRED methodA(){ methodB(); } //事务属性 PROPAGATION_MANDATORY methodB(){ …… }
当单独调用methodB时,因为当前没有一个活动的事务,则会抛出异常throw new IllegalTransactionStateException(“Transaction propagation ‘mandatory’ but no existing transaction found”);当调用methodA时,methodB则加入到methodA的事务中,事务地执行。
(4)PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
Java代码:
//事务属性 PROPAGATION_REQUIRED methodA(){ doSomeThingA(); methodB(); doSomeThingB(); } //事务属性 PROPAGATION_REQUIRES_NEW methodB(){ …… }
Java代码:
main(){ methodA(); }
相当于
Java代码:
main(){ TransactionManager tm = null; try{ //获得一个JTA事务管理器 tm = getTransactionManager(); tm.begin();//开启一个新的事务 Transaction ts1 = tm.getTransaction(); doSomeThing(); tm.suspend();//挂起当前事务 try{ tm.begin();//重新开启第二个事务 Transaction ts2 = tm.getTransaction(); methodB(); ts2.commit();//提交第二个事务 } Catch(RunTimeException ex){ ts2.rollback();//回滚第二个事务 } finally{ //释放资源 } //methodB执行完后,复恢第一个事务 tm.resume(ts1); doSomeThingB(); ts1.commit();//提交第一个事务 } catch(RunTimeException ex){ ts1.rollback();//回滚第一个事务 } finally{ //释放资源 } }
在这里,我把ts1称为外层事务,ts2称为内层事务。从上面的代码可以看出,ts2与ts1是两个独立的事务,互不相干。Ts2是否成功并不依赖于ts1。如果methodA方法在调用methodB方法后的doSomeThingB方法失败了,而methodB方法所做的结果依然被提交。而除了methodB之外的其它代码导致的结果却被回滚了。使用PROPAGATION_REQUIRES_NEW,需要使用JtaTransactionManager作为事务管理器。
(5)PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务。使用PROPAGATION_NOT_SUPPORTED,也需要使用JtaTransactionManager作为事务管理器。(代码示例同上,可同理推出)
(6)PROPAGATION_NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常;
(7)PROPAGATION_NESTED如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。这是一个嵌套事务,使用JDBC 3.0驱动时,仅仅支持DataSourceTransactionManager作为事务管理器。需要JDBC 驱动的java.sql.Savepoint类。有一些JTA的事务管理器实现可能也提供了同样的功能。使用PROPAGATION_NESTED,还需要把PlatformTransactionManager的nestedTransactionAllowed属性设为true;而nestedTransactionAllowed属性值默认为false;
Java代码:
//事务属性 PROPAGATION_REQUIRED methodA(){ doSomeThingA(); methodB(); doSomeThingB(); } //事务属性 PROPAGATION_NESTED methodB(){ …… }
如果单独调用methodB方法,则按REQUIRED属性执行。如果调用methodA方法,相当于下面的效果:
Java代码:
main(){ Connection con = null; Savepoint savepoint = null; try{ con = getConnection(); con.setAutoCommit(false); doSomeThingA(); savepoint = con2.setSavepoint(); try{ methodB(); }catch(RuntimeException ex){ con.rollback(savepoint); } finally{ //释放资源 } doSomeThingB(); con.commit(); } catch(RuntimeException ex){ con.rollback(); } finally{ //释放资源 } }
当methodB方法调用之前,调用setSavepoint方法,保存当前的状态到savepoint。如果methodB方法调用失败,则恢复到之前保存的状态。但是需要注意的是,这时的事务并没有进行提交,如果后续的代码(doSomeThingB()方法)调用失败,则回滚包括methodB方法的所有操作。
嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。
Spring 默认的事务传播行为是 PROPAGATION_REQUIRED,它适合于绝大多数的情况。假设 ServiveX#methodX() 都工作在事务环境下(即都被 Spring 事务增强了),假设程序中存在如下的调用链:Service1#method1()->Service2#method2()->Service3#method3(),那么这 3 个服务类的 3 个方法通过 Spring 的事务传播机制都工作在同一个事务中。
15、MySQL与Oracle区别
mysql与oracle的区别
1.本质区别:
mysql是免费开源的小型数据库;
oracle是收费的大型数据库;
2.安全性:
mysql安全性低,使用路径,用户名,密码
oracle用户名,密码,配置文件,本地身份,外部身份等安全验证
3.存储区别:
与Oracle相比,MySQL没有表空间,角色管理,快照,同义词和包以及自动存储管理;
4.备份类型:
Oracle有冷备份、热备份、导入、导出、数据泵的备份,而且提供了RMAN的备份使用程序;
MySQL有mysqldump和mysqlhotcopy备份工具
5.数据库管理
OracleDBA比MySQLDBA更有收益,有很多的权限;
6.事务的提交方式
MySQL自动提交;
Oracle需要手动提交,执行commit
7.事务隔离级别
MySQL默认是可重复读;
Oracle默认是读以提交;
8.运行程序和外部程序支持
Oracle支持从数据库内部编写,编译和执行的几种编程语言,而且Oracle使用xml传输数据;
MySQL不支持在系统内执行其他语言,也不支持xml;
9.语法
①MySQL主键自增;
MySQL直接使用;
Oracle没有主键自增,一般使用序列来实现;
②单引号的用法
MySQL的字符可以使用单引号或双引号;
Oracle只能使用双引号,双引号用于别名;
③分页
mysql的分页比较简单,使用关键字limit
Oracle分页繁琐,使用伪类来进行分页;
MySQL分页:
select * from 表名 [order by 字段名] limit (当前页码-1)*页面容量,页面容量;
Oracle分页:
select 表名.* from (select 表名.,rownum as r from 表名 where r <= pageSizepageNum ) n where n.r > pageSize*(pageNum-1);
④数据类型不同
字符型varchar2,还有数值型number,时间date
⑤空字符的处理
mysql非空字段也用空的内容;
Oracle定义的非空字段不允许为空;
⑥字符串的模糊查询
mysql对于模糊查询带有下划线的直接转义;
Oracle转义后需要escape来搭配使用;
⑦Oracle有pl/sql编程语言
⑧oracle中有dual虚表,MySQL没有14.数据库分页