数据库的介绍
数据库管理系统: Mysql,oracle,sqlite,access,sql,server等 数据库服务器: 数据库管理系统运行的机器,就是数据库服务器. 数据库分为两种, 有关系型和非关系型
Redis Celery
MySQL的初始
1.登录mysql
mysql -u root -p 远程登录 mysql -u root -p -h106.52.85.190 -P端口 # 注意使用命令远程链接mysql,必须使用的地方有mysql mysql -hIP -P端口 -uroot -p密码
2.修改密码
mysqladmin -uroot -p123 password "新密码" mysqladmin -uroot -p password "新密码"
3.忘记密码,破解(linux)
# 1. 修改配置文件(linux命令行) sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf # 在[mysqld] 下加上skip-grant-tables # 2. 重启mysql服务(linux命令行) systemctl restart mysql # 3.登录root管理用户,不需要输入密码(linux命令行) mysql -u root -p # 直接回车,即可进入mysql命令 # 4. 设置新密码(mysql命令行) mysql> update mysql.user set authentication_string=password('root123') where user="root" and host="localhost"; # 5. 刷新授权表(mysqL命令行) mysql> flush privileges; # 6.进入mysql的配置文件,删除掉先加入的内容,保存退出,重启mysql服务.(linux命令行) sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf # 重启mysql服务(linux命令行) systemctl restart mysql
4.设置统一字符编码(linux版本)
# 1. 修改mysqld配置文件 sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf #加上如下代码 [mysqld] character-set-server=utf8 collation-server=utf8_general_ci # 修改mysql客户端的配置文件 sudo vim /etc/mysql/conf.d/mysql.cnf [mysql] default-character-set=utf8 [client] default-character-set=utf8 # 2、重启MySQL服务 systemctl restart mysql # 3、查看一下 show variables like "%char%"; 注意有坑: 在配置统一字符编码之前的数据库,建议建表的时候,指定字符编码.
MySQL的操作
增删查改
1.操作数据库(目录)
# 增(添加数据库) create database db1 default charset utf8; # 查(查看数据库) show databases; # 查看所有数据库 show create database db1; # 查看指定的数据库 # 改(修改数据库编码) alter database db1 charset gbk; # 修改数据库的字符编码 # 删(删除数据库) drop database db1;
2.操作数据表(文件)
# 增(添加数据表) create table t1(id int,name varchar(32)); # 指定字段 # 查(查看表和表属性) show tables; # 查看所有表(当前数据库下的) show create table t1; # 查看指定表 desc t1; # 查看表属性 mysql> desc t1; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | varchar(32) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ # 改(修改表) alter table t1 modify name char(6); # (modify) 只能修改约束条件和类型 alter table t1 change name Name char(7); # (change) 力度更大,可以改字段名加(modify)的功能 alter table t1 add price decimal(5,2) not null;# (add) 新增price字段 # 删(删除表) drop table t1; # 指定对应的表名; alter table book drop price; # 删除指定的字段名 truncate table t1; # 清空所有记录,并且重置至初识状态,id从1开始
3.操作表记录(文件内容)
# 增(添加表内容) 1.如果所有字段都添加 insert into t1 values(1,"xiaoming"),(2,"xiaohong"); # 按位置添加 insert into t1(id,name) values(1,'xiaoming'),(2,"xiaohong") # 指定字段添加 2.如果指定字段添加 insert into t1(name) values("xiaoming"),("xiaohong"); # 查(查找表内容) select * from t1; # 查看所有字段 select * from t1 where id=1; # 指定字段 # 改(更改表内容) update t1 set name="xiaomi" where id=1; # 注意,不where指定条件,默认会修改所有name的内容 # 删(删除表内容) delete from t1 where name="xiaomi"; # 注意,不where指定id或条件,跟上面说的一样
MySQL的数据类型
1.数值类型
整数类型
""" unsigned 指定该字段为无符号类型 """ tinyint # 2**8(2的8次方范围)1个字节 # 注意:当插入的值超过这个范围,会报1264错误。 '有符号 -128---127 无符号 0---255 ' '# 有符号例子 mysql> create table t1(num tinyint) #创建表结构 mysql> desc t1; #查看表信息 mysql> insert into t1 values(-128),(127); mysql> select * from t1; #查看表内容 # 无号例子 #unsigned 指定无符号类型 mysql> create table t2(num tinyint unsigned); mysql> desc t2; #查看表信息 mysql> insert into t2 values(0),(255); mysql> select * from t2; #查看表内容' int # 2**32(2的32次方范围)4个字节 ' 有符号:-2147483648 ~ 2147483647 无符号: 0 ~ 4294967295 ' bigint # 2**64(2的64次方范围)8个字节 ' 有符号:-9223372036854775808 ~ 9223372036854775807 无符号:0 ~ 184467440737 '
浮点型
decimal: ''' 定义: 准确的小数值,m是数字总个数(负号不算),d是小数点后个数。 m最大值为65,d最大值为30。m:65d:30 精确度: **** 随着小数的增多,精度始终准确 **** 对于精确数值计算时需要用此类型 decaimal能够存储精确值的原因 # 例子 mysql> create table t1(num decimal(5,2)); mysql> insert into t1 values(456.12); mysql> select * from t1; '''
2.日期类型
year #(年) 无论year指定何种宽度,最后都默认是year(4) ''' # 例子 mysql> create table t1(born_year year); mysql> desc t1; mysql> insert into t1 values(1901),(2155);# 超出这个范围会报1264错误。 mysql> select * from t1; ''' date # (日期格式) ''' # 例子 mysql> create table t1(born_date date); mysql> desc t1; mysql> insert into t1 values("2019-5-5"); mysql> select * from t1; ''' time # (时间格式) datetime #(***)(日期时间格式)(1000-01-01 00:00:00/9999-12-31 23:59:59) timestamp #(了解)(1970-01-01 00:00:00/2037 年某时) ''' #三个集合语句 mysql> create table t1(d date,t time,dt datetime); mysql> desc t1; mysql> insert into t1 values(now(),now(),now());#当前日期时间 mysql> select * from t1; 1. 单独插入时间时,需要以字符串的形式,按照对应的格式插入 2. 插入年份时,尽量使用4位值 3. 插入两位年份时,<=69,以20开头,比如50, 结果2050 >=70,以19开头,比如71,结果1971 '''
3.字符串类型
char: # 字符长度范围:0-255 # 定长,执行效率高,浪费空间. varchar: # 字符长度范围:0-65535 # 不定长,速度慢,范围大,节省空间. # 根据实际场景,来平衡使用,char要放在varchar的前面 char_length:# 查看字符数 '''# 例子,查看 mysql> create table t1(c char(5),v varchar(5)); mysql> desc t1; mysql> insert into t1 values('字符串 ','字符串 '); # 增加了空白格 mysql> select c,char_length(c),v,char_length(v) from t1; # 查询字符长度 # char填充空格来满足固定长度,但是在查询时却会很不要脸地删除尾部的空格(装作自己好像没有浪费过空间一样),然后修改sql_mode让其现出原形。 # 略施小计,让char现出原形 mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH'; # 让它显示原先的字符长度 ''' #length: #查看字节数 mysql> select c,length(c),v,length(v) from t1;
4.枚举类型和集合类型
1. # 枚举类型(单选) enum("xxx", "xxx"....) 2. # 集合类型(多选) set("xxx", "xxx","xxx"...) enum # 单选 只能在给定的范围内选一个值,如性别 sex 男male/女female set # 多选 在给定的范围内可以选择一个或一个以上的值(爱好1,爱好2,爱好3...) '''# 枚举和集合例子 mysql> create table t1(id int,name varchar(32),sex enum('male','female'),hobby set('music','read','run','movie')); mysql> desc t1; mysql> insert into t1 values(1,'alex','female','music,movie,aaaa'), -> (2,'egon','female','read,run,music'); mysql> select * from t1; '''
mysql语法严格模式
插入字段不在列表中,值为空,如果报错,mysql为严格模式 ERROR 1265 (01000): Data truncated for column 'hobby' at row 1 严格模式: 严格模式主要有以下场景: 不支持对not null字段插入null值 不支持对自增长字段插入”值 不支持text字段有默认值 1.开启与关闭Strict Mode方法 找到MySQL安装目录下的my.cnf(windows系统则是my.ini)文件 在sql_mode中加入STRICT_TRANS_TABLES则表示开启严格模式,如没有加入则表示非严格模式,修改后重启mysql即可 例如这就表示开启了严格模式: sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
MySQL字段类型
# 约束条件 not null # 字段不能为空 default # 设置默认值 unique # 主键,字段唯一 auto_increment # 自增长,默认为1 该字段必须为主键.主键自增长,被约束的字段必须同时被key约束,一般用于id primary key # 外键,建立表之间的关系
1.not null 和 defult的用法
not null # 约束字段不能为空 default # 设置默认值 # 用法: (字段名称 数据类型 约束条件) mysql> create table t1(id int,name varchar(32),sex enum('male','female') not null default 'male'); mysql> desc t1; +-------+-----------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-----------------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | varchar(32) | YES | | NULL | | | sex | enum('male','female') | NO | | male | | +-------+-----------------------+------+-----+---------+-------+ mysql> insert into t1(id,name) values(1,'egon'); # 插入数据 mysql> select * from t1; +------+------+------+ | id | name | sex | +------+------+------+ | 1 | egon | male | +------+------+------+
2.unique的用法
# 单列唯一 # 方式一: # 直接在字段后加约束条件 mysql> create table t3(id int unique auto_increment,name varchar(32) unique); mysql> desc t3; mysql> insert into t3(name) values('it','id'); # 指定字段,auto_increment自增长,默认为1 mysql> insert into t3 values(7,'ip'),(8,'ip'); # 插入相同的名字会报错 ERROR 1062 (23000): Duplicate entry 'ip' for key 'name' # 方式二:#两着效果相同 unique(字段名) mysql> create table t3(id int,name varchar(32),unique(id),unique(name)); mysql> desc t3; mysql> insert into t3 values(1,'IT'),(2,'IT'); # 插入相同的名字会报错 ERROR 1062 (23000): Duplicate entry 'IT' for key 'name' # 多列联合唯一 unique(字段名1,字段名2...) # 联合唯一的,只有两两相等,才会报错,and的关系 mysql> create table t3(id int,ip char(15),port int,unique(id),unique(ip,port)); mysql> desc t3; +-------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+-------+ | id | int(11) | YES | UNI | NULL | | | ip | char(15) | YES | MUL | NULL | | | port | int(11) | YES | | NULL | | +-------+----------+------+-----+---------+-------+ mysql> insert into t3 values(1,'192.168.0.1',8080), -> (2,'192.168.0.1',8090), -> (3,'192.168.0.2',8080); mysql> select * from t3; #报错例子 mysql> insert into t3 values(4,'192.168.0.1',8080); # 插入数据 ERROR 1062 (23000): Duplicate entry '192.168.0.1-8080' for key 'ip'
3.primary key
# 用法同unique # auto_increment自增长,默认起始值为1 mysql> create table t3(id int primary key auto_increment,name varchar(32)); mysql> desc t3; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(32) | YES | | NULL | | +-------+-------------+------+-----+---------+----------------+ mysql> insert into t3(name) values('alex'),('egon'); mysql> select * from t3; +----+------+ | id | name | +----+------+ | 1 | alex | | 2 | egon | +----+------+ # 重复键值,会报错 mysql> insert into t3 values(2,'yuan'); ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'
4.auto_increment
''' 前提:字段必须为主键. 作用:是主键自增长 被约束的字段必须同时被key约束。''' mysql> create table t3(id int primary key auto_increment,name varchar(32)); mysql> desc t3; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(32) | YES | | NULL | | +-------+-------------+------+-----+---------+----------------+ mysql> insert into t3(name) values('alex'),('egon'); mysql> select * from t3; +----+------+ | id | name | +----+------+ | 1 | alex | | 2 | egon | +----+------+ mysql> insert into t3 values(5,'yuan'); # 可以自己指定id只要不违反约束条件即可。 # 对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增长,一般情况下,delete后面会接where条件,对指定的内容进行删除。 mysql> delete from t3; # 清空表 再重新插入数据起始位置不会从1开始 mysql> truncate table t3;# 清空所有记录,并且重置至初识状态(ID归零)清空auto_increment的索引值 # 关于起始偏移量和步长(了解) # 1. 查看默认值 mysql> show variables like 'auto_inc%'; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | auto_increment_increment | 1 | # 默认步长为1 | auto_increment_offset | 1 | # 默认起始偏移量为1 +--------------------------+-------+ # 2. 设置步长 mysql> set session auto_increment_increment=5; # 当前会话级别 mysql> set global auto_increment_increment=5; # 设置全局,需要退出重新加载才能生效。 # 3.设置起始偏移量 mysql> set session auto_increment_offset=3; mysql> set global auto_increment_offset=3; # 注意:起始偏移量要<=步长,否则设置无效。
5.foreign key
foreign key,# 外键 ,建立表之间的关系。 # 1、建立表关系 # a、先建被关联的表,且保证被关联的字段唯一 mysql> create table department( -> id int primary key , -> name varchar(32), -> comment varchar(128) -> ); mysql> desc department; +---------+--------------+------+-----+---------+--------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+--------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(32) | YES | | NULL | | | comment | varchar(128) | YES | | NULL | | +---------+--------------+------+-----+---------+--------+ # b、再建关联的表 mysql> create table employee( -> id int primary key auto_increment, # 主键自增长 -> name varchar(32), -> age tinyint unsigned, -> dep_id int, -> foreign key(dep_id) references department(id) # 指定外建字段,跟哪张表哪个字段建立关系。 -> ); mysql> desc employee; +--------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+---------------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(32) | YES | | NULL | | | age | tinyint(3) unsigned | YES | | NULL | | | dep_id | int(11) | YES | MUL | NULL | | +--------+---------------------+------+-----+---------+----------------+ # 2、插入数据 # a、先往被关联表插入记录 mysql> insert into department values -> (1,'公关部','公关能力有限部门'), -> (2,'销售部','销售能力有限部门'), -> (3,'技术部','靠技术吃饭部门'); # b、再往关联表插入记录 mysql> insert into employee values -> (1,'任盈盈',18,1), -> (2,'张无忌',23,2), -> (3,'令狐冲',25,2), -> (4,'小龙女',24,1), -> (5,'灭绝师太',56,1), -> (6,'欧阳锋',53,3); # 3.删除数据和更新数据 # a、先删除关联的数据 mysql> delete from employee where dep_id=2; # b、再删除被关联的数据 mysql> delete from department where id=2; # c、因为有外建约束,无法进行更新操作。 # mysql> update employee set id=5 where dep_id=3; # ERROR 1062 (23000): Duplicate entry '5' for key 'PRIMARY' # mysql> update department set id=8 where id=2 # 4、解决上面的问题,只需在建 关联表 的时候,指定一下同步即可。 # 建立关联表 mysql> create table employee( -> id int primary key, -> name varchar(32), -> age tinyint unsigned, -> dep_id int, -> foreign key(dep_id) references department(id) on delete cascade # 删除时同步 on update cascade # 更新时同步 -> ); # 删除部门 mysql> delete from department where id =1; mysql> select * from department ; +----+-----------+--------------------------+ | id | name | comment | +----+-----------+--------------------------+ | 2 | 销售部 | 销售能力有限部门 | | 3 | 技术部 | 靠技术吃饭部门 | +----+-----------+--------------------------+ mysql> select * from employee; # 与之关联的员工一并删除了。 +----+-----------+------+--------+ | id | name | age | dep_id | +----+-----------+------+--------+ | 2 | 张无忌 | 23 | 2 | | 3 | 令狐冲 | 25 | 2 | | 6 | 欧阳锋 | 53 | 3 | +----+-----------+------+--------+ # 更新部门 mysql> update department set id=8 where id=2; mysql> select * from department; +----+-----------+--------------------------+ | id | name | comment | +----+-----------+--------------------------+ | 3 | 技术部 | 靠技术吃饭部门 | | 8 | 销售部 | 销售能力有限部门 | +----+-----------+--------------------------+ # 与之关联的表也会更改 mysql> select * from employee;
MySQL的查询语法
# 1.单表查询语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 2.关键字的执行优先级(重点) # 注解: 1.from # 找到表:from 2.where # 拿着where指定的约束条件,去文件/表中取出一条条记录 3.group by # 将取出的一条条记录进行分组group by,如果没有group by,则整体作为一组 4.having # 将分组的结果进行having过滤 5.select # 执行select 6.distinct # 去重 7.order by # 将结果按条件排序:order by 8.limit # 限制结果的显示条数
单表查询
数据结构准备
# 插入数据结构 mysql> create table employee( -> id int primary key auto_increment, -> name varchar(32) not null, -> sex enum('male','female') not null default 'male', -> age tinyint unsigned not null default 28, -> hire_date date not null, -> post varchar(32), -> post_comment varchar(128), -> salary decimal(9,2), -> office int, # 一个部门一个屋子 -> dep_id int -> ); # 插入数据 mysql> insert into employee(name,sex,age,hire_date,post,post_comment,salary,office,dep_id) values ('任盈盈','female',18,'2018-11-14','sale',null,8000,401,1), ('小龙女','female',23,'2017-11-24','sale',null,9000,401,1), ('王语嫣','female',22,'2016-1-14','sale',null,7000,401,1), ('黄蓉','female',21,'2018-12-14','sale',null,8000,401,1), ('秋香','female',19,'2019-1-11','sale',null,8000,401,1), ('周芷若','female',20,'2018-11-11','sale',null,7000,401,1), ('赵敏','female',21,'2017-2-18','sale',null,8000,401,1), ('令狐冲','male',24,'2017-1-24','operation',null,7000,402,2), ('张无忌','male',23,'2016-5-21','operation',null,7500,402,2), ('郭靖','male',25,'2016-7-28','operation',null,8000,402,2), ('杨康','male',24,'2016-8-28','operation',null,7000,402,2), ('杨铁心','male',54,'2015-4-18','operation',null,9000,402,2), ('杨过','male',27,'2017-5-28','operation',null,7000,402,2), ('张三丰','male',68,'2014-8-8','teacher','主授太极拳',11000,403,3), ('任我行','male',54,'2015-2-4','teacher','主授吸星大法',10000,403,3), ('岳不群','male',50,'2016-12-24','teacher','主授华山剑法',9000,403,3);
1.简单查询
# 查看全部,复杂写法(字段一个个写) select id,name,sex,age,hire_date,post,post_comment,salary,office,dep_id from employee; # 查看全部表内容(实际不推荐这种,按上面那种来写) select * from employee; # 查看指定表字段内容 select id ,name,salary from employee; # 避免重复distinct select distinct post from employee; # 查看指定内容,只显示单个不重复内容 # 通过四则运算查询(加减乘除) select name,salary * 12 from employee; # 原样显示(salary*12) # 修改样式用as 取别名,不加as 默认后面就是别名 select name,salary * 12 as annual_salary from employee;
2.where用法
# where约束条件 ''' where字句中可以使用: 比较运算符:><>= <= <> != between 80 and 100 值在80到100之间 in(80,90,100) 值是80或90或100 like '姓%' '姓_' 可以是%或_,%表示匹配任意多字符, _表示匹配一个字符 逻辑运算符:在多个条件直接可以使用逻辑运算符 and or not ''' # 1、单条件查询 # 查询销售的所有员工 select name from employee where post='sale'; # 2、多条件查询 # 查询销售中工资大于等于8000的员工姓名和薪资 select name,salary from employee where post='sale' and salary >=8000; # 3、关键字between and # 查询不在8000到10000的员工姓名 ,只需在between 前面加not ---> (not between) # 查询工资在8000到10000的员工姓名 select name from employee where salary between 8000 and 10000; # 4、关键字is null(判断某个字段是否为null不能用等号,需要用is) # 查询值位不为空的员工,只需在is后面加not ---> (is not) # 查询职位描述为空的员工 select name,post_comment from employee where post_comment is null; # 特殊符号 '' 是空字符串,不是null # 更新 update employee set post_comment='' where id=1; # 查询 select name ,post_comment from employee where post_comment=''; # 5、关键字IN集合查询 # or 原型(复杂) select name,salary from employee where salary=8000 or salary=9000 or salary=10000; #查询工资不为8000或9000或10000的,只需在in前面加not ---> (not in) # 查询工资为8000或9000或10000的员工姓名和工资 select name,salary from employee where salary in (8000,9000,10000); # 6、关键字LIKE模糊查询 # a、通配符"%",查找'杨'开头的 select name from employee where name like '杨%'; # b、通配符"_" #查找以"杨"开头的两个字符,'__',查找杨的三个字符 select naem from employee where name like '杨_'
3.group by用法
# 单独使用GROUP BY关键字分组 # 注意:我们按照post字段分组,那么select查询的字段只能是post,想要获取组内的其他相关信息,需要借助函数。如:select post from employee group by post; # GROUP BY关键字和GROUP_CONCAT()函数一起使用 # 按照岗位分组,并查看组内成员名 SELECT post,GROUP_CONCAT(name) FROM employee GROUP BY post; #更改别名 SELECT post,GROUP_CONCAT(name) as emp_members FROM employee GROUP BY post; # 聚合函数 # MAX:最大值 # MIN:最小值 # AVG:平均值 # SUM:求和 # COUNT:计数 # 查询每个职位最高的薪资 select post,max(salary) from employee group by post; # 查询每个职位共有多个员工 select post,count(id) from employee group by post;
4.having用法
# having过滤 # HAVING与WHERE不一样的地方在于: # !!!执行优先级从高到低:where > group by > having # 1. Where 发生在分组group by之前,因而Where中可以有任意字段,但是绝对不能使用聚合函数。 # 2. Having发生在分组group by之后,因而Having中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数 # 查询各岗位内包含的员工个数小于4的岗位名、岗位内包含员工名字、个数 select post,group_concat(name),count(id) from employee group by post having count(id) < 4;
5.order by用法
# 按单列排序 select * from employee order by salary; # 默认为升序 SELECT * FROM employee ORDER BY salary ASC; # 升序 SELECT * FROM employee ORDER BY salary DESC; # 降序 # 按多列排序:先按照age排序,如果年纪相同,则按照薪资排序 SELECT * from employee ORDER BY age,salary DESC;
6.limit用法
# 限制查询的记录数 limit select * from employee order by salary desc limit 3; #默认初始位置为0 #查询第三条 select * from employee order by salary desc limit 0,5 #从第0开始,即先查询出第一条,然后包含这一条在内往后查5条 SELECT * FROM employee ORDER BY salary DESC LIMIT 5,5; #从第5开始,即先查询出第6条,然后包含这一条在内往后查5条
7.regexp用法
# 使用正则表达式查询 SELECT * FROM employee WHERE name REGEXP '^任'; #以任开头匹配 SELECT * FROM employee WHERE name REGEXP '女$'; #以女结尾匹配 # 小结:对字符串匹配的方式 WHERE name = '任盈盈'; WHERE name LIKE '杨%'; WHERE name REGEXP '女$';
多表查询
表关系说明
''' 一对一 一对多 多对多 ''' # 表连接方式 inner join # 内连接 left join # 左连接 right join # 右连接 union # 全连接(mysql中用左连接右连接实现) # 子查询 #1:子查询是将一个查询语句嵌套在另一个查询语句中。 #2:内层查询语句的查询结果,可以为外层查询语句提供查询条件。 #3:子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字 #4:还可以包含比较运算符:= 、 !=、> 、<等
一对一
# 一对一关系 # 两张表:学生表和客户表 # 一对一:一个学生是一个客户,一个客户有可能变成一个学校,即一对一的关系 # 关联方式 :foreign key + unique # 一定是student来foreign key表customer,这样就保证了: # 1 学生一定是一个客户, # 2 客户不一定是学生,但有可能成为一个学生 # 1.创建表 # 先建客户表 create table customer( id int primary key auto_increment, name varchar(32) not null, qq varchar(32) not null, tel varchar(32) not null ); # 再建学生表 create table student( id int primary key auto_increment, class_name varchar(32) not null, customer_id int unique, #该字段一定要是唯一的,#也可以建在客户表 foreign key(customer_id) references student(id) on delete cascade on update cascade # 关联同步删除同步更新 ); # 2.插入记录 # 先插被关联的客户表 insert into customer(name,qq,tel) values ('alex',1223,135666544), ('egon',34322,13438895), ('yuan',84322,13954893); # 再插关联的表 insert into student(class_name,customer_id) values ('脱产2期',1), ('脱产3期',2), ('周末13期',3);
一对多
# 以出版社和书籍为例 # 1.创建表 create table press( id int primary key auto_increment, name varchar(32) ); create table book( id int primary key auto_increment, name varchar(32), press_id int, foreign key(press_id) references press(id) on delete cascade on update cascade # 关联同步删除同步更新 ); # 2.插入记录 # 先插被关联的表 inser into press(name) values ('华山出版社'), ('少林出版社'), ('明教出版社'), ('武当出版社'), ('丐帮出版社'); # 再插关联的表 insert into book(name,press_id) values ('独孤九剑',1), ('华山剑法',1), ('九阳神功',2), ('九阴真经',2), ('易筋经',2), ('葵花宝典',3), ('乾坤大挪移',3), ('太极拳',4), ('天罡北斗阵',4), ('吸星大法',5);
多对多
# 1.创建表 # 先创建作者表 create table author( id int primary key auto_increment, name varchar(32), ); # 再建存放作者与书的关系表,即查询二者的关系查这表就可以了. # author2book 建二者关系表时,用2把二者连接起来,约定熟成这样标识 create table author2book( id int not null unique quto_increment, author_id int, book_id int, foreign key(author_id) references author(id) on delete cascade on update cascade, foreign key(book_id) references book(id) on delete cascade on update cascade, primary key(author_id,book_id) ); # 2.插入记录 # 插入作者记录 insert into author(name) values ('张无忌'), ('令狐冲'), ('东方不败'), ('张三丰'), ('冲虚道长'); # 再插入对应的关系记录 insert into author2book(author_id,book_id) values (1,3), (1,7), (2,1), (2,2), (3,6), (4,8);
表连接方式(join..)
# 外连接语法 SELECT 字段列表 FROM 表1 INNER|LEFT|RIGHT JOIN 表2 ON 表1.字段 = 表2.字段; 交叉连接(笛卡尔积) # 注意:这种连接毫无意义 mysql> select * from book,press; # 简单粗暴的将两张表连接起来 # 如果只想取到两表有关系的记录用where条件 mysql> select * from book,press where book.press_id=press.id; #也可以用sql对应的语法实现.
1.inner join内连接用法
# 内连接,只取两表的共同部分 select * from book inner join press on book.press_id = press.id; +----+------------+----------+----+------------+ | id | name | press_id | id | name | +----+------------+----------+----+------------+ | 1 | 独孤九剑 | 1 | 1 | 华山出版社 | | 2 | 华山剑法 | 1 | 1 | 华山出版社 | | 3 | 九阳神功 | 2 | 2 | 少林出版社 | | 4 | 九阴真经 | 2 | 2 | 少林出版社 | | 5 | 易筋经 | 2 | 2 | 少林出版社 | | 6 | 葵花宝典 | 3 | 3 | 明教出版社 | | 7 | 乾坤大挪移 | 3 | 3 | 明教出版社 | | 8 | 太极拳 | 4 | 4 | 武当出版社 | | 9 | 天罡北斗阵 | 4 | 4 | 武当出版社 | +----+------------+----------+----+------------+
2.left join 左连接用法
#先插入一条新的book记录 insert into book(name) values('降龙十八掌'); # 左连接,在内连接的基础上保留左边的记录。 select * from book left join press on book.press_id = press.id; +----+------------+----------+------+------------+ | id | name | press_id | id | name | +----+------------+----------+------+------------+ | 1 | 独孤九剑 | 1 | 1 | 华山出版社 | | 2 | 华山剑法 | 1 | 1 | 华山出版社 | | 3 | 九阳神功 | 2 | 2 | 少林出版社 | | 4 | 九阴真经 | 2 | 2 | 少林出版社 | | 5 | 易筋经 | 2 | 2 | 少林出版社 | | 6 | 葵花宝典 | 3 | 3 | 明教出版社 | | 7 | 乾坤大挪移 | 3 | 3 | 明教出版社 | | 8 | 太极拳 | 4 | 4 | 武当出版社 | | 9 | 天罡北斗阵 | 4 | 4 | 武当出版社 | | 10 | 吸星大法 | 5 | 5 | 丐帮出版社 | | 11 | 降龙十八掌 | NULL | NULL | NULL | +----+------------+----------+------+------------+
3.right join 右连接用法
# 先插入一条新的press记录 insert into press(name) values('峨眉出版社'); # 右连接,在内连接的基础上保留右边的记录。 select * from book right join press on book.press_id = press.id; +------+------------+----------+----+------------+ | id | name | press_id | id | name | +------+------------+----------+----+------------+ | 1 | 独孤九剑 | 1 | 1 | 华山出版社 | | 2 | 华山剑法 | 1 | 1 | 华山出版社 | | 3 | 九阳神功 | 2 | 2 | 少林出版社 | | 4 | 九阴真经 | 2 | 2 | 少林出版社 | | 5 | 易筋经 | 2 | 2 | 少林出版社 | | 6 | 葵花宝典 | 3 | 3 | 明教出版社 | | 7 | 乾坤大挪移 | 3 | 3 | 明教出版社 | | 8 | 太极拳 | 4 | 4 | 武当出版社 | | 9 | 天罡北斗阵 | 4 | 4 | 武当出版社 | | 10 |吸星大法 | 5 | 5 | 丐帮出版社 | | NULL | NULL | NULL | 6 | 峨眉出版社 | +------+------------+----------+----+------------+
4.union全连接用法
# 全外连接,在内连接的基础上保留左右两表没有对应关系的记录。 # 注意:mysql不支持全外连接 full JOIN mysql> select * from book full join press on book.press_id = press.id; #报错 ERROR 1054 (42S22): Unknown column 'book.press_id' in 'on clause' # 强调:mysql可以使用此种方式间接实现全外连接(自己实现全外连接的效果) # union 连接两个以上的 SELECT 语句的结果组合到一个结果集合中。多个 SELECT 语句会删除重复的数据。 select * from book left join press on book.press_id = press.id union select * from book right join press on book.press_id = press.id; +------+-----------------+----------+------+-----------+ | id | name | press_id | id | name | +------+-----------------+----------+------+-----------+ | 1 | 独孤九剑 | 1 | 1 | 华山出版社 | | 2 | 华山剑法 | 1 | 1 | 华山出版社 | | 3 | 九阳神功 | 2 | 2 | 少林出版社 | | 4 | 九阴真经 | 2 | 2 | 少林出版社 | | 5 | 易筋经 | 2 | 2 | 少林出版社 | | 6 | 葵花宝典 | 3 | 3 | 明教出版社 | | 7 | 乾坤大挪移 | 3 | 3 | 明教出版社 | | 8 | 太极拳 | 4 | 4 | 武当出版社 | | 9 | 天罡北斗阵 | 4 | 4 | 武当出版社 | | 10 | 吸星大法 | 5 | 5 | 丐帮出版社 | | 11 | 降龙十八掌 | NULL | NULL | NULL | | 12 | 如来神掌 | NULL |NULL | NULL | | NULL | NULL | NULL | 6 | 峨眉出版社 | +------+-----------------+----------+-------+------+- -+
添加数据多表查询
# 为book表新增单价字段 alter table book add price decimal(5,2) not null; # 查看表结构 mysql> desc book; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(32) | YES | | NULL | | | press_id | int(11) | YES | MUL | NULL | | | price | decimal(5,2) | NO | | NULL | | +----------+--------------+------+-----+---------+----------------+ # 更新新增字段的值 update book set price=60 where id=1; update book set price=30 where id=2; update book set price=70 where id=3; update book set price=40 where id=4; update book set price=80 where id=5; update book set price=40 where id=6; update book set price=50 where id=7; update book set price=80 where id=8; update book set price=30 where id=9; update book set price=40 where id=10;
简单连表查询
# 示例一; # 以内连接的方式查询book和press表,并且book表中的price字段值必须大于50,即找出单价大于50元的书籍以及书籍的出版社名称 select book.name,press.name from book inner join press on book.press_id = press.id where price >50; +--------------+-----------------+ | name | name | +--------------+-----------------+ | 独孤九剑 | 华山出版社 | | 九阳神功 | 少林出版社 | | 易筋经 | 少林出版社 | | 太极拳 | 武当出版社 | +--------------+-----------------+ # 示例二: # 以内连接的方式查询book和press表,并且以price字段的降序方式显示书籍名称、价格和出版社名称。 select book.name,book.price,press.name from book inner join press on book.press_id = press.id order by price desc; +-----------------+-------+-----------------+ | name | price | name | +-----------------+-------+-----------------+ | 太极拳 | 80.00 | 武当出版社 | | 易筋经 | 80.00 | 少林出版社 | | 九阳神功 | 70.00 | 少林出版社 | | 独孤九剑 | 60.00 | 华山出版社 | | 乾坤大挪移 | 50.00 | 明教出版社 | | 九阴真经 | 40.00 | 少林出版社 | | 葵花宝典 | 40.00 | 明教出版社 | | 吸星大法 | 40.00 | 丐帮出版社 | | 天罡北斗阵 | 30.00 | 武当出版社 | | 华山剑法 | 30.00 | 华山出版社 | +-----------------+-------+-----------------+
子查询 (in...)
# 1:子查询是将一个查询语句嵌套在另一个查询语句中。 # 2:内层查询语句的查询结果,可以为外层查询语句提供查询条件。 # 3:子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字 # 4:还可以包含比较运算符:= 、 !=、> 、<等
1.in 或者 = 用法
# 1、查询书籍平均价格在45元以上的出版社的id和名称 #子查询 select id ,name from press where id in (select press_id from book group by press_id having avg(price) > 45); #连表查询 select press.id,press.name from press inner join book on press.id = book.press_id group by book.press_id having avg(book.price) > 45; # 2、查看少林出版社的所有书籍名称 #子查询 select name from book where press_id in (select id from press where name ='少林出版社'); #连表查询 select book.name from book inner join press on book.press_id = press.id where press.name = '少林出版社'; #3.查询出版书籍大于2的出版社名称 #子查询 select name from press where id in (select press_id from book group by press_id having count(press_id) > 2); #连表查询 select press.name from press inner join book on press.id = book.press_id group by book.press_id having count(book.id) > 2;
2.比较运算符 > < != 用法
# 查询书籍价格大于所有书籍平均价格的书名与单价 select name,price from book where price > (select avg(price) from book); # 查询大于出版社里平均价格的书名与单价 select name , price from book as t1 inner join (select press_id,avg(price) avg_price from book group by press_id) as t2 on t1.press_id = t2.press_id where t1.price > t2.avg_price;
3.exists查询
# EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。 # 而是返回一个真假值。True或False # 当返回True时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询 # press表中存在name="少林出版社",Ture mysql> select * from book -> where exists -> (select * from press where name="少林出版社"); # press表中存在name="峨眉出版社",False不进行查询 mysql> select * from book -> where exists -> (select * from press where name="峨眉出版社"); Empty set (0.00 sec)
PyMySQL模块
import pymysql # from pymysql import * # 创建和数据库服务器的连接 connection conn = pymysql.connect( host='localhost', port=3306, user='root', password='root123456', db='students', charset='utf8') # 创建游标对象 cursor = conn.cursor() # 中间可以使用游标完成对数据库的操作 sql = "select * from student;" # 执行sql语句的函数 返回值是该SQL语句影响的行数 count = cursor.execute(sql) print("操作影响的行数%d" % count) # print(cursor.fetchone()) # 返回值类型是元祖,表示一条记录 # 获取本次操作的所有数据 for line in cursor.fetchall(): print("数据是%s" % str(line)) # 关闭资源 先关游标 cursor.close() # 再关连接 conn.close()