MySQL传智播客--Lession13-Lession24笔记
2016-07-07 16:35
281 查看
================lession13==列属性=============================
是否为空
规定一个字段的值,是否可以是null
Null | not null
create table php1(
a int not null,
b int
);
insert into php1 (a) values(10);
mysql> select * from php1;
+----+------+
| a | b |
+----+------+
| 10 | NULL |
+----+------+
insert into php1 (b) values(11);//数据库崩溃了
默认值属性:
Default value 来声明
默认值,在没有为该字段设置值时启用。而且默认值的设置,需要使用固定值
常见的是:一个字段不能为空,而且存在默认值。
create table php2(
a int not null default 10,
b int not null default 21
);
insert into php2 (a) values(10);
insert into php2 (b) values(11);
create table php3(
a int not null default 10,
b int default 21
);
insert into php3 values(20,null);
主键:PK,primary key.
可以唯一标识,某条记录的字段或者是字段的集合,就是主键。
主键可以是真实实体的属性。
但是常用的好的解决方案是:
利用一个与实体信息不相关的属性,作为唯一标识
主键与业务逻辑不发生关系,只用来标识记录。
设置主键的语法:
Primary key完成。
两种方案:
1.字段上设置
方案一:
create table teacher(
t_id int primary key,
t_name varchar(5),
classs_name varchar(6),
days tinyint unsigned
);
insert into teacher values(1,'韩A','0331',25);
insert into teacher values(1,'李A','0228',22); // 主键不能相同
insert into teacher values(null,'李A','0228',22); // 主键也不能为空
insert into teacher values(-1,'李A','0228',22); // 主键能否为负数看数据类型
方案二:(可以设置多列作为主键)
create table teacher2(
t_id int,
t_name varchar(5),
classs_name varchar(6),
days tinyint unsigned,
primary key(t_id)
);
create table teacher3(
t_id int,
t_name varchar(5),
class_name varchar(6),
days tinyint unsigned,
primary key(t_name,class_name)
);
create table teacher4(
t_name varchar(5),
class_name varchar(6),
days tinyint unsigned,
primary key(t_name,class_name) //一个主键包含2个字段
);
注意:组合主键的意义
一个主键内包括多个字段,而不是多个字段都是主键。
只需要一个唯一标识即可,mysql规定只能存在一个主键。
要求:
常见的设计,每一个表都应该存在一个可以唯一标识的主键字段。最好与实体没有联系,
不是实体属性字段。
=======================lession14==自动增长=============================
自动增长:
为每条记录提供给一个唯一的标识。
每次插入记录时,将某个字段的值自动增加1;
使用auto increment 标识。
需要整型,还需要有索引。
create table teacher5(
t_id int primary key auto_increment,
t_name varchar(5),
classs_name varchar(6),
days tinyint unsigned
);
插入数据时,可以选择插入null,或者不插入:
insert into teacher5 values(null,'韩B','0228',34);
+------+--------+-------------+------+
| t_id | t_name | classs_name | days |
+------+--------+-------------+------+
| 1 | 韩B | 0228 | 34 |
+------+--------+-------------+------+
insert into teacher5 (t_name, classs_name, days)values('韩B','0228',34);
+------+--------+-------------+------+
| t_id | t_name | classs_name | days |
+------+--------+-------------+------+
| 1 | 韩B | 0228 | 34 |
| 2 | 韩B | 0228 | 34 |
+------+--------+-------------+------+
自动增长的初始值,是可以设置的,默认是1
通过表选项;auto_increment=n
alter table teacher5 auto_increment 10;
insert into teacher5 values(null,'韩B','0115',32);
+------+--------+-------------+------+
| t_id | t_name | classs_name | days |
+------+--------+-------------+------+
| 1 | 韩B | 0228 | 34 |
| 2 | 韩B | 0228 | 34 |
| 10 | 韩B | 0115 | 32 |
+------+--------+-------------+------+
如果n的值小于已经存在的主键的值
alter table teacher5 auto_increment 5;
insert into teacher5 values(null,'赵A','0115',32);
+------+--------+-------------+------+
| t_id | t_name | classs_name | days |
+------+--------+-------------+------+
| 1 | 韩B | 0228 | 34 |
| 2 | 韩B | 0228 | 34 |
| 10 | 韩B | 0115 | 32 |
| 11 | 赵A | 0115 | 32 |
+------+--------+-------------+------+
insert into teacher5 values(5,'谢A','0115',32);
是否可以手动插入该列的值?可以
+------+--------+-------------+------+
| t_id | t_name | classs_name | days |
+------+--------+-------------+------+
| 1 | 韩B | 0228 | 34 |
| 2 | 韩B | 0228 | 34 |
| 10 | 韩B | 0115 | 32 |
| 11 | 赵A | 0115 | 32 |
| 5 | 谢A | 0115 | 32 |
+------+--------+-------------+------+
该列是否可以更新?可以
update teacher5 set t_id=21 where t_name='赵A';
+------+--------+-------------+------+
| t_id | t_name | classs_name | days |
+------+--------+-------------+------+
| 1 | 韩B | 0228 | 34 |
| 2 | 韩B | 0228 | 34 |
| 10 | 韩B | 0115 | 32 |
| 21 | 赵A | 0115 | 32 |
| 5 | 谢A | 0115 | 32 |
+------+--------+-------------+------+
测试:自动增长设置为20,数据库内已经存在大于二十的记录,删除所有的大于20的记录。
问:插入数据时,ID为多少? 为22,数据库会保留原来已经存在的记录ID
create table teacher6(
t_id int primary key auto_increment,
t_name varchar(5),
class_name varchar(6),
days tinyint unsigned
);
insert into teacher6 values(21,'谢A','0115',32);
mysql> select * from teacher6;
+------+--------+------------+------+
| t_id | t_name | class_name | days |
+------+--------+------------+------+
| 21 | 谢A | 0115 | 32 |
+------+--------+------------+------+
alter table teacher6 auto_increment 20;
ql> delete from teacher6 where t_id=21;
Query OK, 1 row affected (0.12 sec)
insert into teacher6 values(null,'李A','0116',30);
mysql> select * from teacher6;
+------+--------+------------+------+
| t_id | t_name | class_name | days |
+------+--------+------------+------+
| 22 | 李A | 0116 | 30 |
+------+--------+------------+------+
=======================lession15==实体(1)=============================
实体:(1)常用信息表(2)详细信息表(一对一的关系)
1:1
设计:
两个实体表内,存在相同的主键字段。
如果记录的主键值等于另一个关系表内记录的主键值,则两条记录对应 1:1对应。
1:N (一对多)
一个实体,对应多个其他 实体。
例如一个班级对应多个学生。
设计:
在多的那端(N那端),增加一个字段,用于指向该实体所属的另外的实体标识。
M:N多对多:
例如一个老师教过很多班级。一个班级也同时被多个老师教过。
设计:
典型的,利用一个中间表,表示实体之间的对应关系。
讲师主键 讲师姓名
1 韩顺平
3 韩忠康
班级主键 班级号
开班时间
29 PHP0228
2013-02-28
30 PHP0331
2013-03-31
讲师ID 班级ID
1 29
3 29
3 30
中间表的每个记录,表示一个关系。
可以分析:
一个M:N
1:M
1:N
来实现。
作业:用Microsoft Visio画出上面的关系图
=======================lession16==实体(2)=============================
练习更多的实体直接的关系,以及模型
=======================lession17=外键(1)=============================
外键 foreign key
概念:
如果一个实体的(student)的某个字段(student: class id), 指向(引用)另一个实体(class)的
主键(class:class_id),就称student实体的class_id是外键。
被指向的实体称为主实体(主表),也叫父实体(父表)。 class
负责指向的实体,称之为从实体(从表),也叫子实体(子表)。 Student
作用:
用于约束处于关系内的实体。
增加子表记录时,是否有与之对应的父表记录。
在删除或者更新主表记录时,从表应该如何处理相关的记录。
定义一个外键:
在从表上,增加一个字段,指向主表的主键。
使用关键字foreign key
// comment 这个是注释的意思
drop table if exists itcast_class; // 如果已经存在表itcast_class则删除
create table itcast_class(
class_id int primary key auto_increment,
class_name varchar(10) not null default 'itcast_php' comment '班级名称'
)ENGINE=InnoDB character set utf8;
drop table if exists itcast_student;
create table itcast_student(
stu_id int primary key auto_increment,
stu_name varchar(10) not null default '',
class_id int,
foreign key(class_id) references itcast_class (class_id)
)ENGINE=InnoDB character set utf8;
//奇怪的是设计了外键它还可以插入
Insert into itcast_student valuse(null,'lishi',1);
=======================lession18=外键(1)=============================
设置级联操作:
在主表数据发生改变时,与之关联的从表数据应该如何处理:
主表更新:
主表删除:
使用关键字:
On update
On delete来标识。
允许的级联动作:
Cascade关联操作,如果主表被更新或删除,那么从表也会执行相应的操作。
Set null 设置为null,表示从表不指向任何 主表记录。
Restrict: 拒绝主表的相关操作。
修改这个外键:
先删除,再新建。通过修改表完成。
Alter table tbl_name drop foreign key (class_id);
删除外键需要通过指定外键名称达到目的:
可以通过在创建外键是,指定名称,或者使用mysql默认生成的名称
Set null操作:
关联子设置为空:
测试删除:
Alter table tbl_name add foreign key (class_id);
// DROP FOREIGN KEY fk_symbol
CONSTRAINT `itcast_student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `itcast_class` (`class_id`)
Alter table itcast_student drop foreign key itcast_student_ibfk_1;
Alter table itcast_student add foreign key (class_id) references itcast_class (class_id)
on delete set null; // on delete set null意思是删除时,将从表外键,设置为null(前提可以为null)
Delete from itcast_class where class_id=1;
Cascade级联操作:
Insert into itcast_class values(1,'php0331');
Update itcaset_student set class_id=1 where stu_id=1;
Alter table itcast_student add foreign key (class_id) references itcast_class (class_id)
on delete cascade; // cascade级联操作,删除主表时从表的记录也会被删除一般建议是set null
//因为 cascade是不可逆的
测试删除:
delete from itcast_class where class_id=1;
主表和从表都被删除了
On update
指的是只有主表的主键发生变化,才会对从表发生影响
insert into itcast_class values(1,'php0331');
Update itcast_student set class_id=1 where stu_id=2;
Alter table itcast_student drop foreign key itcast_student_ibfk_1;
Alter table itcast_student add foreign key (class_id) references itcast_class (class_id)
on delete cascade //cascade和set null只能在同一时间设置一个
on update restrict; //更新时不允许操作
Alter table itcast_student drop foreign key itcast_student_ibfk_1;
Alter table itcast_student add foreign key (class_id) references itcast_class (class_id)
on update restrict; //更新时不允许操作
Restrict
更新存在关联的主表数据的主键字段:
mysql> update itcast_class set class_id=2 where class_name='php0331';
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test1/itcast_student`, CONSTRAINT `itcast_student_ibfk_4` FOREIGN KEY (`class_id`) REFERENCES `itcast_class` (`class_id`))
=======================lession19=存储引擎=============================
默认的服务器表类型,通过my.ini可以配置:
在mysql5.5之后是默认是InnoDB
Default-storage-engine=Myisam, or InnoDB
在创建表或者编辑表时,可以指定表的存储引擎。
利用表属性:engine表引擎类型
Engine Myisam
Engine InnoDB
//如果表有外键约束存在则操作不成功
Alter table itcast_class engine Myisam;
Alter table itcast_class engine InnoDB;
Innodb & myisam区别:
保存的文件的方式不同:
Myisam:
一个表,三个文件
Tbl_name.frm 结构
Tbl_name.myd 数据
Tbl_name.myi 索引
Innodb:
一个表一个文件:
Tbl_name.frm 结构
所有的innodb表,都使用相同的
innodb存储表空间来保存数据和索引。
Myisam:
优势:插入,索引 ,
劣势:表锁(整个表都锁起来)所以高并发支持不好
Innodb:
优势:更新,删除,高并发
补充:但是甲骨文在倾向于innodb加跟多功能比如5.5开始innodb支持全文索引
选择存储引擎的依据:
1.性能
2.功能
=======================lession20 order by=============================
Order by
按字段值进行排序
Order by 字段 升序或降序(asc|desc) //校对规则决定排序关系
// asc (ascending) desc (descending)
允许多字段排序,
指的是,先按照第一个字段排序,如果说,不能区分,才使用第二个字段。以此类推
Create table teacher_class (
Id int primary key auto_increment,
T_name varchar(4),
Gender enum('female','male'),
C_name varchar(6),
Room int unsigned,
Days tinyint,
Begin_date date,
End_date date
);
Iinsert into teacher_class values(1,'韩信','male','php0115',207,21,'2013-01-15','2013-02-20');
insert into teacher_class values(null,'韩信','male','php0228',106,18,'2013-02-28','2013-03-30');
insert into teacher_class values(null,'韩信','male','php0331',102,22,'2013-03-31','2013-05-05');
insert into teacher_class values(null,'李白','male','php0115',207,20,'2013-02-22','2013-03-25');
insert into teacher_class values(null,'李白','male','php0228',204,22,'2013-03-31','2013-04-29');
insert into teacher_class values(null,'韩非子','male','php0115',207,15,'2013-03-27','2013-04-18');
insert into teacher_class values(null,'韩非子','male','php0331',106,15,'2013-5-28','2013-06-15');
mysql> select * from teacher_class;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
mysql> select * from teacher_class order by days desc;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
mysql> select * from teacher_class order by days asc;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
+----+--------+--------+--------+------+------+------------+------------+
mysql> select * from teacher_class order by days desc,begin_date;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
mysql> select * from teacher_class order by days desc,begin_date desc;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
+----+--------+--------+--------+------+------+------------+------------+
mysql> select * from teacher_class order by days desc,begin_date desc, end_date asc;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
+----+--------+--------+--------+------+------+------------+------------+
注意:如果是分组,则应该使用对分组字段进行排序的group by语法。
=======================lession21=Limit=============================
Limit:
限制获得的记录的数量:
Row1 0
Row2 1
Row3 2
Row4 3
Row5 4
Limit的语法:
Limit offset ,row count
Offset 偏移量,从0开始。可以省略
默认为0。
Row_count 总记录数,如果数量大于,余下的记录数,则获取所有余下的即可:
需要获得 row2-row4
Offset 1
Row_count 3
mysql> select * from teacher_class limit 3,4;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
注意:设置了一个表的id primary key auto_increment ;后当删除一个记录假设这记录的ID为
4且id=4为当时表ID最大的值,那么再插入一条记录后,id是从5开始的。
Offset 偏移量,从0开始。可以省略,默认为0
mysql> select * from teacher_class limit 5;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
+----+--------+--------+--------+------+------+------------+------------+
Row_count 总记录数,如果数量大于,余下的记录数,则获取所有余下的即可:
mysql> select * from teacher_class limit 5,100;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
=======================lession22=distinct=============================
Distinct
去除重复记录:
重复的记录,指的是,字段值,都相同的记录,而不是部分字段相同的记录。
相对的是all,表示所有。默认就是all行为。
mysql> select days from teacher_class;
+------+
| days |
+------+
| 21 |
| 18 |
| 22 |
| 20 |
| 22 |
| 15 |
| 15 |
+------+
7 rows in set (0.00 sec)
mysql> select distinct days from teacher_class;
+------+
| days |
+------+
| 21 |
| 18 |
| 22 |
| 20 |
| 15 |
+------+
5 rows in set (0.09 sec)
mysql> select * from teacher_class;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
7 rows in set (0.00 sec)
mysql> select distinct * from teacher_class;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
7 rows in set (0.00 sec)
mysql> select days,begin_date from teacher_class;
+------+------------+
| days | begin_date |
+------+------------+
| 21 | 2013-01-15 |
| 18 | 2013-02-28 |
| 22 | 2013-03-31 |
| 20 | 2013-02-22 |
| 22 | 2013-03-31 |
| 15 | 2013-03-27 |
| 15 | 2013-05-28 |
+------+------------+
7 rows in set (0.00 sec)
Distinct后面跟两个字段时,要两个字段同时相同才会去掉,如果只是两个字段中的一个字段相同时,会保留下来
mysql> select distinct days,begin_date from teacher_class;
+------+------------+
| days | begin_date |
+------+------------+
| 21 | 2013-01-15 |
| 18 | 2013-02-28 |
| 22 | 2013-03-31 |
| 20 | 2013-02-22 |
| 15 | 2013-03-27 |
| 15 | 2013-05-28 |
+------+------------+
6 rows in set (0.00 sec)
=======================lession23=union(1)=============================
联合查询
mysql> select t_name,days from teacher_class where c_name='php011';
+--------+------+
| t_name | days |
+--------+------+
| 韩� | 21 |
| 李� | 20 |
| 韩� | 15 |
+--------+------+
3 rows in set (0.00 sec)
mysql> select t_name,days from teacher_class where c_name='php011' order by days desc;
+--------+------+
| t_name | days |
+--------+------+
| 韩� | 21 |
| 李� | 20 |
| 韩� | 15 |
+--------+------+
3 rows in set (0.00 sec)
mysql> select t_name,days from teacher_class where c_name='php011' order by days desc limit 1;
+--------+------+
| t_name | days |
+--------+------+
| 韩� | 21 |
+--------+------+
mysql> select t_name,days from teacher_class where c_name='php022' order by days desc limit 1;
+--------+------+
| t_name | days |
+--------+------+
| 李� | 22 |
+--------+------+
=======================lession24=union(2)=============================
将多条select 语句的结果,合并到一起。称之为联合操作。
union联合
使用union关键字 联合 两个select语句即可:
(select t_name,days from teacher_class where c_name='php011' order by days desc limit 1)
Union
(select t_name,days from teacher_class where c_name='php022' order by days desc limit 1);
mysql> (select t_name,days from teacher_class where c_name='php011' order by days desc limit 1)
-> Union
-> (select t_name,days from teacher_class where c_name='php022' order by days desc limit 1);
+--------+------+
| t_name | days |
+--------+------+
| 韩� | 21 |
| 李� | 22 |
+--------+------+
2 rows in set (0.03 sec)
场景:
获得数据的条件,出现逻辑冲突,或者很难在一个逻辑内表示,就可以拆分成多个逻辑,分别实现最后将结果合并到一起。
Union all环境:
获得0115班所有代课老师,结果按照代课天数升序排序,同时需要获得0228班,结果按照降序排序
注意:如果union的结果存在重复的记录,那么会消除重复。可以通过union选项all达到目的。
(Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union
(Select t_name,days,c_name from teacher_class where c_name='php0228' order by days desc limit 10);
(Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all
(Select t_name,days,c_name from teacher_class where c_name='php0228' order by days desc limit 10);
排序:
子语句结果的排序:
1.将子语句包裹子括号内。
2.子语句的order by,只有在order by 配合limit时,才生效。原因是:union在做子语句时,会对没有limit子句的order by 优化(忽略);
对所有结果进行统一排序:
只需要在最后一个select语句后,增加相应的排序规则即可:
(Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all
(Select t_name,days,c_name from teacher_class where c_name='php0228' order by days desc limit 10) order by days;
提示:
子语句没有括号也可以,但是读起来不友好,建议每一个子语句,加一个括号。
注意:
规定,多个select语句的检索到的字段数,必须一致。
mysql> (Select days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all (Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all(Select t_name,days,c_name from teacher_class where
c_name='php0228' order by days desc limit 10);
ERROR 1222 (21000): The used SELECT statements have a different number of columns
更加严格的是,数据类型上,应该也有要求一致:但是,mysql内部做类型转换处理:要求是能够转换成功;
mysql> (Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all (Select days,t_name,c_name from teacher_class where c_name='php0228' order by days desc limit 10);
+----------+----------+---------+
| t_name | days | c_name |
+----------+----------+---------+
| 韩é | 15 | php0115 |
| æŽç | 20 | php0115 |
| 韩ä | 21 | php0115 |
| 22 | æŽç | php0228 |
| 18 | 韩ä | php0228 |
+----------+----------+---------+
5 rows in set (0.00 sec)
检索结果中的列名称问题:
第一条select语句的列名而定;
是否为空
规定一个字段的值,是否可以是null
Null | not null
create table php1(
a int not null,
b int
);
insert into php1 (a) values(10);
mysql> select * from php1;
+----+------+
| a | b |
+----+------+
| 10 | NULL |
+----+------+
insert into php1 (b) values(11);//数据库崩溃了
默认值属性:
Default value 来声明
默认值,在没有为该字段设置值时启用。而且默认值的设置,需要使用固定值
常见的是:一个字段不能为空,而且存在默认值。
create table php2(
a int not null default 10,
b int not null default 21
);
insert into php2 (a) values(10);
insert into php2 (b) values(11);
create table php3(
a int not null default 10,
b int default 21
);
insert into php3 values(20,null);
主键:PK,primary key.
可以唯一标识,某条记录的字段或者是字段的集合,就是主键。
主键可以是真实实体的属性。
但是常用的好的解决方案是:
利用一个与实体信息不相关的属性,作为唯一标识
主键与业务逻辑不发生关系,只用来标识记录。
设置主键的语法:
Primary key完成。
两种方案:
1.字段上设置
方案一:
create table teacher(
t_id int primary key,
t_name varchar(5),
classs_name varchar(6),
days tinyint unsigned
);
insert into teacher values(1,'韩A','0331',25);
insert into teacher values(1,'李A','0228',22); // 主键不能相同
insert into teacher values(null,'李A','0228',22); // 主键也不能为空
insert into teacher values(-1,'李A','0228',22); // 主键能否为负数看数据类型
方案二:(可以设置多列作为主键)
create table teacher2(
t_id int,
t_name varchar(5),
classs_name varchar(6),
days tinyint unsigned,
primary key(t_id)
);
create table teacher3(
t_id int,
t_name varchar(5),
class_name varchar(6),
days tinyint unsigned,
primary key(t_name,class_name)
);
create table teacher4(
t_name varchar(5),
class_name varchar(6),
days tinyint unsigned,
primary key(t_name,class_name) //一个主键包含2个字段
);
注意:组合主键的意义
一个主键内包括多个字段,而不是多个字段都是主键。
只需要一个唯一标识即可,mysql规定只能存在一个主键。
要求:
常见的设计,每一个表都应该存在一个可以唯一标识的主键字段。最好与实体没有联系,
不是实体属性字段。
=======================lession14==自动增长=============================
自动增长:
为每条记录提供给一个唯一的标识。
每次插入记录时,将某个字段的值自动增加1;
使用auto increment 标识。
需要整型,还需要有索引。
create table teacher5(
t_id int primary key auto_increment,
t_name varchar(5),
classs_name varchar(6),
days tinyint unsigned
);
插入数据时,可以选择插入null,或者不插入:
insert into teacher5 values(null,'韩B','0228',34);
+------+--------+-------------+------+
| t_id | t_name | classs_name | days |
+------+--------+-------------+------+
| 1 | 韩B | 0228 | 34 |
+------+--------+-------------+------+
insert into teacher5 (t_name, classs_name, days)values('韩B','0228',34);
+------+--------+-------------+------+
| t_id | t_name | classs_name | days |
+------+--------+-------------+------+
| 1 | 韩B | 0228 | 34 |
| 2 | 韩B | 0228 | 34 |
+------+--------+-------------+------+
自动增长的初始值,是可以设置的,默认是1
通过表选项;auto_increment=n
alter table teacher5 auto_increment 10;
insert into teacher5 values(null,'韩B','0115',32);
+------+--------+-------------+------+
| t_id | t_name | classs_name | days |
+------+--------+-------------+------+
| 1 | 韩B | 0228 | 34 |
| 2 | 韩B | 0228 | 34 |
| 10 | 韩B | 0115 | 32 |
+------+--------+-------------+------+
如果n的值小于已经存在的主键的值
alter table teacher5 auto_increment 5;
insert into teacher5 values(null,'赵A','0115',32);
+------+--------+-------------+------+
| t_id | t_name | classs_name | days |
+------+--------+-------------+------+
| 1 | 韩B | 0228 | 34 |
| 2 | 韩B | 0228 | 34 |
| 10 | 韩B | 0115 | 32 |
| 11 | 赵A | 0115 | 32 |
+------+--------+-------------+------+
insert into teacher5 values(5,'谢A','0115',32);
是否可以手动插入该列的值?可以
+------+--------+-------------+------+
| t_id | t_name | classs_name | days |
+------+--------+-------------+------+
| 1 | 韩B | 0228 | 34 |
| 2 | 韩B | 0228 | 34 |
| 10 | 韩B | 0115 | 32 |
| 11 | 赵A | 0115 | 32 |
| 5 | 谢A | 0115 | 32 |
+------+--------+-------------+------+
该列是否可以更新?可以
update teacher5 set t_id=21 where t_name='赵A';
+------+--------+-------------+------+
| t_id | t_name | classs_name | days |
+------+--------+-------------+------+
| 1 | 韩B | 0228 | 34 |
| 2 | 韩B | 0228 | 34 |
| 10 | 韩B | 0115 | 32 |
| 21 | 赵A | 0115 | 32 |
| 5 | 谢A | 0115 | 32 |
+------+--------+-------------+------+
测试:自动增长设置为20,数据库内已经存在大于二十的记录,删除所有的大于20的记录。
问:插入数据时,ID为多少? 为22,数据库会保留原来已经存在的记录ID
create table teacher6(
t_id int primary key auto_increment,
t_name varchar(5),
class_name varchar(6),
days tinyint unsigned
);
insert into teacher6 values(21,'谢A','0115',32);
mysql> select * from teacher6;
+------+--------+------------+------+
| t_id | t_name | class_name | days |
+------+--------+------------+------+
| 21 | 谢A | 0115 | 32 |
+------+--------+------------+------+
alter table teacher6 auto_increment 20;
ql> delete from teacher6 where t_id=21;
Query OK, 1 row affected (0.12 sec)
insert into teacher6 values(null,'李A','0116',30);
mysql> select * from teacher6;
+------+--------+------------+------+
| t_id | t_name | class_name | days |
+------+--------+------------+------+
| 22 | 李A | 0116 | 30 |
+------+--------+------------+------+
=======================lession15==实体(1)=============================
实体:(1)常用信息表(2)详细信息表(一对一的关系)
1:1
设计:
两个实体表内,存在相同的主键字段。
如果记录的主键值等于另一个关系表内记录的主键值,则两条记录对应 1:1对应。
1:N (一对多)
一个实体,对应多个其他 实体。
例如一个班级对应多个学生。
设计:
在多的那端(N那端),增加一个字段,用于指向该实体所属的另外的实体标识。
M:N多对多:
例如一个老师教过很多班级。一个班级也同时被多个老师教过。
设计:
典型的,利用一个中间表,表示实体之间的对应关系。
讲师主键 讲师姓名
1 韩顺平
3 韩忠康
班级主键 班级号
开班时间
29 PHP0228
2013-02-28
30 PHP0331
2013-03-31
讲师ID 班级ID
1 29
3 29
3 30
中间表的每个记录,表示一个关系。
可以分析:
一个M:N
1:M
1:N
来实现。
作业:用Microsoft Visio画出上面的关系图
=======================lession16==实体(2)=============================
练习更多的实体直接的关系,以及模型
=======================lession17=外键(1)=============================
外键 foreign key
概念:
如果一个实体的(student)的某个字段(student: class id), 指向(引用)另一个实体(class)的
主键(class:class_id),就称student实体的class_id是外键。
被指向的实体称为主实体(主表),也叫父实体(父表)。 class
负责指向的实体,称之为从实体(从表),也叫子实体(子表)。 Student
作用:
用于约束处于关系内的实体。
增加子表记录时,是否有与之对应的父表记录。
在删除或者更新主表记录时,从表应该如何处理相关的记录。
定义一个外键:
在从表上,增加一个字段,指向主表的主键。
使用关键字foreign key
// comment 这个是注释的意思
drop table if exists itcast_class; // 如果已经存在表itcast_class则删除
create table itcast_class(
class_id int primary key auto_increment,
class_name varchar(10) not null default 'itcast_php' comment '班级名称'
)ENGINE=InnoDB character set utf8;
drop table if exists itcast_student;
create table itcast_student(
stu_id int primary key auto_increment,
stu_name varchar(10) not null default '',
class_id int,
foreign key(class_id) references itcast_class (class_id)
)ENGINE=InnoDB character set utf8;
//奇怪的是设计了外键它还可以插入
Insert into itcast_student valuse(null,'lishi',1);
=======================lession18=外键(1)=============================
设置级联操作:
在主表数据发生改变时,与之关联的从表数据应该如何处理:
主表更新:
主表删除:
使用关键字:
On update
On delete来标识。
允许的级联动作:
Cascade关联操作,如果主表被更新或删除,那么从表也会执行相应的操作。
Set null 设置为null,表示从表不指向任何 主表记录。
Restrict: 拒绝主表的相关操作。
修改这个外键:
先删除,再新建。通过修改表完成。
Alter table tbl_name drop foreign key (class_id);
删除外键需要通过指定外键名称达到目的:
可以通过在创建外键是,指定名称,或者使用mysql默认生成的名称
Set null操作:
关联子设置为空:
测试删除:
Alter table tbl_name add foreign key (class_id);
// DROP FOREIGN KEY fk_symbol
CONSTRAINT `itcast_student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `itcast_class` (`class_id`)
Alter table itcast_student drop foreign key itcast_student_ibfk_1;
Alter table itcast_student add foreign key (class_id) references itcast_class (class_id)
on delete set null; // on delete set null意思是删除时,将从表外键,设置为null(前提可以为null)
Delete from itcast_class where class_id=1;
Cascade级联操作:
Insert into itcast_class values(1,'php0331');
Update itcaset_student set class_id=1 where stu_id=1;
Alter table itcast_student add foreign key (class_id) references itcast_class (class_id)
on delete cascade; // cascade级联操作,删除主表时从表的记录也会被删除一般建议是set null
//因为 cascade是不可逆的
测试删除:
delete from itcast_class where class_id=1;
主表和从表都被删除了
On update
指的是只有主表的主键发生变化,才会对从表发生影响
insert into itcast_class values(1,'php0331');
Update itcast_student set class_id=1 where stu_id=2;
Alter table itcast_student drop foreign key itcast_student_ibfk_1;
Alter table itcast_student add foreign key (class_id) references itcast_class (class_id)
on delete cascade //cascade和set null只能在同一时间设置一个
on update restrict; //更新时不允许操作
Alter table itcast_student drop foreign key itcast_student_ibfk_1;
Alter table itcast_student add foreign key (class_id) references itcast_class (class_id)
on update restrict; //更新时不允许操作
Restrict
更新存在关联的主表数据的主键字段:
mysql> update itcast_class set class_id=2 where class_name='php0331';
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test1/itcast_student`, CONSTRAINT `itcast_student_ibfk_4` FOREIGN KEY (`class_id`) REFERENCES `itcast_class` (`class_id`))
=======================lession19=存储引擎=============================
默认的服务器表类型,通过my.ini可以配置:
在mysql5.5之后是默认是InnoDB
Default-storage-engine=Myisam, or InnoDB
在创建表或者编辑表时,可以指定表的存储引擎。
利用表属性:engine表引擎类型
Engine Myisam
Engine InnoDB
//如果表有外键约束存在则操作不成功
Alter table itcast_class engine Myisam;
Alter table itcast_class engine InnoDB;
Innodb & myisam区别:
保存的文件的方式不同:
Myisam:
一个表,三个文件
Tbl_name.frm 结构
Tbl_name.myd 数据
Tbl_name.myi 索引
Innodb:
一个表一个文件:
Tbl_name.frm 结构
所有的innodb表,都使用相同的
innodb存储表空间来保存数据和索引。
Myisam:
优势:插入,索引 ,
劣势:表锁(整个表都锁起来)所以高并发支持不好
Innodb:
优势:更新,删除,高并发
补充:但是甲骨文在倾向于innodb加跟多功能比如5.5开始innodb支持全文索引
选择存储引擎的依据:
1.性能
2.功能
=======================lession20 order by=============================
Order by
按字段值进行排序
Order by 字段 升序或降序(asc|desc) //校对规则决定排序关系
// asc (ascending) desc (descending)
允许多字段排序,
指的是,先按照第一个字段排序,如果说,不能区分,才使用第二个字段。以此类推
Create table teacher_class (
Id int primary key auto_increment,
T_name varchar(4),
Gender enum('female','male'),
C_name varchar(6),
Room int unsigned,
Days tinyint,
Begin_date date,
End_date date
);
Iinsert into teacher_class values(1,'韩信','male','php0115',207,21,'2013-01-15','2013-02-20');
insert into teacher_class values(null,'韩信','male','php0228',106,18,'2013-02-28','2013-03-30');
insert into teacher_class values(null,'韩信','male','php0331',102,22,'2013-03-31','2013-05-05');
insert into teacher_class values(null,'李白','male','php0115',207,20,'2013-02-22','2013-03-25');
insert into teacher_class values(null,'李白','male','php0228',204,22,'2013-03-31','2013-04-29');
insert into teacher_class values(null,'韩非子','male','php0115',207,15,'2013-03-27','2013-04-18');
insert into teacher_class values(null,'韩非子','male','php0331',106,15,'2013-5-28','2013-06-15');
mysql> select * from teacher_class;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
mysql> select * from teacher_class order by days desc;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
mysql> select * from teacher_class order by days asc;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
+----+--------+--------+--------+------+------+------------+------------+
mysql> select * from teacher_class order by days desc,begin_date;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
mysql> select * from teacher_class order by days desc,begin_date desc;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
+----+--------+--------+--------+------+------+------------+------------+
mysql> select * from teacher_class order by days desc,begin_date desc, end_date asc;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
+----+--------+--------+--------+------+------+------------+------------+
注意:如果是分组,则应该使用对分组字段进行排序的group by语法。
=======================lession21=Limit=============================
Limit:
限制获得的记录的数量:
Row1 0
Row2 1
Row3 2
Row4 3
Row5 4
Limit的语法:
Limit offset ,row count
Offset 偏移量,从0开始。可以省略
默认为0。
Row_count 总记录数,如果数量大于,余下的记录数,则获取所有余下的即可:
需要获得 row2-row4
Offset 1
Row_count 3
mysql> select * from teacher_class limit 3,4;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
注意:设置了一个表的id primary key auto_increment ;后当删除一个记录假设这记录的ID为
4且id=4为当时表ID最大的值,那么再插入一条记录后,id是从5开始的。
Offset 偏移量,从0开始。可以省略,默认为0
mysql> select * from teacher_class limit 5;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
+----+--------+--------+--------+------+------+------------+------------+
Row_count 总记录数,如果数量大于,余下的记录数,则获取所有余下的即可:
mysql> select * from teacher_class limit 5,100;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
=======================lession22=distinct=============================
Distinct
去除重复记录:
重复的记录,指的是,字段值,都相同的记录,而不是部分字段相同的记录。
相对的是all,表示所有。默认就是all行为。
mysql> select days from teacher_class;
+------+
| days |
+------+
| 21 |
| 18 |
| 22 |
| 20 |
| 22 |
| 15 |
| 15 |
+------+
7 rows in set (0.00 sec)
mysql> select distinct days from teacher_class;
+------+
| days |
+------+
| 21 |
| 18 |
| 22 |
| 20 |
| 15 |
+------+
5 rows in set (0.09 sec)
mysql> select * from teacher_class;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
7 rows in set (0.00 sec)
mysql> select distinct * from teacher_class;
+----+--------+--------+--------+------+------+------------+------------+
| id | t_name | gender | c_name | room | days | begin_date | end_date |
+----+--------+--------+--------+------+------+------------+------------+
| 1 | 韩� | male | php011 | 207 | 21 | 2013-01-15 | 2013-02-20 |
| 2 | 韩� | male | php022 | 106 | 18 | 2013-02-28 | 2013-03-30 |
| 3 | 韩� | male | php033 | 102 | 22 | 2013-03-31 | 2013-05-05 |
| 5 | 李� | male | php011 | 207 | 20 | 2013-02-22 | 2013-03-25 |
| 6 | 李� | male | php022 | 204 | 22 | 2013-03-31 | 2013-04-29 |
| 7 | 韩� | male | php011 | 207 | 15 | 2013-03-27 | 2013-04-18 |
| 8 | 韩� | male | php033 | 106 | 15 | 2013-05-28 | 2013-06-15 |
+----+--------+--------+--------+------+------+------------+------------+
7 rows in set (0.00 sec)
mysql> select days,begin_date from teacher_class;
+------+------------+
| days | begin_date |
+------+------------+
| 21 | 2013-01-15 |
| 18 | 2013-02-28 |
| 22 | 2013-03-31 |
| 20 | 2013-02-22 |
| 22 | 2013-03-31 |
| 15 | 2013-03-27 |
| 15 | 2013-05-28 |
+------+------------+
7 rows in set (0.00 sec)
Distinct后面跟两个字段时,要两个字段同时相同才会去掉,如果只是两个字段中的一个字段相同时,会保留下来
mysql> select distinct days,begin_date from teacher_class;
+------+------------+
| days | begin_date |
+------+------------+
| 21 | 2013-01-15 |
| 18 | 2013-02-28 |
| 22 | 2013-03-31 |
| 20 | 2013-02-22 |
| 15 | 2013-03-27 |
| 15 | 2013-05-28 |
+------+------------+
6 rows in set (0.00 sec)
=======================lession23=union(1)=============================
联合查询
mysql> select t_name,days from teacher_class where c_name='php011';
+--------+------+
| t_name | days |
+--------+------+
| 韩� | 21 |
| 李� | 20 |
| 韩� | 15 |
+--------+------+
3 rows in set (0.00 sec)
mysql> select t_name,days from teacher_class where c_name='php011' order by days desc;
+--------+------+
| t_name | days |
+--------+------+
| 韩� | 21 |
| 李� | 20 |
| 韩� | 15 |
+--------+------+
3 rows in set (0.00 sec)
mysql> select t_name,days from teacher_class where c_name='php011' order by days desc limit 1;
+--------+------+
| t_name | days |
+--------+------+
| 韩� | 21 |
+--------+------+
mysql> select t_name,days from teacher_class where c_name='php022' order by days desc limit 1;
+--------+------+
| t_name | days |
+--------+------+
| 李� | 22 |
+--------+------+
=======================lession24=union(2)=============================
将多条select 语句的结果,合并到一起。称之为联合操作。
union联合
使用union关键字 联合 两个select语句即可:
(select t_name,days from teacher_class where c_name='php011' order by days desc limit 1)
Union
(select t_name,days from teacher_class where c_name='php022' order by days desc limit 1);
mysql> (select t_name,days from teacher_class where c_name='php011' order by days desc limit 1)
-> Union
-> (select t_name,days from teacher_class where c_name='php022' order by days desc limit 1);
+--------+------+
| t_name | days |
+--------+------+
| 韩� | 21 |
| 李� | 22 |
+--------+------+
2 rows in set (0.03 sec)
场景:
获得数据的条件,出现逻辑冲突,或者很难在一个逻辑内表示,就可以拆分成多个逻辑,分别实现最后将结果合并到一起。
Union all环境:
获得0115班所有代课老师,结果按照代课天数升序排序,同时需要获得0228班,结果按照降序排序
注意:如果union的结果存在重复的记录,那么会消除重复。可以通过union选项all达到目的。
(Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union
(Select t_name,days,c_name from teacher_class where c_name='php0228' order by days desc limit 10);
(Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all
(Select t_name,days,c_name from teacher_class where c_name='php0228' order by days desc limit 10);
排序:
子语句结果的排序:
1.将子语句包裹子括号内。
2.子语句的order by,只有在order by 配合limit时,才生效。原因是:union在做子语句时,会对没有limit子句的order by 优化(忽略);
对所有结果进行统一排序:
只需要在最后一个select语句后,增加相应的排序规则即可:
(Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all
(Select t_name,days,c_name from teacher_class where c_name='php0228' order by days desc limit 10) order by days;
提示:
子语句没有括号也可以,但是读起来不友好,建议每一个子语句,加一个括号。
注意:
规定,多个select语句的检索到的字段数,必须一致。
mysql> (Select days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all (Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all(Select t_name,days,c_name from teacher_class where
c_name='php0228' order by days desc limit 10);
ERROR 1222 (21000): The used SELECT statements have a different number of columns
更加严格的是,数据类型上,应该也有要求一致:但是,mysql内部做类型转换处理:要求是能够转换成功;
mysql> (Select t_name,days,c_name from teacher_class where c_name='php0115' order by days limit 10) Union all (Select days,t_name,c_name from teacher_class where c_name='php0228' order by days desc limit 10);
+----------+----------+---------+
| t_name | days | c_name |
+----------+----------+---------+
| 韩é | 15 | php0115 |
| æŽç | 20 | php0115 |
| 韩ä | 21 | php0115 |
| 22 | æŽç | php0228 |
| 18 | 韩ä | php0228 |
+----------+----------+---------+
5 rows in set (0.00 sec)
检索结果中的列名称问题:
第一条select语句的列名而定;
相关文章推荐
- MySQL中的integer 数据类型
- MySQL存储过程
- mysql中int、bigint、smallint 和 tinyint的区别与长度
- mysql load data 导出、导入 csv
- source命令执行SQL脚本文件
- MySQL创建用户及权限控制
- MySQL管理数据表
- linux下mysql添加用户
- mysql procedure
- mysql触发器
- MySQL 备份和恢复策略
- mac下安装mysql(转载)
- mysql 修改编码 Linux/Mac/Unix/通用(杜绝修改后无法启动的情况!)
- MySQL数据的导出、导入(mysql内部命令:mysqldump、mysql)
- mysql数据行转列
- Linux下修改MySQL编码的方法
- MySQL Server 日志
- MySQL 安全事宜
- MySQL 备份与恢复