1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
| mysql -uroot -p[密码]
+ | user | host | + | chenyushao | localhost | | mysql.infoschema | localhost | | mysql.session | localhost | | mysql.sys | localhost | +
create database test; #创建新的名叫test的数据库
show databases; #查看由哪些数据库
use test; #选中数据库
show tables; #查看数据库里的表
truncate table 表名 # 删除表中数据 delete 可以事物回滚,truncate不可以。
#创建数据表pet create table pet(name VARCHAR(20), owner VARCHAR(20), species VARCHAR(20), sex CHAR(1), brith DATE, death DATE);
describe pet; #查看数据表pet结构
select * from pet #查看pet表中记录
#往数据表里添加数据 INSERT INTO pet VALUES('Puffball','Diane','hamster','f','1999-03-30',NULL);
#删除数据 delete from pet where name=‘旺财’;
#修改数据,注意是update不是updata update pet set name=‘旺旺财’ where owner=‘周星驰’;
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #mysql建表约束 1.#主键约束 它能够唯一确定一张表中的一条记录,也就是给某个字段添加约束,使得该字段不重复且"不为空"; create table user(id int primary key, name varchar(20)); #key确定了id为主键,也就是不能再有出现相同的id了,name没做主键约束,故可以插入一样的name; #联合主键(id和name组成的这一对字段,要不为空,且不能id和name同时相同,id或name单个出现相同的字段是可以的,同时id和name任意一个不能为空null。) create table user3(id int,name varchar(20), password varchar(20), primary key(id,name) );
2.#自增约束 create table userthree(id int primary key auto_increment, name varchar(20 ) ); #仅仅添加name,id 会自动生成1,若再添加一个name(name里面的字段相同不相同都不影响),对应的id会变成2…. create table userthree(id int primary key auto_increment, name varchar(20));
#忘记创建主键约束了,怎么办? create table user4(
id int, name varchar(20)
);
alter table user4 add primary key(id); #后续定义主键 (有时候会说找不到id这个field不知道为什么,换别的field就可以。) alter table user4 modify id int primary key;这样也可以 alter table user4 drop primary key;#后续删除主键
3.#唯一约束 约束修饰的字段值不可以重复。 create table user5(id int,name varchar(20)); alter table user5 add unique(name); #或者 create table user6(id int,name varchar(20),unique(name));
create table user7(id int, name varchar(20), unique(id,name) #类似联合主键,但是这样key会落到id上,后续要删除就alter table user6 drop index id;即可 ); #删除唯一约束 alter table user6 drop index name; #modify添加唯一约束 alter table user6 modify name varchar(20) unique;
#临时总结: 一、建表的时候添加约束 alter table ... add... alter table ... modify ... 二、删除约束(key落到谁头上删除谁就可以了) alter table ... drop ...
4.#非空约束 字面意思, create table user9( id int, name varchar(20) not null ); insert into user9 (id) values(1);#错 insert into user9 values(1,'张三');#对
inser into user9 (name) values('李四');#对 right 5.#默认约束 当插入字段值时,如果没有传值,就会使用默认值 create table user10( id int, name varchar(20), age int default 10 ); #如果没有传入值,age就用10,传入9就变成了9; insert into user10 (id,name,age) values(1,'zhangsan',9); insert into user10 (id,name) values(1,'zhangsan');
6.#外键约束 涉及: 父表、子表。 主表、副表。
#(班级) create table classes( id int primary key, name varchar(20) ); #学生表 create table students( id int primary key, name varchar(20), class_id int, foreign key(class_id) references classes(id)# 指明学生的class_id必须引用来自classes的id ); insert into classes values(1,'一班'); insert into classes values(2,'二班'); insert into classes values(3,'三班'); insert into classes values(4,'四班');
insert into students values(1001,'张三',1); insert into students values(1002,'张三',2); insert into students values(1003,'张三',3); insert into students values(1004,'张三',4);
insert into students values(1005,'李四',5);#报错 students`, CONSTRAINT `students_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `classes` (`id
delete from classes where id=4; # 报错,已经被引用,父表此项就不能删除。
#1、父表 中没有的数据值,在子表中是不可以使用的 #2、子表已经引用了父表的数据后,父表的此这条记录不能被删除。
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#数据库三大设计范式
#第一范式
数据表中所有的字段都是不可分割的原子值。 create table students2( id int, name varchar(20), address varchar(30) );
insert into students2 values(1,'张三','湖南省衡阳市雁峰区'); insert into students2 values(2,'李四','湖南省衡阳市蒸湘区'); insert into students2 values(3,'王五','湖南省衡阳市石鼓区'); #字段还可以继续拆分的,就不满足第一范式,上面就是不满足的address,就是说要尽可能拆分的细。 #范式,设计的越详细,对于某一些实际操作可能更好,但是不一定都是好处。
#第二范式
create table myorder( product_id int, customer_id int, product_name varchar(20),#只和product_id有关 customer_name varchar(20),#只和customer_id有关 primary key(product_id,customer_id)#联合主键 ); #以上,除主键以外的其他列,只依赖于主键的部分字段。不满足第二范式。
create table myorder2( order_id int primary key, product_id int, customer_id int );#以上的product_id和customer_id完全依赖于order_id
create table product( id int primary key, name varchar(20) );#以上的name 完全依赖于id
create table customer( id int primary key, name varchar(20) );#以上的name 完全依赖于id
另一个解释案例: 讲师P 性别 班级P 教室 代课时间 开始 结束 韩忠康 Male php0331 102 30天 2013-03-31 2013-05-05 韩忠康 Male php0228 106 30天 2013-02-28 2013-03-30 韩顺平 male Php0228 106 15天 2013-03-31 2013-04-20
上面的设计可以用讲师P,班级,两个字段作为组合主键,但是问题来了,那么后面的教室仅仅由班级字段(组合主键中的一条)就可以确定,即所谓教室部分依赖于组合主键,那么就不符合2NF。
#第三范式
create table myorder( order_id int primary key, product_id int, customer_id int, customer_phone varchar(15)#和customer_id有关,customer_id非主键。所以不满足第三范式。 );
create table myorder( order_id int primary key, product_id int, customer_id int, ); create table customer( customer_id int primary key, name varchar(20), phone varchar(15) ); #以上满足了第三范式。
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #这里的快速注释 ,是command+/;
create table student( sno varchar(20) primary key, sname varchar(20) not null, ssex varchar(10) not null, sbirthday datetime, class varchar(20) );
create table course( cno varchar(20) primary key, cname varchar(20) not null, tno varchar(20) not null, foreign key(tno) references teacher(tno) );
分数表的错误设计: create table score( sno varchar (20) primary key, cno varchar(20) not null, degree decimal, foreign key(sno) references student(sno), foreign key(cno) references course(cno) );
create table teacher( tno varchar(20) primary key, tname varchar(20) not null, tsex varchar (10) not null, tbirthday datetime not null, prof varchar(20) not null, depart varchar(20) not null );
insert into student values('18416','陈宇韶','男','1993-4-6','184'); insert into student values('18438','董文勇','男','1993-4-6','184'); insert into student values('18435','宁鹏飞','男','1993-4-6','184'); insert into student values('18434','刘雯','男','1993-4-6','184'); insert into student values('18433','陶碧云','男','1993-4-6','184'); insert into student values('18432','曹杰','男','1993-4-6','184'); insert into student values('18417','秦壁辉','男','1993-4-6','184'); insert into student values('18410','秦诗','女','1995-4-6','183'); insert into student values('18422','秦静静','女','1992-4-6','181');
insert into teacher values('1841','李辉','男','1983-4-8','副教授','数学系'); insert into teacher values('1842','朱文','女','1983-7-9','副教授','语文系'); insert into teacher values('1843','何勇','男','1988-2-3','副教授','英语系');
insert into course values('1','数学','1841'); insert into course values('2','语文','1842'); insert into course values('3','英语','1843');
drop table score; 分数表的正确设计: create table score( sno varchar (20) not null, cno varchar(20) not null, degree decimal, foreign key(sno) references student(sno), foreign key(cno) references course(cno), primary key(sno,cno) );
insert into score values('18416','1',120); insert into score values('18438','1',111); insert into score values('18435','2',119); insert into score values('18434','3',99); insert into score values('18433','2',109); insert into score values('18432','1',88); insert into score values('18417','3',115); insert into score values('18417','2',115); insert into score values('18416','2',120); insert into score values('18416','1',121);
select * from student;
select sname ,ssex,class from student;
select depart from teacher; select distinct depart from teacher;
select * from score where degree between 110 and 120; select * from score where degree > 110 and degree < 121;
select * from score where degree in(120,115,112);
select * from student where class='183' or ssex='女';
select * from student order by class desc; select * from student order by class asc;
select * from score order by cno asc , degree desc;
select count(*) from student where class='184';
select sno,cno from score where degree=(select max(degree) from score);
select max(degree) from score;
select sno,cno from score where degree=(select max(degree) from score);
select sno,cno from score order by degree; select sno , cno from score order by degree desc limit 0,1;
select * from course;
select avg(degree) from score where cno='2'; select avg(degree) from score where cno='1'; select avg(degree) from score where cno='3';
select cno,avg(degree) from score group by cno;
select cno from score group by cno having count(cno)>=3;
select cno from score group by cno having count(cno)>=2 and cno like '3%';
select cno, avg(degree) from score group by cno having count(cno)>=2 and cno like '3%';
select cno, avg(degree),count(*) from score group by cno having count(cno)>=2 and cno like '3%';
select sno ,degree from score where degree between 90 and 122;
select sno ,degree from score where degree >70 and degree <90;
select sname ,cno ,degree from student,score where student.sno = score.sno;
select cno ,cname, from course; select cname,sno,degree from course,score where course.cno = score.cno;
select sname,cname,degree from student,course,score where student.sno=score.sno and course.cno=score.cno;
select sname,cname,degree,student.sno,course.cno from student,course,score where student.sno=score.sno and course.cno=score.cno;
select sname,cname,degree,student.sno as stu_s,course.cno as cou_c from student,course,score where student.sno=score.sno and course.cno=score.cno;
select * from student where class='184'; select sno from student where class='184';
select avg(degree) from score where sno in(select sno from student where class='184');
select cno, avg(degree) from score where sno in(select sno from student where class='184') group by cno;
select * from score where cno='1' and degree >(select degree from score where sno='18432' and cno='1');
select degree from score where sno='18432' and cno='1' select * from score where degree>(select degree from score where sno='18432' and cno='1');
select year(sbirthday) from student where sno in('18416','18433') select sno,sname,sbirthday from student where year(sbirthday) in (select year(sbirthday) from student where sno in('18416','18433'));
select tno from teacher where tname='李辉' select cno from course where tno=(select tno from teacher where tname='李辉') select degree , sno from score where cno=(select cno from course where tno=(select tno from teacher where tname='李辉') ) ;
select cno from score group by cno having count(sno)>2; select cno from score group by cno having count(cno)>2; select cno from score group by cno having count(*)>2; select tno from course where cno=(select cno from score group by cno having count(*)>2); select tname from teacher where tno=(select tno from course where cno=(select cno from score group by cno having count(*)>2));
select tname from teacher where tno in (select tno from course where cno in (select cno from score group by cno having count(sno)>2));
select * from student where class in ('184','185');
select cno ,degree from score where degree>='120';
select * from teacher where depart='数学系'; select * from course where tno in (select * from teacher where depart='数学系') select degree from score where cno in (select cno from course where tno in (select tno from teacher where depart='数学系'));
select * from teacher; select prof from teacher where depart='数学系'; select * from teacher where depart='数学系' and prof not in (select prof from teacher where depart='英语系') union select * from teacher where depart='英语系' and prof not in (select prof from teacher where depart='数学系');
select * from score where cno='1'; select * from score where cno='2'; select * from score where cno='1' and degree > any(select degree from score where cno='2') order by degree desc;
select * from score where cno='1' and degree > all(select degree from score where cno='3') order by degree desc;
select tname,tsex,tbirthday from teacher union select sname,ssex,sbirthday from student;
select tname as name,tsex as sex,tbirthday as birhday from teacher where tsex='女' union select sname,ssex,sbirthday from student where ssex='女';
select cno ,avg(degree) from score group by cno; select * from score a where a.degree >(select avg(b.degree) from score b group by cno);
select Score.courseNo,Score.studentNo from (select avg(Score.score) as avgScore,courseNo from Score group by courseNo ) a left join Score on a.courseNo = Score.courseNo where score < avgScore group by Score.courseNo,Score.studentNo
select * from score a where degree > (select avg(degree) from score b where b.cno=a.cno );
select tname,depart from teacher where tno in (select tno from course);
select class,count(*) as '男生数量' from student where ssex='男' group by class having count(*)>=2;
select * from student; select * from student where sname not like '王%';
select year(now()); select year(sbirthday) from student; select year(now())-year(sbirthday),sname from student;
select sbirthday from student order by sbirthday; select max(sbirthday) as '最小', min(sbirthday) as '最大' from student;
select * from student order by class desc,sbirthday;
select * from teacher where tsex='男'; select cname from course where tno in (select tno from teacher where tsex='男'); select cname,tname,tsex from course,teacher where course.tno=teacher.tno and tsex='男';
select sno,cno,degree from score where degree = (select max(degree) from score); # 按学科分 select sno,cno,degree from score a where degree=(select max(degree) from score b where b.cno=a.cno);
select ssex from student where sname='陈宇韶'; select sname,ssex from student where ssex = (select ssex from student where sname='陈宇韶');
select sname,ssex from student where ssex = (select ssex from student where sname='陈宇韶') and class = (select class from student where sname='陈宇韶');
select cno from course where cname = '数学'; select degree ,sname from score,student where ssex='男' and cno=(select cno from course where cname = '数学'); select student.sno,ssex,degree,cname from score,student,course where score.sno=student.sno and score.cno=course.cno and ssex='男'and cname='数学';
create table grade( low int(3), upp int(3), grade char(1) ); insert into grade values (90,100,'A'); insert into grade values (80,89,'B'); insert into grade values (70,79,'C'); insert into grade values (60,69,'D'); insert into grade values (0,59,'E');
select sno ,cno,degree,grade from score,grade where (degree between low and upp) ; # 这里相当于用另一种方法进行了多表的粘合。
# 查看分组的内部信息。group_concat(字段) select sell_date,count(distinct(product))as num_sold,group_concat(distinct(product))as products from Activities group by sell_date order by sell_date; 输入: Activities 表: + | sell_date | product | + | 2020-05-30 | Headphone | | 2020-06-01 | Pencil | | 2020-06-02 | Mask | | 2020-05-30 | Basketball | | 2020-06-01 | Bible | | 2020-06-02 | Mask | | 2020-05-30 | T-Shirt | + 输出: + | sell_date | num_sold | products | + | 2020-05-30 | 3 | Basketball,Headphone,T-shirt | | 2020-06-01 | 2 | Bible,Pencil | | 2020-06-02 | 1 | Mask | +
SQL 的四种连接查询
内连接 inner join 或者 join
外连接 1.左连接 left join 或者 left outer join
2.右连接 right join 或者 right outer join
3.完全外连接 full join 或者 full outer join
create database testJoin;
create table person( id int, name varchar(20), cardId int );
create table card( id int, name varchar(20) );
insert into card values(1,'工行卡'); insert into card values(2,'建行卡'); insert into card values(3,'农行卡'); insert into card values(4,'中行卡'); insert into card values(5,'交行卡'); insert into card values(6,'饭卡');
insert into person values(1,'陈宇韶',1); insert into person values(2,'周建宇',3); insert into person values(3,'罗志康',6);
select * from person inner join card on person.cardId=card.id; + | id | name | cardId | id | name | + | 1 | 陈宇韶 | 1 | 1 | 工行卡 | | 2 | 周建宇 | 3 | 3 | 农行卡 | +
select * from person join card on person.cardId=card.id;
select * from person left join card on person.cardId=card.id; + | id | name | cardId | id | name | + | 1 | 陈宇韶 | 1 | 1 | 工行卡 | | 2 | 周建宇 | 3 | 3 | 农行卡 | | 3 | 罗志康 | 7 | NULL | NULL | +
select * from person right join card on person.cardId=card.id; + | id | name | cardId | id | name | + | 1 | 陈宇韶 | 1 | 1 | 工行卡 | | 2 | 周建宇 | 3 | 3 | 农行卡 | | NULL | NULL | NULL | 2 | 建行卡 | | NULL | NULL | NULL | 4 | 中行卡 | | NULL | NULL | NULL | 5 | 交行卡 | | NULL | NULL | NULL | 6 | 饭卡 | +
select * from person full join card on person.cardId=card.id;
select * from person left join card on person.cardId=card.id union select * from person right join card on person.cardId=card.id; + | id | name | cardId | id | name | + | 1 | 陈宇韶 | 1 | 1 | 工行卡 | | 2 | 周建宇 | 3 | 3 | 农行卡 | | 3 | 罗志康 | 7 | NULL | NULL | | NULL | NULL | NULL | 2 | 建行卡 | | NULL | NULL | NULL | 4 | 中行卡 | | NULL | NULL | NULL | 5 | 交行卡 | | NULL | NULL | NULL | 6 | 饭卡 | +
mysql 中,事务其实是一个最小的不可分割的工作单元。事务能保证一个业务的完整性。 比如 银行转账。a转给b 1000元钱。 a -> 1000 update user set money=money-1000 where name='a';
b update user set money=money+1000 where name='a';
1、mysql是默认开启事务的。autocommit (自动提交) select @@autocommit; + | @@autocommit | + | 1 | +
create database bank; create table user( id int primary key, name varchar(20), money int ); insert into user values(1,'陈宇韶',1000);
rollback; rollback; Query OK, 0 rows affected (0.00 sec)
mysql> select * from user; + | id | name | money | + | 1 | 陈宇韶 | 1000 | + 1 row in set (0.00 sec)
set autocommit=0;select @@autocommit; + | @@autocommit | + | 0 | + 1 row in set (0.00 sec)
insert into user values(2,'陈文君',1); select * from user; + | id | name | money | + | 1 | 陈宇韶 | 1000 | | 2 | 陈文君 | 1 | + 2 rows in set (0.00 sec)
rollback ; select * from user; + | id | name | money | + | 1 | 陈宇韶 | 1000 | + 1 row in set (0.00 sec)
insert into user values(2,'陈文君',1); commit; rollback ; select * from user; + | id | name | money | + | 1 | 陈宇韶 | 1000 | | 2 | 陈文君 | 1 | + 2 rows in set (0.00 sec)
set autocommit=1; update user set money=money-1000 where name='陈宇韶'; update user set money=money+1000 where name='陈文君'; rollback ;
begin; update user set money=money-1000 where name='陈宇韶'; update user set money=money+1000 where name='陈文君';
事务的四大特征: A 原子性:事务是最小单位,不可再分。 C 一致性:事务要求,同一事务中的sql语句,必须保证同时成功或者同时失败。 I 隔离性:事务1 和事务2 之间是具有隔离性的。 D 持久性:事务一旦结束(commit,rollback),就不可以返回。
事务开启: 1、修改默认不提交 set autocommit=0; 2、begin; 3、start transaction ; 事务手动提交(只对增删改有效,对查无效。): commit; 事务回滚: rollback;
事务的隔离性(以下为隔离级别): 1、read uncommitted; 2、read committed; 3、repeatable read ; 4、serializable;
1、read uncommitted;
如果有事务a,和事务b, a 事务对数据进行操作,在操作的过程中,事务没有被提交,但是b 可以看见a 的操作结果。这样导致了脏读。
insert into user values(3,'邓建楚',1000); insert into user values(4,'淘宝店',1000);
mysql 8.0:
select @@global.transaction_isolation;
select @@transaction_isolation
set global transaction isolation level read uncommitted; select @@global.transaction_isolation; + | @@global.transaction_isolation | + | READ-UNCOMMITTED | +
start transaction; update user set money=money-500 where name='邓建楚'; update user set money=money+500 where name='淘宝店';
select * from user; + | id | name | money | + | 1 | 陈宇韶 | 0 | | 2 | 陈文君 | 1001 | | 3 | 邓建楚 | 500 | | 4 | 淘宝店 | 1500 | +
rollback; select * from user; + | id | name | money | + | 1 | 陈宇韶 | 0 | | 2 | 陈文君 | 1001 | | 3 | 邓建楚 | 1000 | | 4 | 淘宝店 | 1000 | +
2、read committed;
set global transaction isolation level read committed; select @@global.transaction_isolation; + | @@global.transaction_isolation | + | READ-COMMITTED | +
bank 数据库 user 表 小陈:银行员工 start transaction; select * from user;
小陈 去厕所 小王:在小王这终端打开user表 ,新建事务。 start transaction; insert into user values(5,'罗志康',100); commit; select * from user; + | id | name | money | + | 1 | 陈宇韶 | 1000 | | 2 | 陈文君 | 1000 | | 3 | 邓建楚 | 1000 | | 4 | 淘宝店 | 1000 | | 5 | 罗志康 | 100 | +
小陈上完厕所回来。算了以下user表的平均数。此时由于终端还停留着以下显示: + | id | name | money | + | 1 | 陈宇韶 | 1000 | | 2 | 陈文君 | 1000 | | 3 | 邓建楚 | 1000 | | 4 | 淘宝店 | 1000 | + select avg(money) from user; + | avg(money) | + | 820.0000 | +
3、repeatable read
set global transaction isolation level repeatable read; select @@global.transaction_isolation; + | @@global.transaction_isolation | + | READ-COMMITTED | +
begin; select * from user; + | id | name | money | + | 1 | 陈宇韶 | 1000 | | 2 | 陈文君 | 1000 | | 3 | 邓建楚 | 1000 | | 4 | 淘宝店 | 1000 | | 5 | 罗志康 | 100 | +
begin;
insert into user values(6,'暴走',1000); select * from user; + | id | name | money | + | 1 | 陈宇韶 | 1000 | | 2 | 陈文君 | 1000 | | 3 | 邓建楚 | 1000 | | 4 | 淘宝店 | 1000 | | 5 | 罗志康 | 100 | | 6 | 暴走 | 1000 | +
+ | id | name | money | + | 1 | 陈宇韶 | 1000 | | 2 | 陈文君 | 1000 | | 3 | 邓建楚 | 1000 | | 4 | 淘宝店 | 1000 | | 5 | 罗志康 | 100 | +
insert into user values(6,'暴走',1000);
4、serializable; 串行化 set global transaction isolation level serializable; select @@global.transaction_isolation;
start transaction; insert into user values(7,'李铁柱',1000); insert into user values(8,'王小花',1000);
start transaction; insert into user values(8,'王小花',1000);
commit;
read-uncommitted > read-committed > repeatable-read > serializable;
|