mysql对大小写不是很敏感,要区分大小写的话,要自己去设置
workbench中建立数据表时的几个选项意思:
1.添加数据库: CREATE DATABASE test_db;
2.查看数据库: SHOW DATABASES; 注意最后有S
3.查看数据库的定义:SHOW CREATE DATABASE test_db \G;
4.删除数据库:DROP DATABASE test_db;
5.查看系统存储引擎:SHOW ENGINES \G;
6.存储引擎选择:如果要提供提交、回滚和崩溃恢复能力的事物安全能力,并要求实现并发控制,InnoDB是个很好的选择。如果数据表主要用来插入和查询记录,则MyISAM引擎能提供较高的处理效率,如果只是临时存放数据,数据量不大,并且不需要较高的数据安全性,可以选择将数据保存在内存中的Memory引擎,MySQL中使用该引擎作为临时表,存放查询的中间结果。如果只有INSERT和SELECT操作,可以选择Archive引擎,Archive存储引擎支持高并发的输入操作,但是本身并不是事物安全的,其非常适合存储归档数据,如记录日志信息可以使用Archive引擎。
7.cmd登录mysql:mysql -h localhost -u root -p
8.选择当前的数据库为test_db: USE test_db;
9.查看默认存储引擎:SHOW VARIABLES LIKE ‘storage_engine’
10.修改默认存储引擎:首先打开my.ini文件,将[mysqld]字段下面的default-storage-engine参数后面的值,由InnoDB改为MyISAM,保存重启MySQL
11.创建tb_emp1表: 注意建表的时候是()而不是{}
CREATE TABLE tb_emp1 ( id INT(11), name VARCHAR(25), deptId INT(11), salary FLOAT );
这里面的int(M) M指示最大显示宽度。显示宽度与数据类型的取值范围无关,数值的位数小于指定的宽度时会由空格填充,如果插入了大于显示宽度的值,只要该值不超过该类型整数的取值范围,数值依然可以插入,而且能够显示出来。
varchar(M)是长度可变的字符串,eg:varchar(50)定义了一个最大长度为50的字符串,如果插入的字符串只有10个字符,则实际存储的字符串为10个字符和一个字符串结束字符。
12.查看表: SHOW TABLES;
13.使用主键约束:
13.1单字段逐渐
有两种定义情况:
CREATE TABLE tb_emp2 ( id INT(11)PRIMARY KEY, name VARCHAR(25), deptId INT(11), salary FLOAT );
或者:
CREATE TABLE tb_emp4 ( id INT(11), name VARCHAR(25), deptId INT(11), salary FLOAT , PRIMARY KEY(id) );
13.2多字段联合主键:
CREATE TABLE tb_emp5 ( name VARCHAR(25), deptId INT(11), salary FLOAT , PRIMARY KEY(name,deptId) );
14.使用外键约束
CREATE TABLE tb_dept1 ( id INT(11)PRIMARY KEY, name VARCHAR(22) NOT NULL, location VARCHAR(50) ); CREATE TABLE tb_emp5 ( id int(11) PRIMARY KEY, name varchar(25), deptId int(11), salary float, CONSTRAINT fk_emp_dept1 FOREIGN KEY(deptId) REFERENCES tb_dept1(id) );
以上语句执行成功以后,在tb_emp5上添加了一个名称为fk_emp_dept1的外键约束,外键名称为deptId,其一代与表tb_dept1的主键id
上面的NOT NULL是非空约束,表示字段的值不能为空,对于使用了非空约束的字段,如果用户在添加数据时没有指定值,数据库系统会报错。
15.唯一性约束
唯一性约束要求该列唯一,允许为空,但只能出现一个空值。唯一性约束可以确保一列或者几列不出现重复值。
其语法规则如下:
15.1 在定义完列之后直接指定唯一约束
name varchar(22)UNIQUE;
15.2 在定义完所有列之后指定唯一约束
CONSTRANT STH UNIQUE (name)
其中STH为约束名
16.设置默认约束
deptId INT(11)DEFAULT 1111
17.设置表的属性值自动增加
id INT(11)PRIMARY KEY AUTO_INCREMENT
AUTO_INCREMENT关键字初始值为1,没增加一条记录,字段值自动加一,一个表只能有一个字段使用AUTO_INCREMENT,且该字段必须是主键的一部分。
CREATE TABLE tb_emp8 ( id INT(11)PRIMARY KEY AUTO_INCREMENT, name VARCHAR(25)NOT NULL, deptId INT(11), salary float, CONSTRAINT fk_emp_dept5 FOREIGN KEY(deptId)REFERENCES tb_dept1(id) ); mysql> insert into tb_emp8(name,salary) -> VALUES('Lucy',1000),('Lura',1200),('Kevin',1500);
结果:
mysql> SELECT *FROM tb_emp8; +----+-------+--------+--------+ | id | name | deptId | salary | +----+-------+--------+--------+ | 1 | Lucy | NULL | 1000 | | 2 | Lura | NULL | 1200 | | 3 | Kevin | NULL | 1500 | +----+-------+--------+--------+ 3 rows in set (0.00 sec)
可以看到我们并没有设置id值,但是插入后id值自动增加了
18.查看表结构 DESCRIBE和SHOW CREATE TABLE语句
18.1 DESCRIBE
describe 表名;可以简化成desc 表名;
18.2 SHOW CREATE TABLE 表名 \G;
不加\G的话,结果显示会比较混乱
19.修改数据表
19.1 修改表名 alter table tb_empt3 rename deptment3;
19.2 修改字段数据类型 alter table 表名 modify 字段名 数据类型;
alter table tb_dept1 modify name varchar(30)
19.3修改字段名 alter table 表名 change 旧的字段名 新的字段名 新数据类型;
19.4添加字段 alter table 表名 add 新的字段名 数据类型 [约束条件] [first|after 已存在的字段名];
[]表示可选。
mysql> alter table tb_dept1 add column3 int(11) after name; mysql> desc tb_dept1; +----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(30) | YES | | NULL | | | column3 | int(11) | YES | | NULL | | | location | varchar(50) | YES | | NULL | | +----------+-------------+------+-----+---------+-------+ 4 rows in set (0.00 sec)
19.5 删除字段 alter table 表名 drop 字段名
19.6 修改字段的排列位置
alter table 表名 modify 字段1 数据类型 first|after 字段2
19.7修改表的存储引擎
alter table 表名 engine=更改后的引擎名
19.8删除表的外键约束
alter table 表名 drop foreign key 外键约束名
20 删除数据表
drop table 表1,表2...;
如果写成drop table if exists 表1,表2...;可以再删除前判断表是否存在,如果不存在,SQL语句可以顺利执行,只是会发出警告。
删除主表时,必须先删除关联的表的外键约束条件,才能删除主表。
21.一些不太一样的运算符:
21.1等于运算符=,用来判断是否相等的,等于返回1
21.2安全等于运算符<=>,在=的基础上可以用来判断null的值,如果都为null时,其返回值为1
21.3<>不等于运算符
21.4 IS NULL,IS NOT NULL运算符
21.5 between and运算符:expr between min and max,假如expr大于或等于min且小于或等于max,则返回1, eg: select 4 between 4 and 6;
21.6 least运算符 多个值返回最小值
21.7 greatest 运算符 多个值返回最大值
21.8 in 、not in运算符 in判断操作数是否为in列表中的其中一个是(not in相反)
21.9 like运算符 expr like 匹配条件
22.一些函数:
22.1 ceil(x)向上取整函数 floor(x)向下取整函数
22.2 rand(x)可以用来产生随机数,x是种子
22.3round(x)返回最接近x的整数
22.4sign(x)返回参数的符号,负数返回-1,0返回0,整数返回1;
22.5 radians(x)将参数由角度转化成弧度 degrees(x)将x由弧度转化为角度
22.6 char_length计算字符串字符个数 eg char_length('date')
22.7 concat(s1,s2) 合并字符串函数 concat_ws(x,s1,s2)x为连接处的分隔符
22.8 insert(s1,x,len,s2) 替换字符串函数,返回s1
22.9 获取指定长度的字符串函数 left(s,n) 从左边开始第n个保留,right(s,n)从右边开始第n个符号保留
22.10删除空格函数 ltrim(s)、rtrim(s)、trim(s)
23.查询
23.1 SELECT 字段名,字段名 FROM 表名;
23.2 SELECT * FROM 表名; *为通配符,可查询所有字段
23.3 SELECT 字段名1、字段名2.。。。FROM 表名 WHERE 查询条件; WHERE后面可以跟条件判断符(例如相等=、不相等<>、大于>、小于<、between、in、is null、以及带and或者or的多条件查询等)
eg :查询价格为10.2元的水果的名称:
SELECT f_name,f_price FROM fruits where f_price =10.2; 注意这里表示的是是否等于
SELECT f_name,f_price FROM fruits where s_id in (101,102);
SELECT f_name,f_price FROM fruits where f_price between 2.00 and 10.2;
SELECT f_name,f_price FROM fruits where s_id="101"and f_price>=5;
23.4查询结不重复:SELECT DISTINCT 字段名 FROM 表名;
SELECT DISTINCT s_id FROM fruits;
23.5对查询结果排序(默认升序): SELECT f_name FROM fruits order by f_name;
对查询结果按降序排序 :SELECT f_name,f_id FROM fruits order by f_name DESC;
23.6分组查询:
23.6.1 创建分组: SELECT s_id,COUNT(*)AS Total FROM fruits GROUP BY s_id;
GROUP BY关键字对数据进行分组,它经常跟MAX()、MIN()、COUNT()、SUM()、AVG()等一起使用,例如上面这个例子就是把s_id分成了好几个分组,并对每个分组进行集合计算。
其结果为:
要想将名字显示出来:
select s_id , group_concat(f_name) as names from fruits group by s_id;
23.6.2 使用having 过滤分组
group by 可以与having一起来限定显示记录所需满足的条件
eg要将水果种类大于1的分组信息显示出来
select s_id,group_concat(f_name) as names from fruits group by s_id having count(f_name)>1;
23.6.3 在group by后面使用with rollup 可以记录计算查询出的所有记录的总和
select s_id,count(*) as total from fruits group by s_id with rollup;
23.6.4 多字段分组
这里按照书上的去写:
select * from fruits group by s_id,f_name;
没找到原因。。
然后我想着用这个应该能成:
select f_id,s_id,group_concat(f_name) as f_name,f_price from fruits group by s_id,f_name;
这结果就是跟书上一致了。
23.6.5 group by 可以与 order by连用来对结果进行排序
select s_id, sum(f_price) as total_price
from fruits
group by s_id
having sum(f_price)>15
order by total_price;
将查询记录先按部门编号高低排列,再按员工工资由高到低排列
select e_name,dept_no,e_salary
from employee
order by dept_no desc,e_salary desc;
23.7 限制查询结果数量 limit[位置偏移量] 行数;
select * from fruits limit 4; 只显示了从第一行到第四行
select * from fruits limit 4,3; 显示了第四行开始的后面三行
23.8使用集合函数查询
23.8.1 count()函数
该函数主要用来计算总数
count(*)计算表中总的行数(如果分组了,就是分组的总得行数),不管某列有数值或者为空值。
count(字段名)计算指定列下总的行数,计算时将忽略空值的行
23.8.2 sum函数用来计算总和,可以与group by 一起用来计算每个分组的总和
23.8.3 acg()函数来计算数据平均值
select avg(f_price) as avg_price
from fruits
group by s_id;
23.8.4 MAX()函数、min()函数
23.9内连接查询
在同一个数据库中,fruits与suppliers有相同数据类型的字段s_id,两个表通过s_id来建立联系,然后从fruits表中查询f_name/f_price,在suplliers表中查询s_id、s_name:
select suppliers.s_id,s_name,f_name,f_price
from fruits,suppliers
where fruits.s_id=suppliers.s_id;
where子句使得两个表中s_id字段值相等的时候才符合连接查询的条件。
select suppliers.s_id,s_name,f_name,f_price
from fruits inner join suppliers
on fruits.s_id=suppliers.s_id;
上面的写法输出了同样的结果
23.10 自连接查询
自连接是一种特殊的内连接查询,它涉及到的两个表都是同一个表,它是指相互连接的表在物理上为同一张表,但在逻辑上可以分为两张表。
查询供应f_id='a1'的水果供应商的其他水果种类:
select f1.s_id,f1.f_id,f1.f_name
from fruits as f1,fruits as f2
where f1.s_id=f2.s_id and f2.f_id='a1';
其结果为
这里为了避免二义性,去了别名,然后再where处,首先是把两个表中的s_id对应了(跟内连接相同),然后选择出f_id='a1'(我觉得可以这样理解:f2.f_id把''a1选出来,把此时的f1.s_id与f2.s_id进行了对比,也就是说,where选出来的应该是f1.s_id)自己写了一个:
select f1.s_id,f1.f_id,f1.f_name
from fruits as f1,fruits as f2
where f1.s_id=f2.s_id and f1.f_id='a1'; 这里吧f2.f_id换成了f1.f_id
这结果验证了我的想法,因为此时where选出来的是'a1'而不是s_id,所以最后输出的只有a1,但是不知道为什么,该结果重复了三次,想不懂。。等待以后考究
23.11外连接查询
有时候需要包含没有关联的行中数据,即返回查询结果中不仅包含符合连接的行,而且还包括坐标、右表或者两个连接表的所有数据行。外连接分为左外连接和右外连接。
23.11.1 left join连接
左连接的结果包括left outer子句汇总指定的左表的所有航,而不仅仅是连接列所匹配的行。如果左表的某行在右表没有匹配行,则在相关联的结果行中,右表的所有选择列表列均为空值。
select customers.c_id,orders.o_num
from customers left outer join orders
on custormers.c_id=orders.c_id;
23.11.2 right join连接同理
23.12子查询
子查询指一个查询语句嵌套在另一个查询语句内部的查询,其常用操作符:any、all、in、exists,子查询可以添加到select、update和delete语句中,而且可以进行多层嵌套,子查询也可以使用比较运算符。
23.13.1 any、some关键字
any 和 some 关键字是同义词,表示满足其中任一条件,它们允许创建一个表达式对子查询的返回值列表进行比较,只要满足内层子查询中的任何一个比较条件,就返回一个叫结果作为外层查询条件。
any关键字姐在一个比较操作符后面,表示若与子查询返回的任何值比较为true,则返回true
首先建立两个数据表:
create table tbl1(num1 int not null);
create table tbl2(num2 int not null);
insert into tbl1 values(1),(5),(13),(27);
insert into tbl2 values(6),(14),(11),(20);
返回tbl2表的所有num2列,然后将tbl1中的num1的值与之进行比较,只要大于num2的任何一个值,即为符合查询条件的结果。
select num1 from tbl1 where num1 >any(select num2 from tbl2);
23.13.2 all关键字
all 关键字需要同时满足所有内层查询的条件
select num1 from tbl1 where num1 >all(select num2 from tbl2);
与前面的any不同,any是num1只要大于num2任意一个就输出,all是要比所有的都大,才能输出
23.13.3 exists关键字
该关键字用来判断是否有返回行,如果至少返回一行,则exists结果为ture,此时未曾查询语句将进行查询,如果子查询没有返回任何行,则exists返回结果为false。
查询tmp10 中是否有soc=100,如果有则返回fruits中的所有数据:
select * from fruits
where exists
(select * from tmp10 where soc = 100);
exists还可以和条件表达式连用:
select * from fruits
where f_price > 10.2 and exists
(select * from tmp10 where soc = 100);
not exists与exists使用方法相同,只是查询的是不存在
23.13.4 in关键字
内层查询语句返回一个数据列,这个数据列的值将提供给外层查询语句进行比较操作
这是orderitems
这是fruits:
通过查找orderitems中0_num=100的值,并返回orderitems中的f_id,将其返回给fruits的f_id,然后通过f_id来查询f_price
select f_price,f_id from fruits where f_id in
(select f_id from orderitems where o_num = 100);
同时还有not in 就是返回的不满足条件的结果
23.13.5 带比较运算符的子查询
23.14 合并查询结果:
通过union来合并查询结果,合并时,两个表对应的列数和数据类型必须相同,加了all则不删除重复行也不对结果自动排序,不加all则删除重复消息
select s_id,f_name,f_price
from fruits
where f_price < 9
union all
select s_id,f_name,f_price
from fruits
where s_id in (101,103);
xbanana是union all上面的查询语句查询的结果,xbanana后面是union all下面的查询语句查询的结果
去掉all以后:没有了重复
23.15 用as可以为表和字段取别名
23.16使用正则表达式查询
mysql中使用regexp关键字指定正则表达式的字符匹配模式
^ 匹配文字开头
& 匹配文字结束
. 匹配任何单个字符
* 匹配零个或多个在它前面的字符
+ 匹配前面的字符一次或者多次
<字符串> 匹配包括指定的字符串的文本
[字符集合] 匹配字符集合中任何一个字符
[^]匹配不在括号中的任何字符 eg [^abc]就是不包括a、b、c
{n,}匹配前面的字符串至少n次
{n,m}匹配前面的字符串至少n次,至多m次
23.17 综合测试遇到的一些问题和思考
做综合测试的时候想要显示max 或min对应的其他属性,发现报错了:
select e1.e_no,e1.e_name,e1.e_salary
from employee as e1,employee as e2
group by e1.dept_no
having e1.e_no=e2.e_no and e2.e_salary=max(e2.e_salary);
select e1.e_no,e1.e_name,e1.e_salary
from employee as e1,employee as e2
where e1.e_no=e2.e_no and e2.e_salary=max(e2.e_salary);
以上都报错了
改良版:
select e_no,e_name,e_salary
from employee
group by dept_no
having e_salary=
(select max(e_salary)
from employee);
但是这个只能射出最大的那个的相关信息
完成版:
select e1.e_no,e1.e_name,e1.e_salary from employee as e1
where e1.e_salary in
(select max(e2.e_salary)
from employee as e2
group by e2.dept_no);
这个可以输出每个组最大的那个salary的其他信息。
子查询很好用啊,用来查询一个信息的相关信息的时候可以用(例子如上),还有一个可以用在横跨两个表之间,如果要查询员工BLAKE的所在部门和部门所在地,BLAKE的所在部门在employee表中,部门所在地在dept表中,这时候可以这样横跨:
select d_no , d_location
from dept
where d_no in
(select dept_no from employee where e_name='BLAKE');
使用连接查询,查询所有员工的部门和部门信息:
select d_no , d_location
from dept
where d_no in
(select dept_no from employee where e_name='BLAKE');
内连接查询,同时查了两块表
24插入
24.1 insert into 表名(插入数据的列) values (插入的数据)
eg: insert into person (id,name,age ,info)
values (1,'green',21,'lawyer');
还可以为指定位置插入值,
insert into person (age )
values (20);
没有插入的部分会被设为null,有默认的就会直接设置为默认值
24.2 同时插入多条记录
insert into 表名(插入数据的列) values(数据),(数据),(数据)
24.3 将查询结果插入到表中
insert into 表1 (列1)
select (列2) from 表2 where (条件)
eg:
insert into person (id,name,age,info)
select id,name,age,info from person_old;
25 更新数据
update table_name
set 字段1=value1,字段2=value2
where (condition)
eg:
update person
set age=15,name='Liming'
where id=10;
eg:
update person
set info='student'
where age between 19 and 22;
上面是把age从19到22的职业全部改成student
eg:
update books set price = price +5 where note = 'novel';
26 删除
delete from table_name [where <condition>]
eg delete from person where id=10;
eg delete from person where age between 19 and 22;
上面这个删除在workbench中报错了,好像是进入了安全更新模式才出现的,设置一下编辑器就可以了
delete from person;
这个也是一样的报错了。
来源:oschina
链接:https://my.oschina.net/u/4433424/blog/3159489