接触数据库很少,最近被赶鸭子上架,基本的sql可以应付,但是复杂一些的就不确定了
#表1CREATE TABLE task (
  `index` int(11) NOT NULL AUTO_INCREMENT,
  `applycount` int(11) NOT NULL,
  `maxcount` int(11) NOT NULL,
  `flag` tinyint(1) NOT NULL
);#表2
CREATE TABLE user (
  `index` int(11) NOT NULL AUTO_INCREMENT, 
  `maxcount` int(11) NOT NULL,
  `count` int(11) NOT NULL
);#表3
CREATE TABLE apply (
  `index` int(11) NOT NULL AUTO_INCREMENT,
  `tid` int(11) NOT NULL, #task.index
  `uid` int(11) NOT NULL  #user.index
);
想完成类似下面伪代码的操作:
//$tid,$uid为php对应变量
//添加
if(task.flag == 1 && task.maxcount>task.applycount && user.maxcount>user.count)
{
   insert into apply(tid,uid) values($tid, $uid);
   update task set applycount = (select count(*) from apply where tid=$tid);
   update user set count = (select count(*) from user where uid=$uid);
}
//删除
if(task.flag == 1)
{
   delete from apply where tid=$tid AND uid=$uid;
   update task set applycount = (select count(*) from apply where tid=$tid);
   update user set count = (select count(*) from user where uid=$uid);
}现在觉得疑惑的地方主要有2个
1、if(task.flag == 1 && task.maxcount>task.applycount && user.maxcount>user.count)
类似这样的判断,在之后的操作中,怎么条件依旧满足?
2、如果某步操作失败,则撤销全部操作请问这样的操作该如何实现呢?

解决方案 »

  1.   


    1,首先表的类型要用innodb存储引擎
    2,开启事务。
    3,将if的条件都放入开启的事务里面,只要有一个不成立了,就rollback。
      

  2.   


    存储过程里面很好实现 ,例子如下:
    DELIMITER $$
    use test$$
    drop procedure if exists test.t1$$
    use `test` $$
    create procedure test.t1()
    begin    drop table if exists t1;
        create table test.t1 (c1 int)
        ENGINE = InnoDB;
              -- set autocommit=0; 这里设置为手动提交,或者下面开启事务,在这种情况下 rollback都有效。
        START TRANSACTION; 
        insert into test.t1 select 1;
        select * from test.t1;
        rollback;
        select 2,c1 from test.t1;
        insert into test.t1 select 2;
        commit;
        select 3,c1 from test.t1;
        insert into test.t1 select 3;
        select 4,c1 from test.t1;end -- 测试call test.t1();
     
      

  3.   


    请问,事务和lock table,哪种效率高一些?
    另外,myisam和innodb是否有性能差距?
      

  4.   


    1,一般来说,事务性能高一些。2,myisam不支持事务,没有rollback措施。innodb支持事务,可以开启事务,如果要实现你的功能,只有建立innodb存储引擎类型的表。
      

  5.   

    3,至于性能,myisam一般长于读多余写,innodb长于高并发以及acid要求比较高的业务。
      

  6.   

    谢谢你的热心指点,问最后一个问题立刻结贴对于数据有效性验证,比如我顶楼的以 maxcount>applycount 为条件的insert,我现在已知的方法有3种1、insert ... select ... where()2、触发程序中故意抛出错误3、事务方式的rollback这三种各有什么优劣?
      

  7.   

    一般用第一种,逻辑简介方便有效。第二种就有点多余了,你先select冗余或者错误的数据,然后再遍历冗余数据时候抛异常,还不如在select的时候就去掉冗余或者错误的数据。第三种跟第二种本质上一样,都是多走一步。当然了,如果你在不满足的条件的记录上,insert之前要做log记录的话,就不要选择第一种了,第二种适合于对sql不太熟悉的人,但是效率没有第三种好。