对表的增删改操作:

创建表:

create table student (

         id  int  primary key  auto_increment,

         name  varchar(10)  character set utf8  not null,

         sex    char(2)  default ‘M’,

         constraint  fk_student_score  foreign key(id)  references score(id)

)  engine=InnoDB;

primary key :指定表的主键;

如果是指定单个主键,可直接在该字段后声明;

如果是指定多个主键,只能采用primary key (X,Y)的形式;

定义外键

constraint fk_T2_T1 foreign key(t2_id) references T1(t1_id); //将T1表中的t1_id字段设置成为T2表的外键;

增加外键

alter table T2 orderitemds add constraint fk_T2_T1 foreign key(id) references T1(id); //将T1表中的t1_id字段设置成为T2表的外键;

auto_increment :让Mysql自动对该列增量;每个表只允许有一个auto_increment列,且必须被索引(以最大的数去递增),从而可将该列当作主键;

注:select last_insert_id():该语句可获得最后一个auto_increment的值;

default:为字段设置默认值;

character set …:指定编码格式,通常是为了让其能识别中文;

engine = :指定mysql引擎;

常用的引擎类型:

InnoDB:可靠地事物处理引擎,但不支持全文检索;

MyISAM:性能极高的引擎,支持全文检索,但不支持事务处理;

MEMORY:功能同于MyISAM,但由于数据库在内存里,速度很快;适用于临时表;

注:新版Mysql默认引擎是InnoDB

更新表:使用alter table语句

增加列:

alter table T add Tname varchar(20); //为T表增加一个名为Tname的列

删除列:一次只能删除一列;

alter table T drop column Tname; ///删除T表中名为Tname的列

删除表:使用Drop table语句

例:drop table T;

重命名表:使用rename table语句

例:rename table T1 to t1, T2 to t2, T3 to t3;

对表中数据的查询操作

SQL语句格式:

select

from

where

group by

having

order by

limit

 

去重:distinct

例:select distinct * from T

数据分组: group by , having , rollup

group by  :进行分组; 如果分组中具有null值,则null将作为一个分组返回;

having   :过滤分组; 它支持所有where中的操作符;

注:可以使用rollup关键字来显示出分组前所有的数据;例:group by prod_id with rollup;

除聚集计算语句外,select语句中使用的每个选择列或表达式列,都必须在group by子句中给出;

排序:order by

select * from XXX order byXXX (desc(降序)/asc(升序))

限制检索行数:limit limit offset

例:    select * from XXX limit 0,2 (从第0行开始,取2行)

等价于  select * from xxx limit 1 offset 2(从第2行开始取1行)

起别名:

可以为表或列起别名;

有两种形式:

(1)table1 t1

(2)table1 as t1

where语句中注意的问题:

注:and比or的优先级高

‘<>’ 等价于 ‘!=’f

between A and B:包括边界

is null

in :指定条件范围 取值时用","分隔,相当于or的作用,但比or操作符执行的更快;并且可以包含select语句;

not

like: %:任意字符(null除外)   _:单个字符

注:用通配符过滤:花费时间较长,避免过度使用;可以考虑用正则表达式;

mysql支持部分正则表达式,可以匹配基本的字符和字符串;

形如: select * from products where prod_name regexp ‘XXXX’

例:检索到prod_name包含文本1000的所有行;

select *   from products   where prod_name regexp ‘1000’

mysql的预定义字符集:

[:digit:]---任意的数字(同[0-9])

[:lower:]---任意小写字母(同[a-z])

[:upper:]---任意大写字母(同[A-Z])

[:alpha:]---任意字符(同[a-zA-Z])

[:alnum:]---任意数字和字母(同[a-zA-Z0-9])

[:blank:]---空格和制表符(同[\\t])

[:space:]---任意的空白字符,包括空格;(同[\\f\\n\\r\\t\\v])

例:-- 表示检索出现连在一起的任意4位数字和小写字母的所有行

select prod_name

from products

where prod_name regexp ‘[[:digit:][:lower:]]{4}’

like 和 regexp的区别:

like是匹配这个列,如果被匹配的文本仅在列值中出现,like并不会找到它,相应的行将不会返回(使用通配符除外)。

regexp是匹配列值,如果被匹配的文本在列值中出现,regexp会找到它,相应的行将会返回(可以用定位符号^和$,让regexp匹配这个列,而非列值)。

当一些操作,不需要从表上选择数据时,mysql中提供了一个内置的特殊的表dual(空表),来方便操作;

mysql中提供的一些常用函数:

聚集函数(汇总函数):

max(),   min(),   sum(),  avg(),  count();

注:它们都忽略列值为null的行;

它们都可以和distinct关键字联合使用;例如:count(distinct prod_price)

文本处理函数:

concat( , ) :用来拼接字段

例:

select concat(vend_name, vend_country)

from vendors

trim( , ):去掉字段中值中的所有空格

rtrim( , ):去掉字段中值右边的所有空格

ltrim( , ):去掉字段中值左边的所有空格

soundex( ):能对串进行发音比较;可将任何文本串转化为描述其语音表示的字母数字;

例如:soundex(cust_contact) = soundex(‘Y.Lie’) //可找到表中cust_contact=Y Lee的这条记录;

日期和时间处理函数:

Now() :返回当前日期和时间

CurData():返回当前日期

Curtime():返回当前时间

Year(D):返回回一个日期D中的年份部分 类似有:Month(D)……

DateOfWeek(D):返回对于一个日期D,返回对应的星期几

DateDiff(D1,D2):计算D1到D2两个日期之差

Date_Format(D,F):按照表示式F的要求显示日期D;

AddDate(D,n):计算起始日期D加上n天的日期;

SubDate(D,n): 计算起始日期D减去n天的日期;

子查询:嵌套在其他查询中的查询

使用子查询的两种方式:

1.一般与in操作符结合使用,但也可以用于测试等不等于;

2.用子查询去创建计算字段;将子查询整体作为一个计算字段使用;

注:一切的问题都可以采用子查询写出;

连接:两个表之间字段取交集

等值连接:where …=…

例: from T1,T2   where T1.p_id=T2.p_id;

内部连接:inner join…on…

例:from T1 inner join T2 on T1.p_id =T2.p_id;

注:推荐用inner join on子句,它的性能好于where.

外连接:left outer join … on… 、right outer join …on…

左外连接:得到的内容为 两者的公共交集+ 左边的表中非关联部分

右外连接:得到的内容为 两者的公共交集+ 右边的表中非关联部分

例:from T1 left outer join T2 on T1.p_id =T2.p_id;

自连接:速度很好,推荐使用

可以通过子查询来实现,

select

from t

where  t_id = {  }

也可以通过不同的别名来实现;

select

from  t as t1, t as t2

where  t1_id = t2_id

 

组合查询:多个查询并将结果作为一个查询结果集返回,使用union操作字

需要使用组合查询的情况:

  1. 在单个查询中从不同的表返回类似结构的数据;
  2. 对单个表执行多个查询,按单个查询返回数据;

在各select语句之间放上关键字union,每个查询必须包含相同的列、表达式或聚集函数。

它会从查询结果中自动去除重复的行,如果需要不取消行,可使用union all;

注:使用uinon可以替代where,能够用较简单的方式去完成由where非常复杂才得到的结果;

范式:

第一范式(1NF):确保每列保持原子性

第二范式(2NF):符合1NF,并且,确保表中的每列都和主键相关

第三范式(3NF):符合2NF,并且,确保每列都和主键列直接相关,而不是间接相关;

BC范式(BCNF):符合3NF,并且,主属性不依赖于主属性

第四范式:要求把同一表内的多对多关系删除。

第五范式:从最终结构重新建立原始结构。

对表中数据的增删改操作:

注:T代表某个表

向表中增加行:有四种形式;

第一种形式:插入完整行,必须按默认顺序为每个列提供一个值;

insert into T

values(……)

注:若该列没有值则用null表示;

第二种形式:插入部分行,可按自己指定的顺序为每个列赋值;

insert into T(……)

values(……)

第三种形式:插入多行;

insert into T(……)

values(……) ;

insert into T(……)

values(……) ;

(Mysql特有的)

insert into T(……)

values(……) ,(……);

第四种形式:插入部分某些查询结果;

insert into T(……)

select ……

修改表中的数据:

update T set ……

例:

//修改编号为1002顾客的顾客名和顾客电话

update customers set cust_name=’Tom’, cust_tele=”10086” where cust_id=1002;

//删除编号为1001顾客的邮件地址

updata customers set cust_email=null where cust_id=1001;

从表中删除行:

delete from T where……

注:也可以用truncate table语句删除表中所有数据,它的速度更快,相当于删除原表,在建一个空表;

视图:即:虚拟的表,它只是一个SQL查询,不包含任何数据;

查看创建视图的语句show create view <视图名称>

创建视图:

create view <视图名称>

as

select查询语句

删除视图drop view <视图名称>

注: 通常视图都是和select语句使用的,

虽然视图是可更新的,即可以对视图使用insert,update,delete;但其实更新一个视图,实际上是更新其基表,是对基表的增删改,所以并不推荐这样使用;

优点:可重用SQL语句;

化简了复杂的SQL操作

使用的部分表,而不是整个表;

能保护数据;

可更改数据格式和表示;

缺点:视图会影响性能,因此使用大量视图时要慎重;

Mysql高级语言

有三种形式的注释

行注释:   #XXX     -- XXX(之间至少有一个空格符)

块注释:   /* XXX */

 

变量局部变量用@开头;全局变量用@@开头;

 

声明变量: 用declare语句 , 变量不能加@符号;使用游标是只能用declare定义

daclare var_name[,……]  type  (default value)

注:declare语句必须用在begin……end语句块中且必须在最前面;变量名不区分大小写; mysql中是一般可以不用事先申明变量,可直接用setselect赋值,

 

变量赋值:;使用变量时用“@var_name”表示即可; 打印时只能用以下的方式;

set语句直接赋值:可以用”=”或”:=”赋值

set  @var_name=value[,…] 或set  @var_name:=value[,…]

select语句查询赋值:只能用”=”赋值,因为在select语句中=被看作比较运算符;

①select  @var_name:=value[,…]

②select  @var_name[,…]

from……

where……

③select  @col_name[,…] into var_name[,…]   #把选定的列赋值给变量

from ……where……

注:直接用set/select语句定义的变量必须加@符号,除非该变量已经被declare声明过;

例://通过连续赋值,加起来赋为t1,并把每个值都打印出来;

select @t1:=(@t2=1)+@t3:=4,@t1,@t2,@t3; from…where…

 

变量的分类:

mysql手册将变量分系统变量和用户变量

但实际中常有以下几种:

局部变量(作用域是当前语句块,即:begin……end):必须用declare声明

用户变量(作用域是当前整个连接):无需使用declare申明,可用select或set会话变量:(作用域是当前整个连接):

定义:

set @var_name=value;

set session @var_name=value;

set @@session var_name=value;

查看:

select @@var_name;

select @@session.var_name;

show session variables like “%var%”

全局变量(作用域是整个数据库):

set global @@var_name=value;

查看:

select @@global.var_name;

show global variables like “%var%”

 

存储过程中的控制语句

if(expr1, expr2, expr3):相当于java中的三目运算符,

expr1是true,则返回expr2,否则返回expr3;

ifnull(expr1, expr2):

若expr1非null,返回本身;否则返回expr2;

nullif(expr1,expr2):

若两者相等,返回null,否则返回expr1;

分支语句之if

if  condition  then  result

[else  result]

end if;

分支语句2之case

形式一:

case value

when compare-value  then  result

[when compare-value  then  result

……]

[else result]

end case;

形式二:====java中的if else语句

case

when condition  then  result

[when condition  then  result

……]

[else result]

end case;

注:在流程控制中end后不用写case;

         condition是一个表达式;

 

循环语句之while循环:执行前检查是否满足循环条件

while condition do

         ……

end while;

循环语句之repeat循环:执行前检查是否不满足循环条件

repeat

         ……

         until condition (没有‘;’)

end repeat;

循环语句之loop循环:

lable_1:loop

         ……

leave lable_1;

end loop;

注:

leave语句:只能循环语句中使用,意思离开语句标号为lable_1的语句,相当于“跳出整个循环”(类似java中的break);当满足了特定条件时,通过“leave 循环标号”语句跳出整个循环;

iterater语句:只能循环语句中使用,意思直接跳转到语句标号为lable_1的语句,相当于“跳过本次循环” (类似java中的continue);

当满足了特定条件时,通过“iterater 循环标号”语句跳过本次循环;

语句标号:lables可以用到while, repeat ,loop等循环控制语句中;

存储过程和函数:统称为PL/SQL子程序,它们是被命名的PL/SQL块,均存储在数据库中,以便共享;

唯一区别:函数向调用者返回数据,而过程不返回数据;函数可以在SQL语句内部被调用,而过程则不能被调用;

存储过程和函数的优点简单,安全,高性能

 

创建存储过程:

注:为了安全可以先执行这句:drop procedure if exists  <过程名称>;

delimiter //(有空格符)

create procedure <过程名称> (

         参数声明

)

begin

         过程体

end //

delimiter ;(有空格符)

注:

①delimiter意思是定义符号, 目的是用delimiter关键字申明当前段的自定义分隔符,将其之间的内容当作存储过程,使mysql编译器不会执行这些的代码;记得用完后要把分隔符还原;

②存储过程定义时有三种参数类型: in,  out,  inout

in 输入参数:在调用时指定,执行中不能被修改并返回;

out 输出参数:执行中能被修改并返回;

inout 输入输出参数:在调用时指定,执行中能被修改并返回;

调用存储过程:

call proc_name (…);

修改存储过程:

alter procedure proc_name ……;

删除存储过程:

drop procedure proc_name ;

查看存储过程:可以获取何时,有谁创建的信息

查看所有存储过程的信息:

show procedure status;

查看指定的存储过程:

show create procedure proc_name;

函数:大体类似于存储过程,只是将关键字procedure变为function

但注意创建函数时不能使用in,out,inout关键字,因为它默认其所有的参数都是in的;

注:为了安全可以先执行这句:drop function if exists  <函数名称>;

delimiter //(有空格符)

create function <函数名称> (

         参数声明 (参数不能是带@的)

)

returns 参数

begin

         过程体

         return 参数;

end //

delimiter ;(有空格符)

 

函数不能用call调用外,但它能在SQL语句内部被调用

例如:select func_name(…) from … where…

使用存储过程和函数的选择:

1.返回多个值或不返回值,用存储过程;返回一个值,用函数;

2.存储过程一般用于执行一个指定的动作;

函数一般用于计算和返回一个值;

3.要在SQL语句内部被使用,只能用函数;

游标cursor:只能用与存储过程或函数;

能在检索出来的行中前进或后退一行或多行;

它不是select语句,而是被该语句检索出来的结果;

创建游标:定义时并未检索数据  只能用declare定义变量;

decalar cur_name cursor for 定义使用的select语句;

打开游标:打开时才按定义检索数据

open cur_name;

使用游标: 通常在while,repeat,loop循环中使用; 游标也可以嵌套;

关闭游标

close cur_name;

注意:使用后必须关闭游标;存储过程或函数中定义的局部变量必须放在游标之前,而定义的句柄必须放在游标之后;

例:创建一个存储过程,使用游标输出orders表中所有的order_num;

但是这样会有多个结果窗口;

delimiter //

create procedure p_1()

begin

 

declare o int;  #局部变量最先定义

declare done boolean default 0;

declare ordernumbers cursor for #游标在其后定义

select order_num from orders;

declare continue handler for  #处理器在最后定义

sqlstate '02000' set done = 1;

open ordernumbers;

fetch ordernumbers into o;

repeat

select o;

#最好将fetch语句放在循环的最后,当其发生异常时能够立即终止循环;

fetch ordernumbers into o;

until done

end repeat;

close ordernumbers;

end //

delimiter ;

注:

fetch cursor  into var_name:获取游标当前指向的数据行并将指针指向下一行,然后赋给一个变量;(只能取一行数据)

declare continue handler forsqlstate '02000' set done = 1;

它表示fetch的执行过程中发生满足sql状态码所代表的异常时,会被自动执行的代码;

触发器trigger: 让某些语句在事件发生前或后自动执行;

创建触发器:

delimiter $

create trigger <触发器名称>

[before|after] [insert|update|delete]  on <表名称>

for ench row

begin

<触发器SQL语句>

end $

delimiter ;

支持的事件类型:insert, update, delete;

例:在增加tab1表记录后,自动将记录中的tab1_id列中的数据增加到tab2表中;

delimiter $

create trigger t_1

after insert on tab1

/* 一次只能定义一种事件类型;

before update on tab1

after delete on tab1

*/

for each row

 

begin

#在增加tab1表中记录后,自动将在指定的新增数据添加到tab2表中;

insert into tab2(tab2_id) values (new.tab1_id);

/*

#在tab1表中修改tab1_name列中数据时,会自动将数据变为大写;

set tab1_name = Upper(new.tab1_name);

#在删除tab1表中记录后,自动将指定的删除数据添加到tab2表中;

insert into tab2(tab2_id) values (old.tab1_id);

*/

end $

delimiter ;
注:

在insert触发器中是不能使用old关键字的,只能用new;

在delete触发器中是不能使用new关键字的,只能用old;

在updeta触发器中,before时用new, after时用old;

因为new中的值可被更新修改;而old中的值都是只读的,不能更新修改;

事务处理:它是一种用来维护数据库完整性的机制,可以保证一组操作的原子性,即:要不整体执行,要不执行;如果成功,则写入数据库;如果发生错误,则可以进行回退到以前的某种状态;一般用于增删改操作;

(内部实现的就是让操作在内存中执行,然后一次性将结果写入硬盘)

涉及的关键字:

transaction:事务

rollback:回退

commit:提交到硬盘

savepoint:保留点,它是事务处理中设置的临时占位符,可以对它发布回退,使其恢复到之前的状态;

例:

start transaction; #开始事务处理

delete from tab1 where id= 0;

savepoint point1; #设置保留点

delete from tab1 where id= 1;

delete from tab1 where id= 2;

rollback to point1; #回退到保留点point1之前的状态;

rollback; #回退到开始事务处理之前的状态

commit; #将结果提交到硬盘

注:如果不用事务处理,Mysql默认是自动提交的,但可以用set autocommit=0 语句,取消自动提交;这样就可以使用回退操作;

 

安全管理:

创建MySql用户账号:

create user 用户名
indentified by ‘密码’;

更改用户名:

rename user … to…;

删掉用户名:

drop user 用户名;

设置访问权限:

show grants for

设置口令:

set password for …… =password(‘ 口令’); //设置自己的口令

set password for …… =password(‘ 口令’);

数据库维护:

备份数据库:使用mysqldump命令

备份多个数据库:

mysqldump –u username –p –all –database
dbname1 dbname2 > Backup.sql

备份所有数据库:

mysqldump –u username –p –all --database
> Backup.sql

注:

-n:不创建数据库

-d:不导出任何数据,只导出数据库的表结构

-t:只导出数据

-r:导出存储过程以及自定义函数

还原数据:

mysql –u root –p dbname < backup.sql

数据库易混点:

数据库中用“=”表示是否相等而不是“==”;

null和任何值操作的结果都是null;

05-27 20:12