数据库
什么是数据库?
简单的说,数据库(Dtabase)就是一个存放数据的仓库,这个仓库是按照一定的数据结果(数据结构是指数据的组织形式或数据之间的联系)来组织、存储的、我们可以通过数据库提供的多种方法来管理数据库里的数据更简单的形象理解,数据库和我们生活中存放杂物的仓库性质一样,区别只是存放的东西不同。
数据库基本术语
- 数据库:database
- 数据表:table
- 列
- 行
- 主键
- 表头
数据库分类
- 关系型数据库:Mysql, Oracle(甲骨文公司), SQL Server…
- 非关系型数据库: redis, mongodb…
Mysql数据库
什么是mysql?
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件。
MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。在存储引擎方面,使用XtraDB(英语:XtraDB)来代替MySQL的InnoDB。 MariaDB由MySQL的创始人Michael Widenius(英语:Michael Widenius)主导开发,他早前曾以10亿美元的价格,将自己创建的公司MySQL AB卖给了SUN,此后,随着SUN被甲骨文收购,MySQL的所有权也落入Oracle的手中。MariaDB名称来自Michael Widenius的女儿Maria的名字。
Mysql使用方法
1. 安装mysql
查找与mariadb有关的软件包
yum search mariadb
安装mariadb的server软件和client软件
yum install mariadb mariadb-server -y
启动mariadb服务
systemctl start mariadb
systemctl enable mariadb
mariadb监听的端口
netstat -antlpe | grep mysql
ss -antlpe | grep mysql
只允许本地连接,阻断所有来自网络的连接
vim /etc/my.cnf (skip-networking=1)
systemctl restart mariadb
2. mariadb的初始化
设置mysql的登陆密码
mysql_secure_installation
mysql -uroot -p
3.mysql基本操作语句
show databases; # 显示数据库,类似于目录,里面包含多个表
use mysql; # 进入名称为mysql的数据库
show tables; # 显示该数据库中的表
desc user; # 显示表的结构
select * from user; # 显示user表中的内容
select Host,User,Password from user; # 显示表中某几列
create database westos; # 创建一数据库名称为westos
create table westosuser(username varchar(10),passwd varchar(6));# 创建一数据表
insert into westosuser values ('user1','123'); # 向表中插入内容
insert into westosuser(passwd,username) values("456","user2"); # 按照指定顺序向表中插入数据
update westosuser set passwd='456' where username="user1"; # 更新表中的内容
alter table westosuser add sex varchar(3); # 添加sex列到westosuser表中
delete from westosuser where username="user1"; # 删除表中用户名为user1的记录
drop table westosuser; # 删除表
drop database westos; # 删除数据库
4.用户和访问权限的操作
create user hello@localhost identified by 'hello'; # 创建用户hello,可在本机登陆,密码为hello
create user hello@'%' identified by 'hello'; # 创建用户hello,可在远程登陆,密码为hello
create database mariadb; # 创建一数据库mariadb,对普通用户进行
grant all on mariadb.* to hello@localhost; # 给hello@localhost用户授权,如果为all,授权所有权限(insert,update,delete,select,create)
flush privileges; # 刷新,重载授权表
show grants for hello@localhost; # 查看用户授权
revoke delete,update on mariadb.* from hello@localhost; # 删除指定用户授权
drop user hello@localhost; # 删除用户
5. 忘记mysql用户密码时,怎么找回?
- 关闭mariadb服务
systemctl stop mariadb - 跳过授权表
mysqld_safe --skip-grant-table & - 修改root密码
mysql
update mysql.user set Password=password(‘westos’) where User=‘root’; - 关闭跳过授权表的进程,启动mariadb服务,使用新密码即可
ps aux | grep mysql
kill -9 pid
mysql -uroot -p
6. mysql的备份与恢复
备份:
mysqldump -uroot -p mariadb >mariadb.dump
mysqldump -uroot -pwestos --no-data mariadb > date +%Y_%m_% d
_mariadb.dump
mysqldump -uroot -pwestos --all-databases >mariadb4.dump
恢复:
mysqladmin -uroot -pwestos create mariadb2
mysql -uroot -pwestos mariadb2 < mariadb.dump
Mysql数据类型
数值
日期
字符串
属性设置
python连接数据库
对数据库的基本操作
import pymysql
# 1.连接数据库
conn = pymysql.connect(
host = 'localhost',
user = 'root',
password = 'westos',
db = 'studentInfo',
charset = 'utf8',
autocommit = True, # 如果要插入数据,是否自动提交? 和conn.commit()功能一致。
)
# 2.创建游标
# python, 必须有一个游标对象,用来给数据库发送sql语句,并执行的
cur = conn.cursor()
# 3.对于数据库进行增删改查
# 1).创建数据表
try:
create_sqli = 'create table hello (id int,name varchar(30));'
cur.execute(create_sqli)
except Exception as e:
print('创建数据表失败', e)
else:
print('创建数据表成功')
# 2).插入数据
try:
insert_sqli = "insert into hello values(2,'fensi');"
cur.execute(insert_sqli)
except Exception as e:
print('插入数据失败', e)
else:
# 如果是插入数据,一定要提交数据,不然数据库中找不到要插入的数据
# conn.commit()
print('插入数据成功')
# 3).插入多条数据
try:
Info = [(i,'hello%s' %(i)) for i in range(100)]
# 方法一
# insert_sqli = "insert into hello values(%d,'%s');"
# for item in Info:
# cur.execute(insert_sqli %item)
# 方法二
insert_sqli = "insert into hello values(%s,%s);"
cur.executemany(insert_sqli,Info)
except Exception as e:
print('插入多条数据失败', e)
else:
print('插入多条数据成功')
# 4). 查询数据库
sqli = 'select * from hello;'
result = cur.execute(sqli) # 默认不返回查询结果集,返回数据记录数
print(result)
# 获取下一个查询结果集
print(cur.fetchone())
print(cur.fetchone())
print(cur.fetchone())
# 获取指定个数个查询结果集
print(cur.fetchmany(5))
# 获取所有的查询结果
print(cur.fetchall())
# 返回执行sql语句所影响的行数
print(cur.rowcount)
# 5). 移动游标指针
print(cur.fetchmany(3))
print('正在移动指针到最开始......')
cur.scroll(0,'absolute')
print(cur.fetchmany(3))
print('正在移动指针到倒数第2个......')
cur.fetchall() # 移动到最后
cur.scroll(-2,mode='relative')
print(cur.fetchall())
# 4.关闭游标
cur.close()
# 5.关闭连接
conn.close()
1).创建数据表:
2).插入数据:
3).插入多条数据:
4). 查询数据库(移动游标指针):
获取表头和信息
with语句实现回滚
import pymysql
# 1.连接数据库
conn = pymysql.connect(
host = 'localhost',
user = 'root',
password = 'westos',
db = 'studentInfo',
charset = 'utf8',
autocommit = True,
)
# with语句实现的效果是: with语句执行结束,如果成功,则提交改变的数据,如果不成功, 则回滚
with conn:
# 判断是否连接?
print(conn.open) # True
# 2.创建游标
cur = conn.cursor()
# 3.
sqli = 'select * from hello;'
result = cur.execute(sqli)
# 显示每列的详细信息
des = cur.description
print('表的描述:', des)
# 获取表头
print('表头:',','.join([item[0] for item in des]))
cur.close()
# 4.关闭游标
conn.close()
print("with语句之外:", conn.open) # False
银行转账
import pymysql
class TransferMoney(object):
# 构造方法
def __init__(self,conn):
self.conn = conn
self.cur = conn.cursor()
def transfer(self,source_id,target_id,money):
# 1). 判断两个银行卡号是否存在?
# 2). 判断source_id是否有足够的钱?
# 3). source_id扣钱
# 4). target_id加钱
if not self.check_account_available(source_id):
raise Exception('账户不存在')
if not self.check_account_available(target_id):
raise Exception('账户不存在')
if self.has_enough_money(source_id,money):
try:
self.reduce_money(source_id,money)
self.add_money(target_id,money)
except Exception as e:
print('转账失败',e)
self.conn.rollback()
else:
self.conn.commit()
print('%s给%s转账%s金额成功' %(source_id,target_id,money))
def check_account_available(self,acc_id):
"""判断帐号是否存在, 传递的参数是银行卡号的id"""
select_sqli = 'select * from bankData where id = %s;' %(acc_id)
print('execute sql:',select_sqli)
res_count = self.cur.execute(select_sqli)
if res_count == 1:
return True
else:
return False
def has_enough_money(self,acc_id,money):
"""判断acc_id账户上的金额 > money"""
# 查找acc_id存储金额
select_sqli = 'select money from bankData where id = %d;' %(acc_id)
print('execute sql:',select_sqli)
self.cur.execute(select_sqli)
# 获取查询到的金额钱数
acc_money = self.cur.fetchone()[0]
# 判断
if acc_money >= money:
return True
else:
return False
def add_money(self,acc_id,money):
update_sqli = 'update bankData set money=money+%d where id = %d' %(money,acc_id)
print('add money:',update_sqli)
self.cur.execute(update_sqli)
def reduce_money(self,acc_id,money):
update_sqli = 'update bankData set money=money-%d where id = %d' %(money,acc_id)
print('reduce money:',update_sqli)
self.cur.execute(update_sqli)
# 析构方法
def __del__(self):
self.cur.close()
self.conn.close()
if __name__ == '__main__':
# 连接数据库
conn = pymysql.connect(
host = 'localhost',
user = 'root',
password = 'westos',
db = 'studentInfo',
charset = 'utf8',
autocommit = True,
)
trans = TransferMoney(conn)
trans.transfer(13997,13998,200)
转账前:
转账后:
python2连接数据库----实现银行账户创建
python2数据库模块:MySQLdb
import random
import MySQLdb as pymysql
# 1. 连接数据库
conn = pymysql.connect(
host = 'localhost',
user = 'root',
passwd = 'westos',
db = 'studentInfo',
autocommit = True,
charset = 'utf8'
)
# 2. 创建游标
cur = conn.cursor()
# 3. 操作
bank_id = random.randint(10000,20000)
print ("创建银行用户%d ........." %(bank_id))
bank_pwd = raw_input("请输入密码:")
bank_money = float(raw_input("存储金额:"))
insert_sqli = "insert into bankData values(%d,%f,'%s')" %(bank_id,bank_money,bank_pwd)
cur.execute(insert_sqli)
print ("创建账户成功 .......")
# 4. 关闭游标
cur.close()
# 5. 关闭连接
conn.close()
数据库中银行账户创建成功:
Redis数据库
什么是Redis?
REmote DIctionary Server(Redis) 是一个key-value存储系统。使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API(python, php, java…)。
它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
Redis的优势?
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
- Redis支持数据的备份,即master-slave模式的数据备份。
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
Redis的安装
1.下载:
下载地址:http://redis.io/download ,下载最新稳定版本。
2.安装:
tar xzf redis-5.0.3.tar.gz
3.启动:
- 执行make命令
- make完后 redis-5.0.3目录下会出现编译后的redis服务程序redis-server,
还有用于测试的客户端程序redis-cli,两个程序位于安装目录 src 目录下: - 启动服务器端:./redis-server
启动客户端:./redis-cli - 也可以通过启动参数告诉redis使用指定配置文件使用下面命令启动。
./redis-server ./redis.conf
注意:
vim /etc/services # 记录服务对应的端口号
常见的端口号:
http: 80
ssh: 22
mysql: 3306
redis: 6379
4.常用操作:
字符串(String)
redis 127.0.0.1:6379> SET runoobkey redis
OK
redis 127.0.0.1:6379> GET runoobkey
"redis"
127.0.0.1:6379> SET views 1000
127.0.0.1:6379> INCR views
(integer) 1001
127.0.0.1:6379> GET views
"1001"
127.0.0.1:6379> INCR views
(integer) 1002
127.0.0.1:6379> DECR views
(integer) 1001
127.0.0.1:6379> DECR views
(integer) 1000
哈希(Hash)
127.0.0.1:6379> HMSET runoobkey name "redis tutorial" description "redis basic commands for caching" likes 20 visitors 23000
OK
127.0.0.1:6379> HGETALL runoobkey
1) "name"
2) "redis tutorial"
3) "description"
4) "redis basic commands for caching"
5) "likes"
6) "20"
7) "visitors"
8) "23000"
列表(List)
redis 127.0.0.1:6379> LPUSH runoobkey redis
(integer) 1
redis 127.0.0.1:6379> LPUSH runoobkey mongodb
(integer) 2
redis 127.0.0.1:6379> LPUSH runoobkey mysql
(integer) 3
redis 127.0.0.1:6379> LRANGE runoobkey 0 10
1) "mysql"
2) "mongodb"
3) "redis"
集合(Set)
redis 127.0.0.1:6379> SADD runoobkey redis
(integer) 1
redis 127.0.0.1:6379> SADD runoobkey mongodb
(integer) 1
redis 127.0.0.1:6379> SADD runoobkey mysql
(integer) 1
redis 127.0.0.1:6379> SADD runoobkey mysql
(integer) 0
redis 127.0.0.1:6379> SMEMBERS runoobkey
1) "mysql"
2) "mongodb"
3) "redis"
有序集合(sorted set)
redis 127.0.0.1:6379> ZADD runoobkey 1 redis
(integer) 1
redis 127.0.0.1:6379> ZADD runoobkey 2 mongodb
(integer) 1
redis 127.0.0.1:6379> ZADD runoobkey 3 mysql
(integer) 1
redis 127.0.0.1:6379> ZADD runoobkey 3 mysql
(integer) 0
redis 127.0.0.1:6379> ZADD runoobkey 4 mysql
(integer) 0
redis 127.0.0.1:6379> ZRANGE runoobkey 0 10 WITHSCORES
1) "redis"
2) "1"
3) "mongodb"
4) "2"
5) "mysql"
6) "4"
python连接Redis
redis常用操作
import redis
import time
# 连接redis
# ********************第一种方式********************
# # redis.Redis(host='localhost',port=6379)
# conn = redis.Redis()
# conn.set('name','fentiao',3)
# print(conn.get('name'))
# print('等待3秒.......')
# time.sleep(3)
# print(conn.get('name'))
# ********************第二种方式********************
# 为了减少每次建立连接, 释放连接的开销, 推荐使用连接池。
# 多个redis对象可以共用一个连接池。
pool = redis.ConnectionPool(host='localhost',port=6379)
conn = redis.Redis(connection_pool=pool)
conn.set('name','fentiao',3)
# 默认返回bytes类型,如果转换,需要解码为utf-8编码格式
print(conn.get('name').decode('utf-8'))
print('等待3秒.......')
time.sleep(3)
print(conn.get('name'))
import redis
pool = redis.ConnectionPool(host='localhost',port=6379)
conn = redis.Redis(connection_pool=pool)
conn.set('name','fentiao',3)
conn.set('age',10,3)
conn.set('scores',100,3)
# 获取key值
print(conn.get('name'))
print(conn['name'])
# 获取所有key值
print(conn.keys())
# 当前redis数据库中数据条数
print(len(conn.keys()))
print(conn.dbsize())
# 删除指定key-value值
conn.delete('views')
print('正在删除key......')
print(conn.get('views'))
# 将内存中的数据保存到磁盘中,重启的时候可以再次加载使用
conn.save()
# 清除redis里面的所有key-value值
print('清除前:',conn.keys())
conn.flushall()
print('清除后:',conn.keys())
应用场景
页面点击数
import redis
pool = redis.ConnectionPool(host='localhost', port=6379)
conn = redis.Redis(connection_pool=pool)
conn.set('views', 19800)
conn.incr('views')
print(conn.get('views').decode('utf-8'))
社交圈子
社交网站,每一个标签都会有自己的用户群,通过圈子可以找到有共同特征的人(eg:python开发, 电影…),当一个用户加入一个或者多个圈子后,系统可以向这个用户推荐圈子中的人
import redis
pool = redis.ConnectionPool(host='localhost', port=6379)
conn = redis.Redis(connection_pool=pool)
# 选择集合存储
conn.sadd('python','user1')
conn.sadd('python','user2')
conn.sadd('python','user3')
conn.sadd('movie','user4')
conn.sadd('movie','user5')
conn.sadd('movie','user6')
conn.sadd('movie','user1')
# 获取某个圈子的成员
print(conn.smembers('python'))
print(conn.smembers('movie'))
# 获得两个圈子共同拥有的成员
print(conn.sinter('python','movie'))
# 获取并集
print(conn.sunion('python','movie'))