数据存储
json
XML:
json是轻量级的数据交互格式
XML是重量级的数据交互格式
HTML:
给用户看的 展示数据的
数据交互格式:
简单理解就是一个字典或者list
书写格式:
1.不能写注释
2.key:Value(必须都是双引号)
3.末尾不能写逗号
4.整个文件有且仅有一个{}或者[]
模块操作
字符串 : loads,dumps
文件对象 : load, dump
import json
# 1.字符串和dic list转换
# 字符串(json)----dic list
data = '[{"name":"张三","age":20},{"name":"李四","age":18}]'
list_data = json.loads(data)
# dic list----字符串(json)
list2 = [{"name": "张三", "age": 20}, {"name": "李四", "age": 18}]
data_json = json.dumps(list2)
# 2.文件对象和dic list转换
# dict list 写入文件
list3 = [{"name": "张三", "age": 20}, {"name": "李四", "age": 18}]
json.dump(list3, open('04json.json', 'w'))
# 读取文件json-----list dict
result = json.load(open('04json.json', 'r'))
print(result)
CSV
writer(fp) :
writer = csv.writer(csv_fp)
表头:
writer.writerow(sheet_title)
内容:
writer.writerows(sheet_data)
import json
import csv
# 需求 json中的数据转换成 csv 文件
# 1.分别读,创建文件
json_fp = open('04json.json', 'r')
csv_fp = open('03csv.csv', 'w')
# 2.提出表头,表内容
data_list = json.load(json_fp)
sheet_data = []
sheet_title = data_list[0].keys()
for data in data_list:
sheet_data.append(data.values())
# 3.csv 写入器
writer = csv.writer(csv_fp)
# 4.写入表头
writer.writerow(sheet_title)
# 5.写入内容
writer.writerows(sheet_data)
# 6.关闭两个文件
json_fp.close()
csv_fp.close()
mongDB
安装
MongoDB简介
MongoDB是一个基于分布式文件存储的数据库,由C++语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB将数据存储为一个文档,数据结构由键值(key=>value)对组成,MongoDB文档类似于JSON对象,字段值可以包含其他文档,数组及文档数组。
MongoDB服务端可运行在Linux、Windows或mac os x平台,支持32位和64位应用,默认端口为27017。
MongoDB支持各种编程语言: Python,Java,C++,PHP,C#等多种语言。
下载MongoDB
安装MongoDB
双击打开文件进行安装,在安装过程中,可以通过点击 "Custom(自定义)" 按钮来设置你的安装目录。
这里我选择安装在E:\MongoDB这个目录下(安装目录会影响我们后面的配置)。
这里选择直接next:
这里安装 "Install MongoDB Compass" 不勾选,否则可能要很长时间都一直在执行安装,MongoDB Compass是一个图形界面管理工具,这里不安装也是没有问题的,可以自己去下载一个图形界面管理工具,比如Robo3T。
之后稍微等待一会就安装好了。
配置MongoDB
MongoDB的安装过程是很简单的,但是配置就比较麻烦了,可能会遇到各种各样的问题,需要你有足够的耐心和仔细。
首先要在MongoDB的data文件夹里新建一个db文件夹和一个log文件夹:
!
然后在log文件夹下新建一个mongo.log:
然后将E:\MongoDB\bin添加到环境变量path中,此时打开cmd窗口运行一下mongo命令,出现如下情况:
这是为什么呢?这是因为我们还没有启动MongoDB服务,自然也就连接不上服务了。那要怎么启动呢?在cmd窗口中运行如下命令:
mongod --dbpath E:\MongoDB\data\db
需要注意的是:如果你没有提前创建db文件夹,是无法启动成功的。运行成功之后,我们打开浏览器,输入127.0.0.1:27017,看到如下图,就说明MongoDB服务已经成功启动了。
但是如果每次都要这么启动服务的话也太麻烦了吧,这里你可以选择设置成开机自启动,也可以选择用命令net start mongodb来手动启动,这里我选择使用后者,具体方法如下。
还是打开cmd窗口,不过这次是以管理员身份运行,然后输入如下命令:
mongod --dbpath "E:\MongoDB\data\db" --logpath "E:\MongoDB\data\log\mongo.log" -install -serviceName "MongoDB"
如果没有报错的话就说明成功添加到服务里了,可以使用win+R然后输入services.msc命令进行查看:
默认是自动运行的,这里我选择把它改成手动的。然后在cmd窗口中运行net start mongodb:
怎么解决呢?两个步骤:
1)运行sc delete mongodb删除服务;
2)再运行一次配置服务的命令:
mongod --dbpath "E:\MongoDB\data\db" --logpath "E:\MongoDB\data\log\mongo.log" -install -serviceName "MongoDB"
然后再运行net start mongodb,服务启动成功:
可能遇到的问题
1.mongod不是内部或外部命令
出现这种问题说明你没有把bin目录添加到环境变量之中,重新添加一下即可解决。
2.服务名无效
首先是看你输入的服务名称是否有误,然后再查看本地服务中有没有MongoDB服务,如果没有服务,则运行命令添加服务即可。
3.发生服务特定错误:100
删除db文件夹下的mongod.lock和storage.bson两个文件,若删除完之后仍然出现这种问题,用sc delete mongodb删除服务,再配置一下服务就能解决了。
启动数据库
mongodb的服务端
studo mongod
sudo service mongodb start
关闭:sudo sevice mongodb stop
mongodb的客户端
mongo
三个警告
root 用户权限太大了
创建用户名和密码
root用户权限太大了
1.启动mongdb
sudo mongod --auth
mongo
2.展示数据库
show databases
3.创建用户
use admin
db.createUser({'user':'yxh',pwd:'123456',roles:["root"]})
4.想继续创建用户名会报错:
登录你已经创建的用户
db.auth('username','pwd')
登录成功之后就可以继续创建了
db.createUser({user:"name2",pwd:"123456"roles:[{db}]})
5.查看所有用户
use admin
show users(root权限)
6.删除用户
db.dropUser('用户名')
数据库的操作
查看所有数据库
show dbs
切换数据库
use xxx
查看当前数据库
db
如果有数据自动创建
不需要手动建库建表
删除数据库
use xxx
db.dropDatabase()
查所有集合(表)
show collections
集合操作
创建集合
db.createCollection('集合名字')
查询集合
show collections
db.集合名.find() 展示集合数据
db.集合名.insert({"":''}) 添加集合数据
删除集合
db.集合名字.drop()
数据库能存储的类型
object ID,string,Array,Boolean,object,timestap,date,double,integer
文档内容操作
增
db.stu.insert({_id:1,name:"李四",age:38,gender:true})
删
db.stu.remove({gender:true})
只删除一个:
db.stu.remove({gender:true},{justOne:true})
删除所有:
db.stu.remove({})
改
id为2名字修改为小王八
db.stu.update({_id:2},{$set:{name:"小王八"}})
小丽年龄修改为15
db.stu.update({name:'小丽'},{$set:{age:15}})
批量修改:
修改所有男生年龄为66
db.stu.update({gender:true},{$set:{age:66}},{multi:true})
删除单个属性
删除id为1的性别
db.stu.update({_id:1},{$unset:{gender:""}})
基本查询
查询所有
db.stu.find()
db.stu.find({})
加条件查询
db.stu.find({gender:false})
db.stu.find({gender:true})
查询一条数据
db.stu.findOne({gender:true})
比较运算:
$lt——less than
$lte——less than equal
$gt——greate than
$gt——greate than equal
$ne——not equal
查询年龄大于18的:
db.stu.find({age:{$gt:18}})
查询年龄小于38的:
db.stu.find({age:{$lt:38}})
查询年龄大于等于30的:
db.stu.find({age:{$gte:30}})
查询年龄不等于10的:
db.stu.find({age:{$ne:10}})
逻辑运算符
$and
find(默认多条件就是且的关系)
查询年龄大于28的男的
db.stu.find({age:{$gt:28},gender:true})
db.stu.find({$and:[{age:{$gt:28}},{gender:true}]})
$or
查询年龄小于30岁的或者是女生
db.stu.find({$or:[{gender:False},{age:{$lt:30}}]})
$混用
年龄小于38岁,或者喜欢老鼠;gender:false1
db.stu.find({$and:[{gender:false},{$or:[{age:{$lt:38}},{like:"老鼠"}]}}]})
范围运算符
in
年龄在38,58,18中的
db.stu.find({age:{$in:[38,58,18]}})
nin
正则表达式
找名字以'李'开头的
db.stu.find({name:{$regex:"^李"}})
db.stu.find({name:/李/})
找a开头英文名(忽略大小写)
db.stu.find({name:/a/i})
db.stu.find({name:{$regex:'a',$options:'i'}})
定义函数
js代码
查找年龄大于20的
db.stu.find({
$where:function(){
return this.age>20
}
})
查询结果显示
limit
只查看前4个
db.stu.find().limit(4)
skip
跳过4个开始看
db.stu.find().skip(4)
查看3,4,5(优先执行skip)
db.stu.find().skip(2).limit(3)
db.stu.find().limit(3).skip(2)
投影
查看姓名和年龄
db.stu.find({},{name:1,age:1})
排序
按年龄升序排序
db.stu.find().sort({age:1})
年龄一样id降序
db.stu.find().sort({age:1,_id:-1})
统计个数
查看男生有多少个
db.stu.find({gender:true}).count()
查看女生有多少个
db.stu.count({gender:false})
默认统计个数
db.stu.find.coutn()
db.stu.count()
去重
去重姓名相同的
db.stu.distinct('name',{})
去重年龄相同的
db.stu.distinct('age',{})
复合查询
aggregate() 管道
db.xx.aggregate(
[
{管道1},
{管道2}
]
)
$group 分组
//$group 分组; 男女分组性别分组
db.stu.aggregate([{$group:{_id:"$gender"}}])
//表达式 $sum $avg $first $last $max $min $push
// 按照性别分组,求年龄之和
db.stu.aggregate(
[
{$group:{_id:"$gender",sumage:{$sum:"$age"}}}
]
)
// 按照性别分组,求年龄平均值
db.stu.aggregate(
[
{$group:{_id:"$gender",avgage:{$avg:"$age"}}}
]
)
// 按照爱好分组,求最大值 age
db.stu.aggregare(
[
{$group:{_id:"like",max_age:{$max:"$age"}}}
]
)
// 按照爱好分组,求最小值 age
db.stu.aggregare(
[
{$group:{_id:"like",min_age:{$min:"$age"}}}
]
)
// 按照爱好分组,求第一个 age
db.stu.aggregare(
[
{$group:{_id:"like",first_age:{$first:"$age"}}}
]
)
// 按照爱好分组,求最后第一个 age
db.stu.aggregare(
[
{$group:{_id:"like",last_age:{$last:"$age"}}}
]
)
// 统计这批人按性别分 养的宠物
db.stu.aggregate([
{
$group:{_id:"$gender",animate:{$push:"like"}}
}
])
$match
//$match == find;区别在于 find不能使用管道传递
// 宠物是小鸡的人有哪些?
db.stu.find({like:"小鸡"})
db.stu.aggregate{[
{$match:{like:"小鸡"}}
]}
// 求年龄大于20;男女年龄平均值
db.stu.aggregare{[
{$match:{age:{$gt:20}}},
{$group:{_id:"gender",aveage:{$avg:"$age"}}}
]}
$project 投影,显示的字段 显示1 or true
// 求年龄小于50岁;求按照爱好分组,求年龄之和,年龄平均值;只想看之和
db.stu.aggregare{[
{$match:{age:{$lt:50}}},
{$group:{_id:"$like",sumage:{$sum:"$age"},aveage:{$avg:"$age"}}},
{$project:{sumage:true}}
]}
$sort 排序
//年龄降序排序
db.stu.aggregare{[
{$sort:{age:-1}}
]}
// 求年龄小于50岁;求按照爱好分组,求年龄之和,年龄平均值;只想看之和降序
db.stu.aggregare{[
{$match:{age:{$lt:50}}},
{$group:{_id:"$like",sumage:{$sum:"$age"},aveage:{$avg:"$age"}}},
{$project:{sumage:true}},
{$sort:{sumage:-1}}
]}
$skip $limit
//跳过2个显示5个
db.stu.aggregare{[
{$skip:2},
{$limit:5}
]}
//允许5个 跳过两个 显示3个
db.stu.aggregare{[
{$limit:5},
{$skip:2}
]}
$unwind 拆分列表; $push
//男女分组之后,各自的名字有哪些
db.stu.aggregare{[
{$group:{_id:"$gender",allname:{$push:"$name"}}},
{$unwind:"$allname"}
]}
//年龄小于60岁,按照性别分组,取出喜欢的宠物,拆分文档
db.stu.aggregare{[
{$match:{age:{$lt:60}}},
{$group:{_id:"$gender",alllike:{$push:"$like"}}},
{$unwind:"$alllike"}
]}
索引查询
//添加50w数据
for (var i =0;i<500000;i++){
db.data.insert(
{
_id:i,
user:"user"+i,
age:i
}
)
}
// _id 1毫秒
db.data.find({_id:333333}).explain('executionStats')
// user222毫秒——1毫秒
db.data.find({user:"user333333"}).explain('executionStats')
// age227毫秒——0毫秒
db.data.find({age:333333}).explain('executionStats')
// 设置内容key 为id;提高查询速度
//设置user为索引
db.data.ensureIndex({user:1})
//查看索引
db.data.getIndexes()
//删除索引
db.data.dropIndex('user_1')
备份和恢复
//备份数据库
把数据库five备份到本地/Users/Desktop/beifen
mongodump -h 127.0.0.1:27017 -d five -o /Users/Desktop/beifen
//恢复数据库
恢复本地five备份到数据库six
mongorestore -h 127.0.0.1:27017 -d six --dir /Users/Desktop/beifen/five
//导出文件
导出six数据库stu表为data.json
mongoexport -h 127.0.0.1:27017 -d six -c stu -o data.json
导出为csv文件
mongoexport -h 127.0.0.1:27017 -d six -c stu -o data.csv --type csv -f _id,name,age,like
//导入文件
//导入文件data.json为seven数据库下的stu表
mongoimport-h 127.0.0.1:27017 -d seven -c stu --file data.json
mongo和python的交互
# 安装 pymongo pip install pymongo
import pymongo
try:
# 1.连接mongo的服务
mongo_py = pymongo.MongoClient()
# 2.库和表的名字:有数据会自动建库建表
# collection = mongo_py['six']['stu2']
collection = mongo_py.six.stu2
# 3.插入数据
one = {"name": "张三", "age": 50}
# collection.insert_one(one) # 插入一条
two_many = [
{"name": "小三", "age": 50},
{"name": "李四", "age": 40},
{"name": "王五", "age": 20},
{"name": "赵六", "age": 10}
]
# collection.insert_many(two_many) # 插入多条
# 删除数据
# collection.delete_one({"age": 10})
# collection.delete_many({"age": 50})
# 修改数据
# 修改所有年龄为20岁的姓名为小王
# collection.update_many({"age": 20}, {"$set": {"name": "小王"}})
# 查询
result = collection.find({"age": 50})
for i in result:
print(i)
except Exception as e:
print(e)
finally:
# 关闭数据库
mongo_py.close()
redis
Windows 下安装
Redis 支持 32 位和 64 位。这个需要根据你系统平台的实际情况选择,这里我们下载 Redis-x64-xxx.zip压缩包到 C 盘,解压后,将文件夹重新命名为 redis。
打开文件夹,内容如下:
打开一个 cmd 窗口 使用 cd 命令切换目录到 C:\redis 运行:
redis-server.exe
如果想方便的话,可以把 redis 的路径加到系统的环境变量里,这样就省得再输路径了,后面的那个 redis.windows.conf 可以省略,如果省略,会启用默认的。输入之后,会显示如下界面:
这时候另启一个 cmd 窗口,原来的不要关闭,不然就无法访问服务端了。
切换到 redis 目录下运行:
redis-cli.exe -h 127.0.0.1 -p 6379
config
redis.windows.conf
注释后允许所有人访问
# 192.168.1.100 10.0.0.1
# 127.0.0.1 ::1
与其他主机交互需要修改,默认为:
127.0.0.1
端口:
port 6379
是否线程守护:
daemonize no
有16个数据库:
databases 16
15分钟保存一次,5分钟保存十次,60秒保存10000次
save 900 1
save 300 10
save 60 10000
数据库保存文件名
dbfilename dump.rdb
路径:
dir ./
logfile:
/redis/redis-server.log
master slave 主从端
bing:0.0.0.0
数据操作
string
支持最大为:512M
增加
set : 单次写入
set one "1"
set two "2"
mset:多次写入
mset one 1 two 2
setex key 时间 value :设置one内容为abc 3秒过期
setex one 3 "abc"
读取
get:一次读取
get one#"1"
get two#"2"
mget:多次读取
mget one two #"1" "2"
追加
append key value
append two "3456"
get two #"23456"
hash
存对象 属性值
单个属性
hset person name "张三"
hset person age 18
hset person gender true
hget person name
hget person age
hget person gender
多个属性
hset person name "张三"
hset person age 18 gender true
查看key
hkeys person
查看value
hvals person
删除属性
hdel person name age
list
增加:
lpush:
lpush one 1
lpush one 2
lpush one 3 4 5 6
lrange one 0 -1 #6 5 4 3 2 1
rpush:
rpush two 1 2 3 4 5 6
lrange two 0 -1 # 1 2 3 4 5 6
lpop:
lpop one #6
lpop one #5
lpop one #4
lpop one #3
rpop:
rpop two #6
rpop two #5
rpop two #4
rpop two #3
根据范围取出
lrange one 0 -1 #6 5 4 3 2 1
指定位置插入
linsert one before 1 "A" #在列表one 1前面添加A
linsert one after 1 "B" #在列表one 1后面添加B
单独修改值根据索引
lset one 2 "D" # one中索引为2的d修改为D
删除数据
lrem key1 count "值"
count>0从头删
count<0从尾删
count=0符合条件的都删
lrem one 1 e #从头删除e
lrem one -1 "一" #从尾删除一
lrem one 0 b #所有b都删除
set
特点
1.无序
2.string
3.不重复
4.没有修改
增加
sadd
sadd key value value value value
查看所有元素
smembers key
删除
srem
srem key1 value1 value2
判断元素是否在集合中
sismember key value
返回1找到0没找到
zset
stored set
有顺序权重
增加
zadd key score1 value score2 value2
查看元素
zrange: zraange key 0 -1 范围
zrangebyscore key 权重1 权重2
zscore key value :根据内容获取权重
删除指定元素
zrem key value
zremrangebyscore key 权重范围
键key 的命令
keys * :查看所有的key
key K* :查看以K开头
exists key: 查看key是否存在
type key: 查看键的类型
del key:删除key
exprie key 时间:给key设置过期时间
python和redis的交互
pip install redis
redus.StrictRedis()
host,port,db
string
增加(true false)
set
删除
修改
查询
import redis
# 1.连接数据库 key-value
client = redis.StrictRedis(host='127.0.0.1', port=6379)
# 2.设置key
key = 'pyone'
# 3.string 增加 true false
result = client.set(key, "1")
# 4 .删除 1 ,0
result = client.delete(key)
# 5 .改
result = client.set(key, "2")
# 6.查--bytes
result = client.get(key)
result = client.keys() # 查看所有的键 ()内可传正则
清空数据
flushdb 清空当前数据库
flushall 清除所有数据库 0-16个
主从服务器
master
写入
slave
读取
10:1
当前电脑的终端
ifconfig:
ubuntu
sudo apt install ipmiutil
IP地址:192.168.20.20
redis.conf:
bind:192.168.20.20
重启服务
salve
1.复制刚刚的配置文件redis.conf
salve.conf
2.修改
bind:192.168.20.20
slaveof 192.168.20.20 6379
port 6378
重启 sudo redis-server slave.conf
3.redis.cli - h 192.168.20.20 info Relication
查看关系
4.redis.cli - h 192.168.20.20 -p 6379
5.redis.cli - h 192.168.20.20 -p 6378
6.在master 写入数据
7.在slave 读取
mysql
安装
ubuntu:
sudo apt-get install mysql-server mysql-client
mac:
brew install mysql
windows:
exe
navicat:
mysql的图形界面
E_R模型
E:
实体--表
R:
关系
表表关系:
1对1,1对多,多对多
三范式
1.列不可拆分
2.唯一标志
3.引用主键
数据的完整性
字段类型
int:整数decimal:小数 数字
char:确定个数的字符串 varchar:可变字符串 text 字符串
datetime: 日期
bit:布尔
约束
主键
primary key
非空
not null
唯一
unique
默认
default
外键
foreign
逻辑删除
物理删除
从磁盘真正的删除
重要数据
删除标识 1 0
数据库的启动
mysql.server start
mysql.server stop
客户端:mysql -u root -p
输入密码
查看安装数据的版本
select version();
显示当前时间
select now();
端口号
3306
数据库的操作
创建数据库:
create database 数据库名 charset=uft8;
查询所有数据库:
show databases:
查询当前数据库:
select database();
切换数据库:
use 数据库名;
删除数据库:
drop database 数据库名;
表的操作
查看所有表:
show tables;
建表:
create table dog(
id int auto_increment primary key,
name varchar(10) not null
);
添加字段:
alter table dog add birthday datatime;
删除字段:
alter table dog drop age;
查看表内容:
desc dog;
修改表名称:
rename table dog to cat;
修改表:
change
删除表:
drop table tablename;
查看建表时语句:
show create table dog;
数据操作
插入语句:
insert into dog values(1,"labuladuo");
insert into dog values(1,"黄金毛",1);
插入单个字段(缺省插入):
insert into dog(name) values("小猎犬");
insert into dog(name,gender) values("德国牧羊犬",1);
插入多条数据:
insert into dog values(5,"腊肠",0),(6,"约克夏",1)
缺省插入多条数据:
insert dog(name) values("太师犬"),("贵宾犬"),("狮子狗")
查询所有数据:
select * from dog;
修改数据:
update dog set name="泰迪" where id=8;
删除数据:
物理删除:delete from dog where id = 4;
alter table dog add isdelete bit default 0;(添加是否删除字段)
逻辑删除: update dog set isdelete=1 where id=2;
查询时只查询isdelete=0的数据
查询操作
create table stu(
id int auto_increment primary key,
name varchar(10) not null,
birthday datetime,
gender bit default 0,
isdelete bit default 0,
address varchar(100),
score int
);
insert into stu values(1,"小明","2008-01-01",0,0,"北京",90),
(2."小红","2007-04-01",1,0,"上海",80);
条件运算
= ,>= ,<= ,!= (<>)
select * from stu where id=7;
select * from stu where id>6;
select name,address from stu where id<>6;
逻辑运算
and,or,not
id大于6的女生:
select * from stu where id>6 and gender=1;
编号小于4或男生
select * from stu where id<4 gender=0;
模糊查询
like
% 表示任意多个字符
_ 表示任意一个字符
select * from table_name where 字段 like "模糊值"
select * from stu where name like "小%";
select * from stu where name like "张%" or name like "%王";
select * from stu where name like "张_" ;
范围查询
in #表示一个非连续的范围
not in
between 范围1 and 范围2 #表示一个连续的范围
select * from stu where id in(1,3,5,7);#id 在1,3,5,7内的人
select * from stu where id not in(1,3,5,7);#id 不在1,3,5,7内的人
select * from stu where id between 1 and 5;#id 在1~5的人
select * from stu where id between 2 and 4 and gender=1;#id 在2~4的男生
判断空
null
select* from stu where address is null;#判断地址为空的
not null
select* from stu where address is not null;#判断地址不为空的
查询符号的优先级
()
not
条件运算
and or (先and 后or)
聚合查询
统计个数
count()
select count(*) from stu where 查询条件;
列的最大值
max()
select max(score) from stu;
列的最小值
min()
select min(score) from stu;
列求和
sum()
select sum(score) from stu where gender = 1;
列的平均值
avg()
select avg(score) from stu where gender = 1;
分组查询
group by 分组的依据
男生女生的总数:
select gender as "别名" ,count(*) from stu group by gender;
分组之后继续筛选:
having
男生的总数:
select count(*) from stu where gender = 0;
select gender as "性别",count(*) from stu group by gender having gender = 0;
where和having区别:
where:原始数据筛选
having:分组结束之后 group by 结果进行筛选
排序
order by 字段
asc升序(默认)
desc降序
select * from stu where isdelete=0 order by score desc;#没被删除的学生分数降序
select * from stu where gender=0 order by id asc;#男生id升序
分页
limit start,count 在实际开发中 涉及到的时数学问题
select * from stu limit 0, 3;#查询前三个
select * from stu limit 3,2; #查询4,5
去重
distinct
select distinct birthday from stu;
select distinct address from stu;
ER模型 关系
1.关系
不建议表和表之间建立循环的关系闭合
学生表
学科表
成绩表:
foreign key (stuid) references stu(id),
foreign key (subid) references subjects(id),
多表约束 产生关系 如果又删除修改操作,对应的关联表数据 就会报错
逻辑删除解决这个问题
先建表 再约束
alter table scores and contraint stu foreign key (stuid) references stu(id) on delete cascade
cascade 级联关系 #一删除 有关联的表 全部删除
restrict 限制关系
set null 外键制空
no action
create table subjects(
id int auto_increment primary key not null,
title varchar(10) not null
);
insert into subjcets values(0,"语文"),(0,"数学"),(0,"英语"),(0,"科学");
create table stu(
id int auto_increment primary key not null,
name varchar(20) not null,
birthday datetime,
gender bit default 1,
isdelete bit default 0,
address varchar(100),
score int(10)
);
insert into stu values(1,"小明","2008-01-01",0,0,"北京",90),
(2,"小红","2008-03-01",1,0,"上海",100),
(3,"小兰","2006-04-01",1,0,"广州",80),
(4,"小王","2008-05-01",0,0,"深圳",50);
create table scores(
id int auto_increment primary key not null,
stuid int,
subid int,
score decimal(5,1),#五位数保留一位
foreign key(stuid) references stu(id),
foreign key(subid) references subjects(id)
);
链接查询
inner join
多表查询
查询学生的名字 学课对应的成绩:
select stu.name,subjects.title,scores.score
from scores
inner join stu on scores.stuid=stu.id
inner join subjects on scores.subid=subjects.id;
left join
A表左链接B表:结果以A为基准
select stu.name,subjects.title,scores.score
from scores
left join stu on scores.stuid=stu.id;
right join
A表右链接B表:结果以B为基准
select stu.name,subjects.title,scores.score
from scores
right join stu on scores.stuid=stu.id;
查询学生姓名平均分
select stu.name,avg(scores.score)
from scores
inner join stu on socres.stuid=stu.id
group by stu.name;
查男生 姓名 总分
select stu.name,sum(scores.score)
from scores
inner join stu on scores.stuid = stu.id
where stu.gender=0
group by stu.name;
查各个科目的平均分
select subjects.title,avg(scores.score)
from scores
inner join subjects on scores.subid = subjects.id
group by subjects.title;
学生名 最高分
select stu.name,max(scores.score)
from scores
inner join stu on scores.stuid=stu.id
where stu.id<5
group by stu.name;
自关联
省表:
id,name,23个省
城市表:
id,name,pid,1663市区
将声称市区 放在一个表里面实现数据存储和查询:
pid关联省份id
自关联的一个表:
areas表的名字
create table areas(
id int primary key,
title varchar(50),
pid int,
foreign key(pid) references areas(id)
);
id: 省NULL
市区:省份的id
查询当前省份: select * from areas where pid is null;
县:市区的id
村:县的id
atitle
pid
select p.title,c.title from areas as p
inener join areas as c on p.id=c.pid
where p.title="广州市";
select city.* from areas as city
inner join areas as province on city.pid=province.id
where province.title="广东省";
导sql文件数据
cd 当前路径
source areas.sql
视图view
对于复杂查询的封装
创建视图
create view 视图的名字 as sql的查询语句
create view studentsscore as
select stu.name,scores.score from scores
inner join stu on scores.stuid=stu.id;
查看视图 的结果
select * from 视图名字
select * from sutdentsscore;
删除视图
drop view 视图名字
drop view studentsscore;
事务
四大特性ACID
A:原子性 事务中所有操作不可分割,执行全部或者不执行
C:一致性必须有顺序执行
I:隔离性事物之间是隔离的没关系的
D:持久性 事务行为持久化
mysql的表 要求 类型
innodb(默认)
ddb
查看ENGINE 引擎
show create table areas;
修改表引擎
alter table stu engine = innodb
开启事务 begin
begin;
insert into subjects values(0,"AI课");
select * from subjects;# 无AI课
提交事务 commit
commit;
select * from subjects;# 有AI课
事务回滚 rollback
begin;
insert into subjects(title) values("爬虫");
select * from subjects;# 有爬虫课
rollback;
select * from subjects;# 无爬虫课
select * from subjects;# 无爬虫课
查询效率问题
索引查询
效率最高
数据类型越小越好
能用整型最好
不适用NULL 用0,”“,特殊符号代替
创建索引
create index indexname on tablename(key(length));
查看所有索引
show index from tablename;
删除索引
drop index indexname on tablename
验证时间
set profiling=1;
select * from areas where title="贵州省";
show profiles;
create index titleIndex on areas(title(50));
select * from areas where title ="贵州省";
show profiles;
python和mysql交互
Connection对象
建立和数据库的连接:
host , port , db , username , passwd , charset=utf8
关闭连接:
close()
事务处理:
commit()
回滚
rollback()
Cursor对象
execute() 执行MySQL的语句
fetchone 一行数据一个元组
fetchall() 一个大元组包含多个小元组
安装 python3 pymysql
pip install pymysql
# 安装pip install pymysql
import pymysql
try:
# 1.链接数据库
conn = pymysql.Connect(
host="localhost",
port=3306,
db='animal',
user='root',
passwd='root',
charset='utf8'
)
# 2.创建游标对象 cursor()
cur = conn.cursor()
# 增加一条数据 科目表--GO语言
# insert_sub = 'insert into subjects values(0,"GO语言")'
# result = cur.execute(insert_sub)
# 修改
# update_sub = 'update subjects set title="区块链" where id=7'
# result = cur.execute(update_sub)
# 删除
delete_sub = 'delete from stu where id=8'
result = cur.execute(delete_sub)
# 查询一条
select_sub = 'select * from subjects'
cur.execute(select_sub)
result = cur.fetchone()
# 查询多条
select_sub = 'select * from subjects'
cur.execute(select_sub)
result = cur.fetchall()
for res in result:
print(res)
# 提交事务
conn.commit()
# 关闭游标
cur.close()
# 关闭链接
conn.close()
except Exception as e:
print(e)
mysql的备份和恢复
备份
mysqldump -u root -p db_name table_name >备份文件的绝对路径
恢复
mysql -u root -p db_name