数据库必须了解的问题

SQL语句中的几种连接

1、内连接分为(等值连接,不等连接,自然连接)

 

(1)、等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。


  内连接 inner join 或者 join;它为返回字段ID同时存在于表voteMaster 和 voter中的记录


(2)、不等连接: 在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、<=、<、!>、!<和<>。
  
(3)、自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。

l       同一张表之间的连接查询

l       主要用于在参照表上显示   上下级关系或层次关系

l       语法:

    select  t1.col_name, t2.col_name

    from  table1  t1  inner join  table1  t2

    on  t1.col_name = t2.col_name

 

2、外连接分为(左连接,右连接,全外连接)

假设有如下表:

一个为投票主表,一个为投票者信息表~记录投票人IP及对应投票类型,左右连接实际说是我们联合查询的结果以哪个表为准~

(1):如右接连 right join 或 right outer join:

我们以右边voter表为准,则左表(voteMaster)中的记录只有当其ID在右边(voter)中存在时才会显示出来,如上图,左边中ID为3.4.5.6因为这些ID右表中没有相应记录,所以没有显示!

(2):因此我们自然能理解左连接 left join 或者 left outer join

可见,现在右边中ID在中存在时才会显示,当右边中没有相应数据时则用NULL代替!
(3):全连接 full join 或者 full outer join,为二个表中的数据都出来,这里演示效果与上一样!
 

3、交叉连接

交叉连接(完全连接)cross join 不带 where 条件的
没有 WHERE 子句的交叉联接将产生联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。(table1和table2交叉连接产生6*3=18条记录)

等价select vm.id,vm.voteTitle,vt.ip from voteMaster as vm,voter as vt

数据库范式

1NF:对于表中的每一行,必须且仅仅有唯一的行值.在一行中的每一列仅有唯一的值并且具有原子性.

2NF:非主键列是主键的子集,非主键列活动必须完全依赖整个主键。主键必须有唯一性的元素,一个主键可以由一个或更多的组成唯一值的列组成。一旦创建,主键无法改变,外键关联一个表的主键。主外键关联意味着一对多的关系.

3NF: 要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。

 

数据库事务特性

它必须同时满足4个特性:原子性(Atomic)、一致性(Consistency)、隔离性(Isolation)和持久性(Durabiliy),简称为ACID。

 

隔离级别 

●脏读(dirty read):当一个事务读取另一个事务尚未提交的修改时,产生脏读。

 A插入数据并没有提交,B能Select出来。
●非重复读(non-repeatable read):同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删除,每次返回不同的结果集,此时发生非重复读。

 A 先Select,B做Update或者Delete 并提交。

 A 在Select,则发现数据变了

这2次查询在同一条件下。统一操作下,同一个事务当中,返回值不一样。
●幻像读(phantom read):同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读。

 A 先Select,B在Insert并提交。

 A 在Select,发现多一条。

这2次查询在同一条件下。同一操作下,返回记录集不一样
事务隔离级别对数据库一致性现象的解决情况,见表1。

 

1.隔离级别 read uncommitted
级别read uncommitted(又称读取未提交内容)允许任务读取数据库中未提交的数据更改。也称为脏读,原因在于任务会显示以后被回退的结果。表2显示了一个执行脏读的select 查询。
如果T2在T1更新表后,尚未回退更改前查询该表,T2所计算的数量会减少100。事务T1中的update语句在T_sample上获取一个排它锁。但事务T2在查询T_sample前并不试图获取共享锁,因此它并没有被T1阻塞。反之亦然。

2.隔离级别 Read Committed
级别Read Committed(又称读取已提交内容)可防止脏读。该级别查询只读取已提交的数据更改。如果事务需要读取被另一未完成事务修改的数据,该事务将等待,直到第一个事务完成(提交或回退)。在上面的例子中,T2事务在隔离级别1下的select语句将被T1事务update语句产生的排它锁阻塞,直到T1结束释放锁后才能完成读取。

3.隔离级别Serializable
级别Serializable(可串行化)可防止幻像和非重复读。在非Serializable的级别下,如果一个事务读取了满足搜索条件的一组数据记录,而第二个事务修改了数据(通过 insert、delete 或 update 语句);如果第一个事务按相同的搜索条件重复读取,它将获得一组不同的数据记录,产生幻像读或非重复读。在表3中,在隔离级别Read Committed下运行的事务T6在第二个查询中发现了一个幻像行。
避免事务中的非重复读(在隔离级别Serializable的条件下),见表4。

 

 

乐观所,悲观锁

Oracle的悲观锁需要利用一条现有的连接,分成两种方式,从SQL语句的区别来看,就是一种是for update,一种是for update nowait的形式。

select * from test where id = 10 for update

select * from test where id = 10 for update nowait

 

乐观锁的做法就是采用版本戳,这个在Hibernate中得到了使用。采用版本戳的话,首先需要在你有乐观锁的数据库table上建立一个新的column,比如为number型,当你数据每更新一次的时候,版本数就会往上增加1。比如同样有2个session同样对某条数据进行操作。两者都取到当前的数据的版本号为1,当第一个session进行数据更新后,在提交的时候查看到当前数据的版本还为1,和自己一开始取到的版本相同。就正式提交,然后把版本号增加1,这个时候当前数据的版本为2。当第二个session也更新了数据提交的时候,发现数据库中版本为2,和一开始这个session取到的版本号不一致,就知道别人更新过此条数据,这个时候再进行业务处理,比如整个Transaction都Rollback等等操作。在用版本戳的时候,可以在应用程序侧使用版本戳的验证,也可以在数据库侧采用Trigger(触发器)来进行验证。不过数据库的Trigger的性能开销还是比较的大,所以能在应用侧进行验证的话还是推荐不用Trigger。

 

 

试图的好处

(1)安全性。使用视图隐藏了数据的来源。   
(2)方便性。在多表连接查询时,可以使用视图提高效率。  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值