--->清屏 等价于 # clear
如果id是auto_increment,那么insert into数据时,可以为以下两种方法:
# service mysqld restart
4、修改表alter table
(1)增加列 add
mysql> alter table add column age int;
mysql> desc test;
mysql> alter table test add column sex enum('man','woman') not null default 'man' after name;
mysql> alter table test add column sno varchar(10) first;
(2)删除列 drop
mysql> alter table test drop id;
mysql> alter table test drop column age;
(3)修改列 modify/change
mysql> alter table test modify age tinyint not null;
mysql> alter table test change name sname varchar(30) not null;
ModifY 仅仅修改字段的类型。字段名不变。
change 修改列名 类型。
(4)重命名表 rename to/rename...to
mysql> alter table test rename to mytest;
mysql> rename table mytest to test;
5、约束
(1)主键约束(primary key)
(2)唯一约束(unique)
(3)非空约束(not null)
(4)外键约束
mysql> create table sinfo(id int primary key auto_increment,sno varchar(10) not null unique,name varcha
r(20) not null,cno varchar(10),age tinyint unsigned,addr varchar(60),foreign key (cno) references class(cno))auto_increment=1,engine=innodb;
mysql> alter table stu_info add constraint CNO_FK foreign key(cno) references class(cno) on delete rest
rict on update restrict;
on delete cascade:级联更新和删除
on delete set null:更新或删除时将子表的相应记录设置为null
on delete restrict:如果子表有匹配的记录则不允许进行delete/update操作
mysql> alter table sinfo drop foreign key sinfo_ibfk_1; 删除外键。
练习:新建class和student两个表,在class表里面包含班级编号,班级名称,班级人数3个字段,然后插入3条
记录。student表包含生编号,学生姓名,学生所属班级名称和联系电话四个字段,其中班级名称为外键列,
引用class表的班级名称,对于更新或删除使用restrict方式,然后在student插入3条记录,删除class表中的数据 (delete from class where ..)分别观察当班级名称在或不在class表的班级名称中的情况。
外键的条件:必须是唯一的。
答案:
mysql> create table class(cid primary key,cname varchar(20) unique,cnum varchar(60));
mysql> insert into class values('c1','1班','29人');
mysql> insert into class values('c2','2班','39人');
mysql> create table student(sid int(20) primary key,sname varchar(20),phone varchar(20),cname varchar(20)
not null,foreign key(cname) references class(cname));
mysql> insert into student values('1','张三','18229197191','c1');
mysql> insert into student values('2','里斯','15989197191','c2');
mysql> alter table student add constraint fk_cname foreign key(cname) references class(cname) on delete restrict on update restrict;
6、mysql语句类型
(1)DDL语句
create database
drop database
create table
alter table
drop table
create index
drop index
(2)DML语句
insert(插入数据)
mysql> insert into sinfo values(2,'s000002','赵芳','c0002',33,'湖南省长沙市');
mysql> insert into sinfo set id=3,sno='s000003',name='张因',cno='c0003',age=36,addr="湖南省长沙市定王
台"; mysql> insert into sinfo select id,sno,name,cno,age,addr from stu_info;
update(更新数据)
mysql> update sinfo set age=48 where id=4;
delete(删除数据)
mysql> delete from sinfo where id>4;
tuncate(清空表)
mysql> truncate sinfo;
select(数据查询)
where条件表达式:
and 逻辑与 salary > 5000 and salary<10000
or 逻辑或 salary < 5000 or salary>10000
not 逻辑非 not sex="man"
between salary between 5000 and 10000
= 等于
> 大于
< 小于
>= 大于等于
<= 小于等于
!= 不等于
<> 不等于
+,-,*,/ 加、减、乘、除
is null 值为空
like 字符匹配 name like '%apple%'
group by和having 分组和条件设置
limit 指定记录的输出个数
order by 字段名 ASC | DESC
例:
mysql> select * from salaries where salary>=60000 and salary<61000;
mysql> select * from salaries where salary between 30000 and 31000;
mysql> select * from employees where first_name like '%Mary%';
mysql> select * from employees where first_name is null;
mysql> select * from employees where first_name is not null;
mysql> select * from salaries where salary in (50000,60000,70000);
mysql> select * from salaries where salary in (50000,60000,70000) order by emp_no ASC;
mysql> select * from salaries where salary in (50000,60000,70000) order by emp_no desc;
mysql> select emp_no as 员工编号,salary as 薪水,from_date as 入职时间,to_date as 离职时间 from salarie
s where salary in (50000,60000,70000) order by emp_no desc limit 10;
mysql> select gender as 性别,count(gender) as 人数 from employees group by gender;
练习:在employees表中统计从1960年(包括1960)后每一年出生的员工数
mysql> select year(birth_date) as 出生年份,count(year(birth_date)) as 人数 from employees group by 出
生年份 having 出生年份>=1960;
mysql> select year(birth_date) as 出生年份,count(year(birth_date)) as 人数 from employees group by 出
生年份 having not 出生年份>=1960;
例:求员工的平均工资,大于平均工资和小于平均工资的人数
mysql> select avg(salary) as 平均工资 from salaries;
select count(*) as 小于平均工资人数,avg(salary) as 平均工资 from salaries where salary<(select avg(sal
ary) from salaries);
7、多表查询
查询所有学生的编号、姓名、成绩和住址
mysql> select infoa.sno,infoa.name,infoa.score,infob.addr from infoa,infob where infoa.sno=infob.sno;
inner join...on :取所有查询表的交集
left join...on : 取左边表的所有记录和右边表的交集
right join...on :取右边边表的所有记录和左边表的交集
练习:查询所有住在长沙市的学生编号、姓名、成绩和住址
mysql> select infoa.sno,infoa.name,infoa.score,infob.addr from infoa left join infob on infoa.sno=infob.
sno where addr="湖南省长沙市";
mysql> select a.sno,a.name,a.score,b.addr from infoa as a left join infob as b on a.sno=b.sno where addr
="湖南省长沙市";
练习:查询employees数据库中每个部门的员工人数,然后给出部门的编号和人数
(共有4个部门 departments、dept_emp、dept_manager 、salaries )
mysql> select dept_emp.dept_no as 部门编号,count(*) as 部门人数 from dept_emp left join (employees,depar
tments) on (departments.dept_no=dept_emp.dept_no and employees.emp_no=dept_emp.emp_no) group by dept_emp.dept_no;
练习:查询男女员工的人数
mysql> select gender as 性别,count(*) as 人数 from employees group by gender
练习:查询男女员工的平均工资
mysql> select employees.gender,avg(salaries.salary) from employees,salaries where employees.emp_no=salar
ies.emp_no group by gender;
练习:列出各部门的平均工资,按照降序进行排列
mysql> select dept_emp.dept_no as 部门编号,avg(salaries.salary) as 平均工资 from dept_emp inner join sal
aries on dept_emp.emp_no=salaries.emp_no group by dept_no order by 平均工资 desc;
mysql> select a.dept_name,b.dept_no,avg(c.salary) as 平均工资 from departments a,dept_emp b,salaries c w
here a.dept_no=b.dept_no and b.emp_no=c.emp_no group by dept_no order by 平均工资 desc;
mysql> select a.dept_name as 部门名称,b.dept_no as 部门编号,avg(c.salary) as 平均工资 from departments a
,dept_emp b,salaries c where a.dept_no=b.dept_no and b.emp_no=c.emp_no group by b.dept_no order by 平均工资 desc;
mysql> select a.dept_name as 部门名称,b.dept_no as 部门编号,avg(c.salary) as 平均工资,max(c.salary) as
最 高工资,min(c.salary) as 最低工资 from departments a,dept_emp b,salaries c where a.dept_no=b.dept_no and b.emp_no=c.emp_no group by b.dept_no order by 平均工资 desc;
mysql> select departments.dept_no as 部门编号,avg(salary) as 平均工资 from departments,salaries,dept_emp where departments.dept_no=dept_emp.dept_no and dept_emp.emp_no=salaries.emp_no group by departments.dept_no order by avg(salary) desc;
练习:列出每个部门的部门名称名称、部门编号、部门的管理者姓名(包括first_name和last_name)和性别
mysql> select a.dept_no as 部门编号,a.dept_name as 部门名称,concat(c.first_name,' ',c.last_name) as 部门
管 理者,c.gender as 性别 from departments a,dept_manager b,employees c where a.dept_no=b.dept_no and b.emp_no=c.emp_no order by 部门编号;
练习:将员工编号、员工姓名(first_name+last_name)、所属部门、1990年后加入公司的员工及薪水等信息
建立一个新表einfo。
mysql> create table einfo(select employees.emp_no,concat(employees.first_name,' ',employees.last_nam
e) as 员工姓名,employees.hire_date,departments.dept_name,salaries.salary from employees left join (departments,salaries,dept_emp) on employees.emp_no=salaries.emp_no and dept_emp.dept_no=departments.dept_no and employees.emp_no=dept_emp.emp_no where year(employees.hire_date)>=1990);
三、分区表
分区表的优点:
数据分开存放在不同的文件,可以支持更大的数据文件
在某些特定条件下能提高查询、删除、更新的效率
可以把一些归类的数据放在一个分区中,可以减少服务器检查数据的数量加快查询。
方便维护,通过删除分区来删除老的数据。
分区数据可以被分布到不同的物理位置,可以做分布式有效利用多个硬盘驱动器。
注意:
在有分区表的情况下,如果create 的 table 有主键(主键是可以有多个的),那么要进行分区的那个字段必须为主键之一。
1、range分区表 (要求分区的字段类型必须为整数类型)
mysql> create table mytest(id int,name varchar(20) not null,birthday date,primary key(id,birthday))auto_
increment=1 partition by range(year(birthday))( partition p01 values less than (2000), partition p02 values less than (2010), partition p03 values less than maxvalue);
练习:
创建一个新表,包含学生编号,学生姓名,联系电话、所属院系四个字段,其中院系为5个数字值,分别为
1、2、3、4、5代表五个不同的院系,要求将表里面的数据按院系分别保存到5个不同的数据文件,创建完成后
观察数据文件的名称和大小等信息,并插入几条数据
mysql> create table stu_info(id int,name varchar(10),phone varchar(20),xueyuan int) partit
ion by range (xueyuan) (partition p1 values less than (2),partition p2 values less than (3),partition p3 values less than (4),partition p4 values less than (5),partition p5 values less than (6));
2、list分区表(要求分区的字段必须是整数类型)
mysql> create table mytest1(sid int not null,name varchar(20),area varchar(10)) partition by list (sid)
(partition p01 values in (1,2), partition p02 values in (3,4),partition p03 values in (5,6));
练习:创建一个包含员工id、员工姓名、员工住址的表,将员工id的尾数为1、4、7的存放到p01分区,2、5、8的
存放到p02分区,3、6、9存放到p03分区,然后存储id为1-10的10个数据,观察存储情况
id%10 <==> mod(id,10)
partiton p02 ---> p01 p02 这些是自己给分区起的名字。
cat /etc/my.cnf 查看一下数据库文件存放在哪个目录下。datadir=/database/mydata
# cd /database/mydata (此题目,我用的是test数据库 :use test;)
# cd test 即可以 看到这些分区类型。
3、hash分区表
mysql> create table mytest2(sid int not null,name varchar(20),area varchar(10)) partition by hash (sid)
partitions 3;
mysql> create table mytest2(sid int not null,name varchar(20),area varchar(10)) partition by linear hash
(sid) partitions 3;
hash分区表不给分区起名字,那么默认情况下分区名字是什么?cd /database/mydata/test查看。
默认是 表名#P#p0.idb 是从p0开始的。
4、key分区
mysql> create table mytest3(sid int not null,name varchar(20),area varchar(10)) partition by key (area)
partitions 3;
mysql> create table mytest3(sid int not null,name varchar(20),area varchar(10)) partition by linear key
(area) partitions 3;
5、分区管理
新增分区
range分区表:mysql> alter table sinfo add partition (partition gd06 values less than (7));
list分区表:mysql> alter table employee add partition (partition p04 values in (0,1,3));
key分区表:mysql> alter table mytest1 partition by key(area) partitions 4;
hash分区表:mysql> alter table mytest1 partition by hash(area) partitions 4;
删除分区
mysql> alter table sinfo drop partition gd01;
如果删除分区,则table中在分区中的数据也一并被删除 且该数据库文件也被删除(如:mytest#P#p1.ibd)
如果删除table中的数据(delete from mytest where id=1;),其所在分区不会被删除,该数据库文件也不会被删除。
合并分区 (只有相邻分区才可以合并)
mysql> alter table mytest reorganize partition p2,p3 into (partition p13 values less than (2020));
mysql> alter table sinfo reorganize partition p03,p04 into (partition p034 values in (0,3,6,9));
四、从文本文件导入数据
mysql> load data [local] infile '/lianxi/zll/mysql/file1.txt' into table sinfo fields terminated by
' ' enclosed by '"' escaped by '"' lines terminated by '\r';
fields terminated by 字段分隔符,默认为tab
enclosed by '"' escaped by '"' 每个字段的内容是否放在特定的字符里面,如"姓名"
lines terminated by 每条记录行的分隔符,默认为回车"\r"
练习:将access.log.1文件中的ip地址,访问的协议及状态,传输的字节数,请求方式和访问的url及端口导入到
数据库表中,并要求在最前面加入编号,从1开始
1222441666.045 0 192.168.20.171 TCP_DENIED/403 1869 CONNECT urs.microsoft.com:443 - NONE/- text/html
提取的内容为:192.168.20.171 TCP_DENIED/403 1869 CONNECT urs.microsoft.com:443
记录的字段为:
id ipaddr pstats fsize method url
1 192.168.20.171 TCP_DENIED/403 1869 CONNECT urs.microsoft.com:443
[root@ZLL mysql]# cat -n access.log.1 |tr -s ' '|awk -F ' ' '{print$1,$4,$5,$6,$7,$8,$9}' >>access.log.2
mysql> create table accesslog(id int,ipaddr varchar(30),pstats varchar(60),fsize varchar(30),method varchar(30),url varchar(90));
mysql> alter table accesslog modify id int(15) primary key auto_increment;
mysql> load data local infile '/lianxi/zll/mysql/access.log.2' into table accesslog fields terminated by ' ';
练习:将access.log.1文件中的ip地址,访问的协议及状态,传输的字节数,请求方式和访问的url及端口导入到
数据库,并要求在最前面加入编号,从1开始,如果url的长度大于60,则取前55个字符。
五、将数据导出为文本文件
mysql> select * from employees into outfile '/lianxi/zll/mysql/employees.txt';
ERROR 1 (HY000): Can't create/write to file '/lianxi/zll/mysql/employee.txt' (Errcode: 13 - Permission deni
ed)
因为在mysql导出文本文件是以mysql用户来导出(写)文件到/lianxi/zll/mysql目录下的,而/lianxi/zll/mysql目录是root用户权限。所以 以mysql用户权限 到 root用户权限下 写文件 是被denied的。
解决办法:可以先把/lianxi/zll/mysql的root权限改为mysql。 chown mysql:mysql /lianxi/zll/mysql 再导出文件。最后再把改目录权限改回来。