数据库语言sql
数据库语言SQL
SQL的形式
交互式SQL
-
一般DBMS都提供联机交互工具
-
用户可直接键入SQL命令对数据库进行操作
-
由DBMS来进行解释
嵌入式SQL
-
能将SQL语句嵌入到高级语言(宿主语言)
-
使应用程序充分利用SQL访问数据库的能力、宿主语言的过程处理能力
-
一般需要预编译,将嵌入的SQL语句转化为宿主语言编译器能处理的语句
SQL语言主要组成部分
数据定义语言(DDL,Data Definition Language)
-
数据定义语言是指用来定义和管理数据库以及数据库中的各种对象的语句,这些语句包括CREATE、ALTER和DROP等语句。在SQL Server中,数据库对象包括表、视图、触发器、存储过程、规则、缺省、用户自定义的数据类型等。这些对象的创建、修改和删除等都可以通过使用CREATE、ALTER、DROP等语句来完成。
-
常见的数据类型
-
字符型:
-
定长字符型 char(n) 由于是定长,所以速度快
-
变长字符型 varchar(n)
-
数值型:
-
整型 int(或integer) -231~+231
-
短整型 smallint -215~+215的
-
浮点型 real、float、double
-
数值型 numeric (p [,d])
-
日期/时间型:
-
DateTime
-
文本和图像型
-
Text:存放大量文本数据。在SQLServer中,Text对象实际为一指针
-
Image:存放图形数据
SQL语句
--sql语句的注意 : 1 以;作为结束符 2 不区分大小写
--mysql 数据库的操作
-- 链接数据库
mysql -uroot -pmysql
-- 不显示密码
mysql -uroot -p
mysql
-- 退出数据库
exit/quit/ctrl + d
-- sql语句最后需要有分号;结尾
-- 显示数据库版本 version
select version();
-- 显示时间
select now();
-- 查看当前使用的数据库
select database();
-- 查看所有数据库
show databases;
-- 创建数据库
-- create database 数据库名 charset=utf8;
create database python01; # 可能会出现乱码
create database python01 charset=utf8;
-- 查看创建数据库的语句
-- show create database ....
show create database python01;
-- 使用数据库
-- use 数据库的名字
use python01;
-- 删除数据库
-- drop database 数据库名;
drop database python01;
--02 数据表的操作
-- 查看当前数据库中所有表
show tables;
-- 创建表
-- int unsigned 无符号整形
-- auto_increment 表示自动增长
-- not null 表示不能为空
-- primary key 表示主键 数据库主键,指的是一个列或多列的组合,
-- 其值能唯一地标识表中的每一行,通过它可强制表的实体完整性。
-- 主键主要是用于其他表的外键关联,以及本记录的修改与删除。
-- default 默认值
-- create table 数据表名字 (字段 类型 约束[, 字段 类型 约束]);
create table xxx(
id int unsigned primary key not null auto_increment,
name varchar(20) not null
);
-- 查看表结构
-- desc 数据表的名字;
desc xxx;
-- 创建 classes 表(id、name)
-- varchar表示可变长度的字符串
--
create table classes(
id int unsigned primary key auto_increment not null,
name varchar(20) not null
);
-- 创建 students 表(id、name、age、high (decimal)、gender (enum)、cls_id)
-- decimal表示浮点数,如decimal(5,2)表示共存5位数,小数占2位,例如:185.88
-- 枚举类型(enum) 例如:enum("男性","女性","中性","保密")
create table students(
id int unsigned primary key auto_increment not null,
name varchar(20) not null,
age int unsigned,
high decimal(5,2),
gender enum("男性","女性","中性","保密") default "保密",
cls_id int unsigned
);
-- 查看表的创建语句
-- show create table 表名字;
show create table xxx;
-- 修改表-添加字段 mascot (吉祥物)
-- alter table 表名 add 列名 类型;
alter table classes add chongwu varchar(20) default"蛇";
-- 修改表-修改字段:不重命名版
-- alter table 表名 modify 列名 类型及约束;
alter table classes modify mascot varchar(30) default"葫芦娃";
-- 修改表-修改字段:重命名版
-- alter table 表名 change 原名 新名 类型及约束;
alter table classes change chongwu mascot varchar(20) default"法拉利";
-- 修改表-删除字段
-- alter table 表名 drop 列名;
alter table classes drop mascot;
-- 删除表
-- drop table 表名;
-- drop database 数据库;
--03 增删改查(curd)
-- 增加
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(20) | NO | | NULL | |
+-------+------------------+------+-----+---------+----------------+
-- 全列插入
-- insert [into] 表名 values(...)
-- 主键字段 可以用 0 null default 来占位
-- 向classes表中插入 一个班级
insert into classes values(1,"python大神班");
+--------+-------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------------------------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(20) | NO | | NULL | |
| age | int(10) unsigned | YES | | NULL | |
| high | decimal(5,2) | YES | | NULL | |
| gender | enum('男性','女性','中性','保密') | YES | | 保密 | |
| cls_id | int(10) unsigned | YES | | NULL | |
+--------+-------------------------------------------+------+-----+---------+------------
-- 向students表插入 一个学生信息
insert into students values(1,"班主任",18,166.66,2,111);
insert into students values(0,"吴彦祖",42,188.88,1,222);
insert into students values(null,"晨哥",28,188.88,1,333);
-- 部分插入
-- insert into 表名(列1,...) values(值1,...)
insert into students(name) values("老王");
-- 多行插入
insert into students values(null,"老李",28,188.88,1,333),(null,"赵四",28,188.88,1,333);
-- 修改
-- update 表名 set 列1=值1,列2=值2... where 条件;
-- 全部修改
update students set high = 170.00;
-- 按条件修改
update students set high = 170.00 where id=3;
-- 按条件修改多个值
-- update students set gender ="",name = "xxx" ;
update students set gender="中性",name="111" where id=3;
-- 查询基本使用
-- 查询所有列
-- select * from 表名;
select * from students;
---定条件查询
select * from students where id=1;
-- 查询指定列
-- select 列1,列2,... from 表名;
select name,gender from students;
-- 可以使用as为列或表指定别名
-- select 字段[as 别名] , 字段[as 别名] from 数据表;
select name as "姓名",gender as "性别" from students;
-- 字段的顺序
select gender as "性别",name as "姓名" from students;
-- 删除
-- 物理删除
-- delete from 表名 where 条件
delete from students where id=3;
-- 逻辑删除
-- 用一个字段来表示 这条信息是否已经不能再使用了
-- 给students表添加一个 is_delete 字段 bit 类型
alter table students add is_delete bit default 0;
update students set is_delete=1 where id = 1;
-- 数据库备份与恢复
mysqldump –uroot –p 数据库名 > python.sql;
mysql -uroot –p 新数据库名 < python.sql;
视 图 (VIEW)
演示(详见PPT41)
--创建
create view 视图名称 as select语句;
--查看
show tables;
--使用
select * from 视图名称;
--删除视图
drop view 视图名称;
--修改视图
create or replace view test4 as select t1.name as tname,t2.\* from test as t1 LEFT JOIN test1 as t2 on t1.pid = t2.id;
方便操作,特别是查询操作,减少复杂的SQL语句,增强可读性;
提高了重用性,就像一个函数
对数据库重构,却不影响程序的运行
提高了安全性能,可以对不同的用户
让数据更加清晰
数据查询(Select)
数据查询是数据库应用的核心功能
-- 查询所有字段
-- select * from 表名;
select * from students;
-- 查询指定字段
-- select 列1,列2,... from 表名;
select name,gender from students;
-- 使用 as 给字段起别名
-- select 字段 as 名字.... from 表名;
select name as "姓名",gender as "性别" from students;
-- select 表名.字段 .... from 表名;
select name as "姓名",gender as "性别" from students as s;
-- 可以通过 as 给表起别名
-- select 别名.字段 .... from 表名 as 别名;
select s.name as "姓名",s.gender as "性别" from students as s;
失败的select students.name, students.age from students as s;
-- 消除重复行(查性别)
-- distinct 字段
select gender from students;
select distinct gender from students;
-- 条件查询
-- 比较运算符
-- select .... from 表名 where .....
-- >
-- 查询大于18岁的信息
select * from students where age > 18;
-- <
-- 查询小于18岁的信息
select * from students where age < 18;
-- >=
-- <=
-- 查询小于或者等于18岁的信息
select * from students where age <= 18;
-- =
-- 查询年龄为18岁的所有学生的名字
(区别)select * from students where age = 18;
-- != 或者 <>
select * from students where age != 18;
-- 逻辑运算符
-- and
-- 18和28之间的所以学生信息
select * from students where age >=18 and age <=28;
失败 select * from students where age>18 and <28;
-- 18岁以上的女性
select * from students where age > 18 and gender = 2;
-- or
-- 18以上或者身高高过180(包含)以上
select * from students where age > 18 or height >= 180;
-- not
-- 不在 18岁以上的女性 这个范围内的信息
-- select * from students where not age>18 and gender=2;
select * from students where not (age > 18 and gender = 2);
-- 模糊查询(where name like 要查询的数据)
-- like
-- % 替换任意个
-- _ 替换1个
-- 查询姓名中 以 "小" 开始的名字
select * from students where name like "小%";
-- 查询姓名中 有 "小" 所有的名字
select * from students where name like "%小%";
-- 查询有2个字的名字
select * from students where name like "__";
-- 查询有3个字的名字
select * from students where name like "___";
-- 查询至少有2个字的名字
select * from students where name like "__%";
-- 范围查询
-- in (1, 3, 8)表示在一个非连续的范围内
-- 查询 年龄为18、34的姓名
select * from students where age =18 or age = 34;
select * from students where age in (18,34);
-- not in 不非连续的范围之内
-- 年龄不是 18、34岁之间的信息
select * from students where age not in (18,34);
(注意)select name from students where not age in (18,34);
-- between ... and ...表示在一个连续的范围内
-- 查询 年龄在18到34之间的的信息
select * from students where age between 18 and 34;
-- not between ... and ...表示不在一个连续的范围内
-- 查询 年龄不在在18到34之间的的信息
select * from students where age not between 18 and 34;
失败的select * from students where age not (between 18 and 34);
-- 空判断
-- 判空is null
-- 查询身高为空的信息
select * from students where height is null;
-- 判非空is not null
select * from students where height is not null;
失败select * from students where height not is null;
-- 排序
-- order by 字段
-- asc从小到大排列,即升序
-- desc从大到小排序,即降序
-- 查询年龄在18到34岁之间的男性,按照年龄从小到大到排序
select * from students where (age between 18 and 34) and gender = 1 order by age asc;
-- 查询年龄在18到34岁之间的女性,身高从高到矮排序
select * from students where (age between 18 and 34) and gender = 2 order by height desc;
-- order by 多个字段
-- 查询年龄在18到34岁之间的女性,身高从高到矮排序, 如果身高相同的情况下按照年龄从小到大排序
select * from students where (age between 18 and 34) and gender = 2 order by height desc,age asc;
-- 查询年龄在18到34岁之间的女性,身高从高到矮排序, 如果身高相同的情况下按照年龄从小到大排序,
-- 如果年龄也相同那么按照id从大到小排序
select * from students where (age between 18 and 34) and gender = 2 order by height desc,age asc,id desc;
-- 聚合函数
-- 总数
-- count
-- 查询男性有多少人,女性有多少人
select count(*) from students where gender = 1;
select count(*) from students where gender = 2;
-- 最大值
-- max
-- 查询最大的年龄
select max(age) from students;
-- 查询女性的最高 身高
select max(height) from students where gender = 2;
-- 最小值
-- min
select min(height) from students where gender = 2;
-- 求和
-- sum
-- 计算所有人的年龄总和
select sum(age) from students;
-- 平均值
-- avg
-- 计算平均年龄
select avg(age) from students;
-- 计算平均年龄 sum(age)/count(*)
-- 四舍五入 round(123.23 , 1) 保留1位小数
-- 计算所有人的平均年龄,保留3位小数
select round(avg(age),3) from students;
-- 计算男性的平均身高 保留2位小数
select round(avg(height),2) from students where gender = 1;
-- 分组
-- group by
-- 按照性别分组,查询所有的性别
select gender from students group by gender;
-- select name,gender from students group by gender;
-- 失败select * from students group by gender;
select * from students group by gender;
-- 计算每种性别中的人数
select count(*),gender from students group by gender;
-- group_concat(...)
-- 查询同种性别中的姓名
select group_concat(name),gender from students group by gender;
-- 查询每组性别的平均年龄
select avg(age),gender from students group by gender;
-- having(注意having和group by)
(!)-- 查询平均年龄超过30岁的性别,以及姓名 having avg(age) > 30
select gender,group_concat(name) from students
group by gender
having avg(age) > 30;
-- 查询每种性别中的人数多于2个的信息
select gender,group_concat(name) from students group by gender having count(*) > 2;
-- with rollup 汇总的作用(了解)
select gender,count(*) from students group by gender with rollup;
-- 分页
-- limit start, count
-- 限制查询出来的数据个数
-- 查询前5个数据
select * from students limit 5;
-- 每页显示2个,第1个页面
select * from students limit 0,2;
-- 每页显示2个,第2个页面
select * from students limit 2,2;
-- 每页显示2个,第3个页面
select * from students limit 4,2;
-- 每页显示2个,第4个页面
select * from students limit 6,2;
-- 每页显示2个,显示第6页的信息, 按照年龄从小到大排序(limit 必须写到sql语句的最后)
错误1 select * from students limit 10,2 order by age asc;
-- 工作错误的写法
错误2 select * from students limit 2*(6-1),2;
-- limit 放在最后面(注意)
-- 连接查询
-- inner join ... on
-- select ... from 表A inner join 表B;
select * from students inner join classes;
-- 查询 有能够对应班级的学生以及班级信息
select * from students inner join classes on students.cls_id = classes.id;
-- 按照要求显示姓名、班级
select students.name,classes.name from students inner join classes on students.cls_id = classes.id;
-- 给数据表起名字
select s.name,c.name from students as s inner join classes as c on s.cls_id = c.id;
-- 查询 有能够对应班级的学生以及班级信息,显示学生的所有信息 students.*,只显示班级名称 classes.name.
select s.*,c.name from students as s inner join classes as c on s.cls_id = c.id;
-- 在以上的查询中,将班级姓名显示在第1列
select c.name,s.* from students as s inner join classes as c on s.cls_id = c.id;
-- 查询 有能够对应班级的学生以及班级信息, 按照班级进行排序
-- select c.xxx s.xxx from students as s inner join clssses as c on .... order by ....;
select c.name,s.* from students as s inner join classes as c on s.cls_id = c.id order by c.name;
-- 当时同一个班级的时候,按照学生的id进行从小到大排序
select c.name,s.* from students as s inner join classes as c on s.cls_id = c.id order by c.name,id asc;
-- left join
-- 查询每位学生对应的班级信息
select * from students left join classes on students.cls_id = classes.id;
-- select * from students right join classes on students.cls_id = classes.id;
-- 查询没有对应班级信息的学生
-- select ... from xxx as s left join xxx as c on..... where .....
-- select ... from xxx as s left join xxx as c on..... having .....
select * from students left join classes on students.cls_id = classes.id where classes.name is null;
(注意)不建议使用 select * from students left join classes on students.cls_id=classes.id having classes.id is null;
-- right join on
-- 将数据表名字互换位置,用left join完成
-- 子查询
-- 标量子查询: 子查询返回的结果是一个数据(一行一列)
-- 列子查询: 返回的结果是一列(一列多行)
-- 行子查询: 返回的结果是一行(一行多列)
-- 查询出高于平均身高的信息(height)
-- 1 查出平均身高
select avg(height) from students ; -- 172
-- 2 查出高于平均身高的信息
select * from students where height >(select avg(height) from students) ;
-- 查询学生的班级号能够对应的 学生名字
-- select name from students where cls_id in (select id from classes);
-- 1 查出所有的班级id
select id from classes; -- 1,2
-- 2 查出能够对应上班级号的学生信息
select * from students where cls_id in (select id from classes);
Where 子句
查询满足指定条件的元组可以通过Where子句来实现
使where子句中的逻辑表达式返回True值的元组,是符合要求的元组,将被选择出来
-
Where 子句——运算符
比较:<、<=、>、>=、=、<> 等
-
确定范围:Between A and B、Not Between A and B
-
确定集合:IN、NOT IN
-
字符匹配:LIKE,NOT LIKE
-
空值:IS NULL、IS NOT NULL
-
多重条件:AND、OR、NOT
-
Where 子句——Like
-
字符匹配:Like、Not Like
-
通配符
- % —— 匹配任意字符串
- _ —— 匹配任意一个字符
-
大小写敏感
-
Where 子句——转义符 escape
From 子句
列出将被查询的关系(表)
-
From 子句——元组变量
-
为 From 子句中的关系定义元组变量
-
方便关系名的引用
-
连接子句
-
内连接 内连接是指包括符合条件的每个表的记录,也称之为全记录操作。
-
外连接 外连接是指把两个表分为左右两个表。右外连接是指连接满足条件右侧表的全部记录。左外连接是指连接满足条件左侧表的全部记录。全外连接是指连接满足条件表的全部记录。
-
左外连接
-
右外连接
-
全外连接
Order By子句
-
指定结果集中元组的排列次序
-
耗时
-
ASC升序(缺省)、DESC降序
子查询(Subquery )
子查询是嵌套在另一查询中的 Select-From-Where 表达式(Where/Having)
SQL允许多层嵌套,由内而外地进行分析,子查询的结果作为父查询的查找条件
可以用多个简单查询来构成复杂查询,以增强SQL的查询能力
子查询中不使用 Order By 子句,Order By子句只能对最终查询结果进行排序
-
子查询——单值比较
- 返回单值的子查询,只返回一行一列
- 父查询与单值子查询之间用比较运算符进行连接
- 运算符:>、>=、=、<=、<、 <>
-
子查询——多值
- 子查询返回多行一列
- 运算符:In、All、Some(或Any)、Exists
- 子查询——多值成员In
- 若值与子查询返回集中的某一个相等,则返回true
- IN 被用来测试多值中的成员
- 子查询——多值比较 ALL
- 父查询与多值子查询之间的比较用All来连接
- 值s比子查询返回集R中的每个都大时,s>All R 为True
- All表示所有
- <> all 等价于 not in
- 子查询——多值比较Some/Any
- 父查询与多值子查询之间的比较需用Some/Any来连接
- 值s比子查询返回集R中的某一个都大时返回 Ture
- s > Some R为True 或
- s > Any R为True
- Some(早期用Any)表示某一个(任意一个)
- = some 等价于 in、<> some 不等价于 not in
- 子查询——存在判断Exists
- Exists + 子查询用来判断该子查询是否返回元组
- 当子查询的结果集非空时,Exists为True
- 当子查询的结果集为空时,Exists为False
- 不关心子查询的具体内容,因此用 Select *
-
具有外部引用的子查询,称为相关子查询(Correlated Queries)
-
外层元组的属性作为内层子查询的条件
聚合函数
把一列中的值进行聚合运算,返回单值的函数
-
五个预定义的聚合函数
-
平均值:Avg( )
-
总和: Sum( )
-
最小值:Min( )
-
最大值:Max( )
-
计数: Count( ) 返回所选列中不为NULL的数
-
-
Group By 将查询结果集按某一列或多列的值分组,值相等的为一组,一个分组以一个元组的形式出现,只有出现在Group By子句中的属性,才可出现在Select子句中
-
Having 针对聚合函数的结果值进行筛选(选择),它作用于分组计算结果集,跟在Group By子句的后面。
-
Having 与 Where的区别
-
Where 决定哪些元组被选择参加运算,作用于关系中的元组
-
Having 决定哪些分组符合要求,作用于分组
-
聚合函数的条件关系必须用Having,Where中不应出现聚合函数
-
-
-
聚合函数对Null的处理
-
Count:不计
-
Sum:不将其计入
-
Avg:具有 Null 的元组不参与
-
Max / Min:不参与
-
索引
数据库中的索引与书籍中的索引类似,在一本书中,利用索引可以快速查找所需信息,无须阅读整本书。在数据库中,索引使数据库程序无须对整个表进行扫描,就可以在其中找到所需数据。书中的索引是一个词语列表,其中注明了包含各个词的页码。而数据库中的索引是某个表中一列或者若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单
索引的作用
-
通过创建唯一索引,可以保证数据记录的唯一性。
-
可以大大加快数据检索速度。
-
可以加速表与表之间的连接,这一点在实现数据的参照完整性方面有特别的意义。
-
在使用ORDER BY和GROUP BY子句中进行检索数据时,可以显著减少查询中分组和排序的时间。
-
使用索引可以在检索数据的过程中使用优化隐藏器,提高系统性能
聚集索引与非聚集索引
-
聚集索引对表的物理数据页中的数据按列进行排序,然后再重新存储到磁盘上,即聚集索引与数据是混为一体的,它的叶节点中存储的是实际的数据
-
非聚集索引具有完全独立于数据行的结构,使用非聚集索引不用将物理数据页中的数据按列排序。非聚集索引的叶节点存储了组成非聚集索引的关键字值和行定位器
创建索引
约束
主键约束(primary key constraint)
唯一性约束(unique constraint)
检查约束(check constraint)
缺省约束(default constraint)
外部键约束(foreign key constraint)
-- sql强化演练( goods 表练习)
-- 查询类型 cate_name 为 '超级本' 的商品名称 name 、价格 price ( where )
select name,price from goods where cate_name = "超级本";
-- 显示商品的种类
-- 1 分组的方式( group by )
select cate_name from goods group by cate_name;
-- 2 去重的方法( distinct )
select distinct cate_name from goods;
-- 求所有电脑产品的平均价格 avg ,并且保留两位小数( round )
select round(avg(price),2) from goods;
-- 显示 每种类型 cate_name (由此可知需要分组)的 平均价格
select cate_name,avg(price) from goods group by cate_name;
-- 查询 每种类型 的商品中 最贵 max 、最便宜 min 、平均价 avg 、数量 count
select max(price),min(price),avg(price),count(*) from goods group by cate_name;
-- 查询所有价格大于 平均价格 的商品,并且按 价格降序 排序 order desc
-- 1 查询平局价格(avg_price)
select avg(price) as avg_price from goods;
-- 2 使用子查询
select * from goods where price > (select avg(price) as avg_price from goods) order by price desc;
-- 查询每种类型中最贵的电脑信息(难)
-- 1 查找 每种类型 中 最贵的 max_price 价格
select cate_name,max(price) as max_price from goods group by cate_name;
-- 2 关联查询 inner join 每种类型 中最贵的物品信息
-- select * from goods
-- inner join
-- (select cate_name,max(price) as max_price from goods group by cate_name) as max_price_goods
-- on goods.cate_name=max_price_goods.cate_name and goods.price=max_price_goods.max_price;
select * from goods
inner join
(select cate_name,max(price) as max_price from goods group by cate_name) as max_price_goods
on goods.cate_name = max_price_goods.cate_name and goods.price = max_price_goods.max_price;
-- 创建"商品分类"表
第一步 创建表 (商品种类表 goods_cates )
create table if not exists goods_cates(
id int unsigned primary key auto_increment,
name varchar(40) not null
);
第二步 同步 商品分类表 数据 将商品的所有 (种类信息) 写入到 (商品种类表) 中
-- 按照 分组 的方式查询 goods 表中的所有 种类(cate_name)
select cate_name from goods group by cate_name;
-- (注意) 把查询出来的 结果 写入 goods_cates 表里去 ( insert into ) 只插入name
insert into goods_cates(name) (select cate_name from goods group by cate_name);
第三部 同步 商品表 数据 通过 goods_cates 数据表来更新 goods 表
-- 因为要通过 goods_cates表 更新 goods 表 所以要把两个表连接起来
select * from goods inner join goods_cates on goods.cate_name = goods_cates.name;
-- 把 商品表 goods 中的 cate_name 全部替换成 商品分类表中的 商品id ( update ... set )
update (goods inner join goods_cates on goods.cate_name = goods_cates.name) set goods.cate_name = goods_cates.id;
第四部 修改表结构
-- 查看表结构(注意 两个表中的 外键类型需要一致)
desc goods;
-- 修改表结构 alter table 字段名字不同 change,把 cate_name 改成 cate_id int unsigned not null
alter table goods change cate_name cate_id int unsigned not null;
-- 创建 商品品牌表 goods_brands
第一步 创建 "商品品牌表" 表
-- 第一种方式 先创建表
create table goods_brands (
id int unsigned primary key auto_increment,
name varchar(40) not null);
-- 插入数据 brand_name(分组)
-- 按照 分组 的方式查询 goods 表中的所有 种类(brand_name)
select brand_name from goods group by brand_name;
--(注意) 把查询出来的 结果 写入 goods_brands 表里去 ( insert into ) 只插入name
insert into goods_brands(name) (select brand_name from goods group by brand_name);
-- 第二种方式 创建表的同时插入数据(了解,不建议使用)
create table goods_brands (
id int unsigned primary key auto_increment,
name varchar(40) not null) select brand_name as name from goods group by brand_name;
第二步 同步数据
-- 通过goods_brands数据表来更新goods数据表 g.brand_name=b.id
update (goods inner join goods_brands on goods.brand_name = goods_brands.name) set goods.brand_name = goods_brands.id;
第三部 修改表结构
-- 通过alter table语句修改表结构 brand_id int unsigned not null
alter table goods change brand_name brand_id int unsigned not null;
-- 外键的使用(了解)
-- 向goods表里插入任意一条数据
insert into goods (name,cate_id,brand_id,price) values('老王牌拖拉机', 10, 10,'6666');
-- 约束 数据的插入 使用 外键 foreign key
-- alter table goods add foreign key (brand_id) references goods_brands(id);
alter table goods add foreign key (cate_id) references goods_cates(id);
alter table goods add foreign key(brand_id) references goods_brands(id);
-- 失败原因 老王牌拖拉机 delete
-- delete from goods where name="老王牌拖拉机";
delete from goods where name="老王牌拖拉机";
-- 创建表的同时设置外键 (注意 goods_cates 和 goods_brands 两个表必须事先存在)
create table goods(
id int primary key auto_increment not null,
name varchar(40) default '',
price decimal(5,2),
cate_id int unsigned,
brand_id int unsigned,
is_show bit default 1,
is_saleoff bit default 0,
foreign key(cate_id) references goods_cates(id),
foreign key(brand_id) references goods_brands(id)
);
-- 如何取消外键约束
-- 需要先获取外键约束名称,该名称系统会自动生成,可以通过查看表创建语句来获取名称
show create table goods;
-- 获取名称之后就可以根据名称来删除外键约束
alter table goods drop foreign key goods_ibfk_1;
alter table goods drop foreign key goods_ibfk_2;
总结:在实际开发中,很少会使用到外键约束,会极大的降低表更新的效率
-- sql注入 ' or 1 or '
select * from goods where name = '%s' % name
select * from goods ;
使用navicat对表(结构及数据)的导入及导出
导出
右键原表/转储sql文件-结构和数据
导入
右键表/运行sql文件
外连接 python连接
# python与mysql的交互使用
# 基本流程 1 connection对象 |2 cursor对象 |3 关闭cursor |4 关闭connection
from pymysql import connect
# 创建Connection连接
conn = connect(host='localhost',port=3306,database='jing_dong',user='root',password='1234',charset='utf8')
def main():
# 获得Cursor对象
cursor = conn.cursor()
# 插入10万次数据
for i in range(100000):
cursor.execute("insert into test_index values('ha-%d')" % i)
# 提交数据
conn.commit()
if __name__ == "__main__":
main()
小练习
use test1907
show TABLES
alter database test1907 CHARACTER set gbk
drop database test1907
create table goods(
name VARCHAR(20)UNIQUE,
price VARCHAR(30),
number VARCHAR(20),
user_name VARCHAR(20)
)
CREATE TABLE class(
id INT UNSIGNED auto_increment not null PRIMARY KEY,
NAME VARCHAR(20)
);
create table students(
id INT unsigned auto_increment not null primary key,
name varchar(20) not null,
age int unsigned,
high decimal(5,2),
gender enum('男','女') default '男',
cls_id int unsigned)
alter table students add add_time TIMESTAMP
insert into class VALUES(1,'第7班')
insert into students VALUES(1,'gd',18,180.00,NULL,1,NULL)
insert into students VALUES(2,'zly',28,180.00,'男',1,NULL)
SELECT * FROM students
desc goods
show create table goods
ALTER table goods add user_id int
ALTER table goods add user_names VARCHAR(20)
ALTER table goods DROP user_names
insert into goods(name,price,number,user_name,user_id)values('lcs',66,3,'lsclsc',1)
insert into goods(name,price,number,user_name,user_id)values('lll',55,2,'llll',3),
('sss',44,4,'ssssss',2)
insert into goods(name,price,number,user_name,user_id)values('ccc',656,31,'lsclwsc',7)
UPDATE goods set name='ooo'WHERE user_id=1
DELETE from goods WHERE user_name='lsclwsc'
create table goods(
name VARCHAR(20)UNIQUE,
price VARCHAR(30) not NULL,
xingb VARCHAR(3) DEFAULT('nan')
)
select * from goods
select name from goods
select name from goods WHERE price >44
CREATE database books charset = 'utf8'
use books
CREATE table book(
id int PRIMARY key auto_increment,
book_name varchar(20),
price float(5,2),
auth varchar(20),
publish varchar(20)
)
insert into book VALUES(1,'北平无故事',25,'刘和平','作家出版社'),
(2,'人间失格',16,'太宰治著','作家出版社'),
(3,'高兴',16,'贾平凹','人民出版社'),
(4,'源氏物语',57,'刘和平','人民出版社'),
(5,'卡夫卡文集',9,'卡夫卡','邮电出版社'),
(6,'大家',12,'王蒙','邮电出版社'),
(7,'拉片子',37,'杨健','清华出版社'),
(8,'古代散文',5,'归有光','安徽出版社'),
(9,'百花散文',6,'孙虹选','百花文艺出版社'),
(10,'方令孺散文集',5,'方令孺','安徽文艺')
--asc 从低向高
select * from book order by price desc
select * from book where publish = '作家出版社' ORDER BY price DESC
select * from book where auth = '刘和平'
DELETE from book where id = 2
UPDATE book SET price = 10 where price < 10
select * from book where price = 10
SELECT price from book order by price asc
select * from book where price < 20
update book set price=price*1.2
CREATE DATABASE db_test charset='utf8'
use db_test
CREATE table staff (
sid int PRIMARY key auto_increment,
sname varchar(20),
sex enum('男','女'),
job VARCHAR(20),
brithday datetime,
salary int(10),
comm int(10),
withhold int(10)
)
insert into staff VALUES
(1001,'张三','男','高级程师','1975-1-1',2200,1100,200),
(1002,'李四','女','助工','1985-1-1',1200,200,100),
(1003,'王五','男','工程师','1978-11-11',1900,700,200),
(1004,'赵六','男','工程师','1979-1-1',1960,700,150)
rename table staff to emp
ALTER table emp add hobby varchar(50) UNIQUE
insert into emp VALUES(1005,'晓七','女','高级程师','1975-1-1',2200,1100,200,'足球');
SELECT * from emp where sid in (1002,1003,1005);
update emp set job='架构师' where job='高级程师';
DELETE from emp where sid = 1003 and sname='王五';
UPDATE emp set salary = salary-300 where sid = 1004;
1.课程表
Course
课程号
课程名称
教师编号
2.成绩表
Score
学号
课程号
成绩
3.教师表
Tcacher
教师编号
教师名字
教师性别
出生年月日
职称
所在班级
4.学生表
student
学号
姓名
性别
出生年月日期
所在班级
create table student(
sno varchar(20) primary key,
sname varchar(10) no null,
ssex varchar(10) not null,
sbirthday datetime,
class varchar(20)
);
create table course(
cno varchar(20),
cname varchar(20) not null,
tno varchar(20) not null,
foreign key(tno) references teacher(tno)
);
create table teacher(
tno varchar(20) primary key,
tname varchar(20) not null,
tsex varchar(20) not null,
tbirthday datetime,
pro varchar(20) not null,
depart varchar(20) not null
);
create table score(
sno varchar(20) not null,
cno varchar(20) not null,
degree decimal,
foreign key(sno) references student(sno),
foreign key(cno) references course(cno),
primary key(sno, cno)
);
select * from student;
写入数据
insert into student values('108','曾华','男','1977-09-01','95033');
--修改编码
alter database 1907test character set="utf-8"
1,查询student表中的所有记录
-- select * from student;
2,检查student表中的所有记录的sname,Ssex和class。
--select sname,ssex,class from student
3、查询老师所有的单位即不重复的depart列
-- select distinct depart from teacher;
4.查询socre表中成绩在从68到80之间的记录。
-- select * from score where degree between 60 and 80;
5.查询score表成绩中为85、86或88。-
-- select * from score where degree in(85,86,88);
6、查询student表中“95031”班或性别为“女”同学的同学记录
-- select * from student where class="95031" or ssex="女";
7.以class降序查询student表的所有记录
-- select * from student order by class desc;#asc
8.以cno升序。degree降序查询score表的所有记录
-- select *from score order by cno asc,degree desc;
9、查询“95031”班学生人数。
-- select count(*) from student where class="95031"
10、查询score表中的最高分的学生学号和课程号(子查询或者排序)
-- select sno,cno from score where degree=(select max(degree) from score);
-- select sno,cno from score order by degree desc limit 0,1;
-- 11.查看每门课的平均成绩 (分组查询)
-- select cno,avg(degree) from score group by cno;
-- 12.查询score表中至少有2名同学选修的并以3开头的课程的平均分数 havimg(组级过滤)
-- select cno,avg(degree),count(*)
-- from score
-- group by cno
-- having count(cno)>=2 and cno like '3%';
-- 13.查询分数大于70,小于90的sno列(条件查询)
-- select sno,degree from score where degree>70 and degree<90;
-- select sno,degree from score where degree between 70 and 90;
-- 14.查询所有学生的 sname,con,和degree 列。(多表查询)
-- select sno,sname from student;
-- select cno,degree from score;
-- select sname,cno,degree from student,score
-- where student.sno=score.sno;
-- 15.查询所有学生的sno,cname和degree
-- select cno,cname from course;
-- select cno,sno,degree from score;
-- select sno,cname,degree from course,score where course.cno = score.cno;