Mysql入门

注释

–这是一行注释
#这是一行注释
/*
多行注释
*/

登陆

cmd输入:
mysql -uroot

创建数据库

create database zk; –zk为数据库名字
use zk; //进入该数据库

创建表

CREATE TABLE Customers
(
cust_id char(10) NOT NULL primary key, –主键
cust_name char(50) NOT NULL references 表名(cust_name), –外键
cust_address char(50) NULL , –默认是NULL,不输入也可以
cust_city char(50) NULL ,
cust_state char(5) NULL ,
cust_zip char(10) NULL ,
cust_country char(50) NULL ,
cust_contact char(50) NULL ,
cust_email char(255) unique, –唯一性约束,每一行都不一样
cust_price decimal(8,2) NOT NULL default 1.0; –有初始值
);

约束

非空约束(not null)
唯一性约束(unique)
主键约束(primary key) PK
外键约束(foreign key) FK
检查约束(目前MySQL不支持、Oracle支持)

查看表的结构

describe Customers;4

更新表的结构

更新表的结构比较复杂,规则不统一,最好在设计表的时候,设计好
alter table

新增一列

alter table venders
add vender_phone char(20);

删除一列

alter table venders
drop column vender_phone;

删除表

drop table venders;

重命名表/列

ALTER TABLE test RENAME TO test1;
alter table test change t_name t_name_new varchar(20);

设置主键和外键

ALTER TABLE Customers ADD PRIMARY KEY (cust_id);
ALTER TABLE OrderItems ADD CONSTRAINT FK_OrderItems_Orders 
FOREIGN KEY (order_num) REFERENCES Orders (order_num);          
--REFERENCES表示OrderItems中的order_num都来自Orders (order_num),FK_OrderItems_Orders外键id

插入数据

INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES(‘1000000001’, ‘Village Toys’, ‘200 Maple Lane’, ‘Detroit’, ‘MI’, ‘44444’, ‘USA’, ‘John Smith’, ‘sales@villagetoys.com’);

查询列

select 列名1,列名2 from 表名;
select * from 表明;//查询所有列

检索不同的值

select distinct 列名 from 表名;

检索前5行

Mysql:
select 列名 from 表名 limit 5; –其他软件不一样
select 列名 from 表名 limit 5 offsset 5; –从第5行开始的前5行数据

排序检索

select 列名 from 表名 order by 列名1; –按列名1排序,确保order by子句在select语句中的最后
select 列名 from 表名 order by 列名1,列名2; –先按列名1排序。只有列名1一样时,才按列名2排序
select 列名1,列名2,列名3 from 表名 order by 2,3; –按相对位置排序,即先按列名2排序。只有列名2一样时,才按列名3排序

倒序

select 列名 from 表名 order by 列名1 desc; –按列名1**倒序**排序
select 列名 from 表名 order by 列名1 desc,列名2; –按列名1**倒序**排序
select 列名 from 表名 order by 列名1 desc,列名2 desc; –按列名1,列名2**倒序**排序

where 数据过滤

select 列名 from 表名 where 列名1<10;–筛选列名1小于10
<> –不等于
!= –不等于,access不支持
!< –不小于
between a and b –在两只之间
is null –是null
如果和数值型比较,不用加”
如果和字符串比较,加”,如:
select 列名 from 表名 where id <> ‘167’;

操作符,也叫逻辑操作符(类似&&),连接多个where子句

and 且,优先级 高于or
or 或者
not 非
in 在。。里
() 要多用
where A or B and C; –满足A或者(B且C)
where (A or B) and C; –满足(A或者B)且C
where id in (A,B); –相当于where id==A or id==B
where not id==A; –相当于where id!=A;

通配符

like去匹配类似的字符串


 %                          任意字符任意次
 [JM]                       该位置字符是J或者M的字符串
 [^JM]                      该位置字符不是J且不含M的字符串    
 -                          某个字符出现一次
select 列名 from 表名
where 列名1 like '[^JM%]';            --匹配开头字母不是J且不是M的字符串

计算字段

字段、列、属性类似

拼接字段

大部分可以用+
也有用 || | | concat() c o n c a t ( ) 函数的

select NAME+'('+ID+')' from...
select NAME ||'(' || ID || ')' from...
select concat( NAME, '(', ID, ')' )  from...

别名 AS

计算得到的新的字段,默认没有字段名字,得取名字

select concat( NAME, '(', ID, ')' )  as 别名 from...

算术计算(加减乘除)

select price * number as 总价 from ...

不加from,select还可以简单的处理表达式,如:

select trim(' abc ');               --输出abc,trim()函数是去掉字符串首尾的空格
select 2*3;             --输出6

使用函数处理数据

优点:简单、性能高
缺点:不可移植(不同的DBMS函数一般都不同)
常用函数:

RTRIM()             --去字符串的首尾空格
LEFT()                  --左侧字符
LOWER()         --小写
UPPER()             --大写
SOUNDEX()       --将字符串转为声音的值
DATEPART(yy, 列名)     --输出时间的年分的前两个字符

汇总数据

AVG()                   --返回平均值
MAX()                   --返回最大值
MIN()                   --返回最小值
COUNT(列名)               --返回列名不为NULL的行数
COUNT(*)                --返回所有行的行数
SUM()                   --求和
DISTINCT                --返回不同的值

分组数据

分组

group by        --分组计算,对每一个组计算一次

筛选

having和where的区别:
having是筛选组数据
where是筛选行数据
例子:

select 列名, count(*) from 表名
group by 列名
having count(*) > 3;

排序

order by

select 列名, count(*) from 表名
group by 列名
having count(*) > 3
order by 列名;

子句顺序

select
from
where
group by
having
order by

例子:

select 列名, count(*)
from 表名
where 列名1>4
group by 列名2
having ...
order by 列名3;

子查询

其实就是嵌套查询,例如

select ... from ...
where id in
(select ... from ... where...)   

作为子查询的select只能查询单列,不然会出错
子查询的缺点很明显:
1.很难看,逻辑不清晰
2.不利于调试

等值联结(内联结)

我们习惯把一类数据放在一个表里,但是会有重复的数据,重复数据多绝对不是一件好事(修改不方便)。所以我们把相关表关联,同相同的数据。

select1.列名1,列名2,列名3           --列名2,列3在两个表里只有一个,可以不加表名
from1,表2
where1.列名1 = 表2.列名1;          --此处的列名一定要完全限定列名,**必须确定到哪一张表**,因为有多张表

上述代码,如果去掉where语句。那么输出的是两个表的笛卡儿积。输出的行数是表1行数*表2行数,这种联结也叫做叉联结
另一种等值联结代码:(使用join on语句)

select 列名1,列名2,列名3
from1 inner join2
on1.列名1 = 表2.列名1;

多表等值联结

select 列名1,列名2,列名3
from1,表2,表3
where1.列名1 = 表2.列名1
and1.列名1 = 表3.列名1;

高级联结

自联结

就是自己和自己联结,但是得给这张表取两个名字(理解为复用)

select c1.* 
from customers as c1 inner join customers as c2 
on c2.cust_contact='Jim Jones' and c1.cust_name=c2.cust_name;

自然联结

自然联结就是使每个列只返回一次,每个内联结都是自然联结

外联结

和内联结对比:
1.内联结只返回表1和表2都有且满足条件的数据
2.外联结不仅返回内联结的数据还会返回在条件中,(左/右)表有的但是另一个表没有的数据

mysql> select customers.cust_id,orders.order_num 
from customers left outer join orders 
on customers.cust_id=orders.cust_id;

+------------+-----------+
| cust_id    | order_num |
+------------+-----------+
| 1000000001 |     20005 |
| 1000000001 |     20009 |
| 1000000002 |      NULL |
| 1000000003 |     20006 |
| 1000000004 |     20007 |
| 1000000005 |     20008 |
+------------+-----------+
--最后的结果中1000000002在左表中有cust_id,右表中没有关联,所有没有order_num
left outer join on          --包含左表有,右表没有关联的数据
right outer join on         --包含右表有,左表没有关联的数据
full outer join on          --包含左/右表有,右/左表没有关联的数据

联结和聚集函数结合使用

mysql> select customers.cust_id,count(orders.order_num) 
from customers inner join orders 
on customers.cust_id=orders.cust_id 
group by customers.cust_id;
+------------+-------------------------+
| cust_id    | count(orders.order_num) |
+------------+-------------------------+
| 1000000001 |                       2 |
| 1000000003 |                       1 |
| 1000000004 |                       1 |
| 1000000005 |                       1 |
+------------+-------------------------+

union(组合查询)

将select检索出来的数据合并,默认去重复
union all取消去重复

select...
union
select...
union
select...
order by ...                    --order只能放在最后一个select的最后部分

插入数据

方便的不安全的插入方法

insert into customers
values('1000000006',
        ...,
        'USA');

这种插入方法不安全,仅仅按给的顺序去一列一列插入。
此外,如果列的顺序一旦改变,那么很容易出错

安全的插入方式

insert into customers(cust_id,
                       ...,
                      cust_country)
values('1000000006',
        ...,
        'USA');

有的列可以省略,前提是:该列可以为空,或者该列有默认值

使用检索出来的数据插入

insert into customers(cust_id,
                       ...,
                      cust_country)
select cust_id,
        ...,
    cust_country
from custnew;

这种方法可以多行插入,检索出来几行就插入几行
但是,这种方法其实也是按照查询出来的列的顺序进行插入的,可能会出错

将已存在的表的数据复制到新的列表

create table custnew as
select * from customers;                --这里支持select的所有操作

更新和删除

更新

**1.一定要带上where,不然更新所有的行
2.可能需要一定的安全权限**

update customers
set cust_email='123@hotmail.com',
    cust_country='china'
where cust_id='1000000001';

删除

加上where,删除某一行或某几行,否则删除所有行

delete from customers
where cust_id='1000000001';

注意

在有外键的表中,插入或者删除可能会报错,比如
1.插入一个没有供应商(外键)的产品
2.删除一个在其他表里还有订单的产品

视图

1.视图类似于检索数据再创建一张表
2.但是,与表不同的是,视图不包含任何的数据,只包含查询,每次需要视图中的数据时,需要重新查询一次,性能较低
3.用法和表相同

create view viewname as
select ...

存储过程

类似与自己写函数

创建

mysql> delimiter $$  #将语句的结束符号从分号;临时改为两个$$(可以是自定义)
mysql> CREATE PROCEDURE delete_matches(IN p_playerno INTEGER)
    -> BEGIN
    ->   DELETE FROM MATCHES
    ->    WHERE playerno = p_playerno;
    -> END$$
Query OK, 0 rows affected (0.01 sec)

mysql> delimiter ;  #将语句的结束符号恢复为分号

调用

call delete_matches(57);

事务处理

事务具有原子性:要么全完成,要么全部不完成
1.事务:一组SQL指令
2.回退:回退到上一个状态,和撤销指令(只能撤销insert、update、delete)
3.提交:将为存储的结果存储
4.保留点:备份一个状态,用于回退

隐式提交

一般的SQL语句,都是直接执行并提交。这就是所谓的隐式提交;
而,事务是没有这种隐式提交。所以,事务处理需要,隐式提交。
使用commit语句

开始事务

start transaction
...
start transaction
...
commit transaction      --提交事务

回退

delete from orders;
rollback;               --撤销指令

保留点

保留点越多越好,方便回退

savepoint point1;               --创建还原点
rollback transaction point1;                --回退到point1还原点

例子

start transaction
insert into customers (cust_id,cust_name)
values('1000000006','TT');
savepoint point1;
insert into customers (cust_id,cust_name)
values('1000000007','TTk');
if @@error <> 0
rollback transaction point1;
commit transtion

使用游标

创建一个表,再 insert 些数据 ;代码,初始化

create table test.level (name varchar(20));
...

判断是否有useCursor存储过程

drop procedure if exists useCursor;

创建存储过程

CREATE PROCEDURE useCursor()
BEGIN

局部变量的定义 declare

declare tmpName varchar(20) default '' ;  
declare allName varchar(255) default '' ;           --游标用到的变量,必须放cursor之前不然报错
declare cur1 CURSOR 
FOR 
SELECT name FROM test.level ;  

MySQL 游标 异常后 捕捉;
并设置 循环使用 变量 tmpname 为 null 跳出循环。

declare CONTINUE HANDLER FOR SQLSTATE '02000' SET tmpname = null; 

开游标

OPEN cur1;

抓游标的数据赋值给变量,游标向下走一步

FETCH cur1 INTO tmpName;

循环体 这很明显 把MySQL 游标查询出的 name 都加起并用 ; 号隔开

WHILE ( tmpname is not null) DO 
set tmpName = CONCAT(tmpName ,";") ; 
set allName = CONCAT(allName ,tmpName) ; 
FETCH cur1 INTO tmpName;
END WHILE;

关闭游标

CLOSE cur1;

选择数据

select allName ;

结束存储过程

END;
调用存储过程:

call useCursor();

例子

drop procedure if exists zk;
delimiter $$
create procedure zk()
begin
declare temp text default '';
 declare tmpName text default '' ;
declare allName text default '' ;
 declare cur cursor for
 select cust_id from customers where cust_id in ('1000000001','1000000002');
declare CONTINUE HANDLER FOR SQLSTATE '02000' SET temp = null;
 open cur;
 fetch cur into temp;
while(temp is not null) do
set temp = concat(temp,';');
set allname = concat(allname,temp);
fetch cur into temp;
end while;
 close cur;
 select allname;
 end;$$
delimiter ;
call zk();
+------------------------+
| allname                |
+------------------------+
| 1000000001;1000000002; |
+------------------------+

索引

创建索引

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
 [USING index_type]
 ON table_name (index_col_name,...)

删除索引

ALTER TABLE table_name
DROP INDEX index_name;

查看索引

--如果查看索引前,没有使用user db_name等命令指定具体的数据库,则必须加上FROM db_name
SHOW INDEX FROM table_name [FROM db_name]
--如果查看索引前,没有使用user db_name等命令指定具体的数据库,则必须加上db_name.前缀
SHOW INDEX FROM [db_name.]table_name

触发器

参考https://www.cnblogs.com/lyhabc/p/3802704.html

CREATE TRIGGER trigger_name trigger_time trigger_event
    ON tbl_name FOR EACH ROW trigger_stmt
  • 触发程序是与表有关的命名数据库对象,当表上出现特定事件时,将激活该对象。

  • 触发程序与命名为tbl_name的表相关。tbl_name必须引用永久性表。不能将触发程序与临时表表或视图关联起来。

  • trigger_time是触发程序的动作时间。它可以是BEFORE或AFTER,以指明触发程序是在激活它的语句之前或之后触发。

  • trigger_event指明了激活触发程序的语句的类型。trigger_event可以是下述值之一:

· INSERT:将新行插入表时激活触发程序,例如,通过INSERT、LOAD DATA和REPLACE语句。

· UPDATE:更改某一行时激活触发程序,例如,通过UPDATE语句。

· DELETE:从表中删除某一行时激活触发程序,例如,通过DELETE和REPLACE语句。

请注意,trigger_event与以表操作方式激活触发程序的SQL语句并不很类似,这点很重要。
例如:

CREATE TABLE account(acct_num INT ,amount DECIMAL(10,2));
CREATE TRIGGER ins_sum BEFORE INSERT ON account
FOR EACH ROW SET @SUM=@SUM+new.amount;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值