Skip to content

Latest commit

 

History

History
922 lines (758 loc) · 29.9 KB

数据库相关.md

File metadata and controls

922 lines (758 loc) · 29.9 KB

数据库

数据库的安装

在windows环境下安装MySQL.
进去MySQL官网,下载mysql-installer-community-5.7.21.0.msi
安装指南:
1:选择Custom 最后一个自定义安装
2:选择MySQLServer X64 在旁边框中选择MySQL Client Progranms
3:只安装server第一个
4:如果出现缺失文件的提示,选择该文件 Execute
5:ready to config

注意: 如果不想开机自启 记得不要勾选 start the MySQL Server at sys start
DBMS 数据库管理系统
DBA 数据库管理员
DB 数据库
SQL 结构化查询系统
    -- DDL 数据定义语言 : creat 新建/ drop(删除) / alter (修改)
	-- DML 数据操作语言 : insert 插入 delete 删除 update 更新
	-- DQL 数据查询语言 : select
	-- DCL 数据控制语言  : grant / revoke / begin / commit / rollback		

数据库的启动和关闭

在运行界面 输入services.msc  可以手动点击停止和重启或者启动
或者 在cmd 以管理员身份  输入 net start mysql57    net stop mysql57

数据库的相关知识

q1:为什么要使用数据库
a1:数据持久化 - 将数据从容易丢失的存储介质(内存)转移到持久存储介质(硬盘)
a2:可以快速检索,高效的放入数据和管理数据.

q2:什么是关系型数据库?
a1:理论基础 - 集合论和关系代数
a2:用二维表组织数据
表- 实体
行- 记录
列- 字段
表与表之间有关系
编程语言 - SQL 结构化查询语言

q3:什么是数据库,数据库系统,数据库管理系统?
a1:数据库简称DB -Database 数据的仓库(集散地)
a2:数据库系统DBS -包括了DB,DBMS(数据库管理系统),DBA(数据库管理员)
a3:(r)DBMS -(关系型)数据库管理系统 -管理数据库的软件

常见的关系型数据库:
	-MySQL:小巧但是强大
	-oricle:号称世界上最好的关系型数据库 强大,可以提供商业智能
	-IBM DB2: 强大,可以提供商业智能
	-SQL Server
	-SQLite:嵌入式数据库(移动端)

常用的客户端工具:
	-SQLyog
	-Toad for MySQL
	-Navicat for MySQL

数据库的相关操作

show databases;  查看所有数据库
show tables 查看所有表
select version();
quit;  退出服务器
?  查看所有可以使用的命令
在Navicat for MySQL 如果想连接自己
可以选择连接127.0.0.1(回还地址) 或者localhost 
? 指令   可以进入帮助系统 ? int 
show create table tb_student; 查看建表的过程
desc 表明 查看表的详细信息

SQL语句

用 '--' 表示注释
-- 如果指定的数据库存在则删除该数据库
drop database if exists school;
-- 创建数据库  指定默认字符集 utf8
create database school default charset utf8;
-- 切换到school数据库
use school;
-- 关系型数据库是通过二维表来组织数据的
-- 主键(primary key)  能够标识唯一的一条记录的列
-- comment 关键字后面跟的也是注释
-- 删除学生表,先判断该表是否存在
drop table if exists tb_student
-- 创建学生表
create table tb_student
(
stuid int not null,    -- 指定字符类型为数字
sname varchar(5) not null,	  -- varchar为可变长度字符串 不超过5个
stel char(11),    -- char 为固定长度字符串
primary key(stuid)    -- 设置主键
);

-- 修改学生表
-- 增加
alter table tb_student add column saddr varchar(100);
-- 删除
alter table tb_student drop column saddr;

-- 插入学生记录
insert into tb_student values
(1004,'瓜皮',1,'1993-2-3','西藏'),
(1005,'香蕉皮',1,'1993-1-3','内蒙'),
(1006,'椰子皮',1,'1993-5-3','阿富汗');

insert into tb_student (stuid,sname)values(1002,'朱林易'); -- 只给stuid,sname赋值

-- 删除数据(危险操作)
delete from tb_student where stuid=10000
-- where表示删除的条件

-- 更新数据
-- 通常情况下更新或删除单条数据都是以ID字段(主键)作为条件
update tb_student set sbirth='1995-4-22',saddr='乌鲁木齐' where sname='朱林易';
update tb_student set sname='大帅比' where stuid=1002;
update tb_student set saddr='大美新疆' where stuid in (1001,1002,1003);

E-R图(实体关系图)

将实体和实体的属性用图像来展示,分析出实体与实体之间的关系
一对一关系 1-1
一对多关系(多对一)  1-N
多对多关系  M-N
椭圆框表示属性 方框表示实体 菱形框表示联系成因

将两个表之间创建关系连接

create table tb_person
(
personid int not null auto_increment,  -- 自增字段(此列会自增,不用复制)
pname varchar(20) not null,
pbirth date,
primary key (personid)
);

create table tb_idcard
(
carid char(18) not null,
cpolici varchar(20) not null,
cexpire date not null,
pid int not null,
primary key (carid)
);

-- 外键约束
alter table tb_idcard add constraint fk_idcard_pid
foreign key (pid) references tb_person(personid);

-- 唯一性约束
alter table tb_idcard add constraint uk_idcard_pid
unique(pid);

insert into tb_person(pname,pbirth) values
('朱林易','1995-4-22'),
('黑鬼哥哥','1995-04-22');

insert into tb_idcard values
('650103199504221444','乌鲁木齐','2030-2-22',1),
('650103199504221331','乌鲁木齐','2030-2-23',2);

-- 可以理解为加了外键约束变成一对多 加了外键约束和唯一性约束变成一对一
-- 而多对多需要通过第三张表来实现

-- scid int not null auto_increment scid为自增值,不用设置
-- on delete cascade; -- 级联删除,即删除用户时将用户的订单也一起删除
-- on update cascade  级联更新

关系型数据库中数据完整性指的是什么?

1:实体完整性:每条记录都是第一无二的(主键/唯一约束/唯一索引)
2:参照完整性:表中的数据要参照其他表已有的数据(外键)
3:域完整性:数据是有效的(数据类型/非空约束/默认值约束/检查约束)

表的设计原则

范式理论(1NF/2NF/3NF/BCNF)
范式级别指的是表设计的规范程度,范式级别越高规范程度也就越高
范式级别越高在插入/删除/更新数据时可能发生的问题就越少,而且表中的数据冗余程度(重复)也就越低
实际开发中往往会降低范式级别来提升查询数据的性能
1NF -列的属性值不能够再拆分
2NF -除了主键列之外的列要完全依赖于主键
-- 场景:不同学院的学生可能有相同的学号
-- 学生表(stuid,sname,ssex,did,dname,dtel)
-- 主键(stuid,did)
这种依赖是部分依赖而不是完全依赖所以不满足2NF
3NF -消除传递依赖
-- 场景:整个学校学生的学号是唯一的
-- 学生表:(stuid,sname,ssex,did,dname,dtel)
-- 主键(stuid)

DCL(数据控制语言)

-- DCL
-- 授予权限和召唤权限
-- 创建用户
create user hellokitty identified by'123456';
-- 修改密码
alter user hellokitty identified by'654321'
-- 授权
grant all on school.tb_student to hellokitty;
-- 收回权限
revoke all on school.tb_student from hellokitty;
-- 只给只读权限
grant select on school.tb_student to hellokitty;
-- 将school下的所有表给hellokitty
grant all on school.* to hellokitty;
-- 将所有库所有表所有权限给hellokitty
grant all on *.* to hellokitty;
-- 将所有库所有表的权限收回
revoke all on *.* from hellokitty;
-- 删除用户
drop user hellokitty;

DQL(查询)

-- 查询所有学生信息
select * from tb_student;
select * from tb_course;
-- 笛卡尔积
select * from tb_student,tb_course;
-- 如果想进行字符串拼接 使用concat函数
select concat(job,':',ename) as title,
(sal+ifnull(comm,0))*13 as annsal
from tbemp order by annSal desc;
--ifnull函数 如果是空值取后面的,不是空取前面的.
-- 投影和别名: 查询所有课程名称及学分
select sname as 姓名,ssex as 性别 from tb_student; -- as可以省略,但是最好不要省略
select cname as 课程名称,ccredit as 学分 from tb_course;
select sname as 姓名,if(ssex,'男','女') as 性别 from tb_student;   -- MySQL专用
select sname as 姓名,case ssex when 1 then '男' else '女' end as 性别 from tb_student; -- 通用写法
-- 筛选: 查询所有女学生的姓名和出生日期
-- = / <> / < / > / <= / >=
select sname,sbirth from tb_student where ssex=0;
-- 筛选学分大于2个学分的课程的名称和编号
select cname,courseid from tb_course where ccredit>2;
-- 范围筛选: 查询所有80后学生的姓名、性别和出生日期
select sname,ssex,sbirth from tb_student where '1980-1-1' <= sbirth and sbirth <= '1989-12-31';
select sname,ssex,sbirth from tb_student where sbirth between '1980-1-1' and '1989-12-31';
-- 模糊查询: 查询姓王的学生姓名和性别
-- 通配符 %(0个或多个) _(一个)
select * from tb_student where sname='杨过';
select * from tb_student where sname like '杨%';
-- 模糊查询: 查询姓杨名字总共两个字的学生的姓名
select sname from tb_student where sname like'杨_';
-- 模糊查询: 查询姓杨名字总共三个字的学生的姓名
select sname from tb_student where sname like'杨__';
-- 模糊查询: 查询名字中有杨字的学生的姓名(模糊)
select * from tb_student where sname like '%杨%';
-- MySQL 支持正则表达式
select * from tb_student where sname regexp '^[张杨].+' -- 写的不对,大致格式
-- 多条件和空值处理: 查询没有录入生日和家庭住址的学生姓名 -- 如果判断不是空值就是 is not null
select * from tb_student where sbirth is null and saddr is null;
-- 去重: 查询学生的籍贯
select distinct saddr from tb_student where saddr is not null; -- distinct 可以进行出重处理
-- 排序: 查询学生的姓名和生日按年龄从大到小排列
-- 默认值为asc从小到大
-- 如果改为desc则改为从大到小
select sname,sbirth from tb_student where sbirth is not null order by sbirth desc;  --      如果要筛选的话要先筛选 后排序 
-- 筛选和排序: 查询所有录入了家庭住址的男学生的姓名、出生日期和家庭住址按年龄从小到大排列
select sname,sbirth,saddr from tb_student where saddr is not null and ssex=1 order by sbirth desc;
-- 聚合函数: 查询年龄最大的学生的出生日期
-- MySQL特有的函数:now()/if()
-- 聚合函数  min() max() sum() avg()求平均 count()计数 在任意数据库都支持
select min(sbirth) from tb_student;
select max(sbirth) from tb_student;
-- 分组查询: 查询男女学生的人数
-- 经验:在使用group by 时,如果不希望执行默认的排序操作
-- 可以在分组后使用order by null来避免默认的排序操作提升查询性能

-- 筛选(where)-分组(group by)-筛选(having)-排序(order by)
select count(stuid) from tb_student where ssex=1;
select ssex,count(stuid) from tb_student group by ssex;
select if(ssex,'男','女') as 性别,count(stuid) as 人数 from tb_student group by ssex;
select if(ssex,'男','女') as 性别,count(stuid) as 人数 from tb_student where saddr is not null
group by ssex order by ssex desc; -- 先筛选再分组再排序
select case ssex when 1 then '男' else '女' end as 性别,count(stuid) as 人数 from tb_student where saddr is not null
group by ssex;
-- 聚合函数: 查询课程编号为1111的课程的平均成绩
select cid,avg(score) from tb_sc where cid=1111;  -- 聚合函数会自动排出空值
-- 聚合函数: 查询学号为1001的学生所有课程的平均成绩
select sid,avg(score) from tb_sc where sid=1001;
-- 查询平均分未及格的课程
-- where 子句构造的筛选是分组以前的筛选
-- 如果希望对分组以后的数据进行分组进行筛选那么要写having子句
select cid,avg(score) from tb_sc group by cid having avg(score)<60;
-- 分组查询和空值处理: 查询每个学生的学号和平均成绩
select sid,avg(score) from tb_sc group by sid order by avg(score);
-- 查询平均分低于60的学生的id
select sid,avg(score) from tb_sc group by sid having avg(score)<60;

-- 子查询: 查询年龄最大的学生的姓名
select sname,sbirth from tb_student where sbirth=(select min(sbirth) from tb_student);
select sname,sbirth from tb_student where sbirth=(select max(sbirth) from tb_student);

-- 子查询: 查询选了两门以上的课程的学生姓名
select sname,stuid from tb_student
where stuid in (
select sid from tb_sc 
group by sid having count(sid)>2) and ssex=1;

-- 连接查询: 查询选课学生的姓名和平均成绩
select sname,avgScore from tb_student,
(select sid,avg(score) as avgScore from tb_sc
group by sid) t
where stuid=sid;
-- 内连接只显示符合条件的连接
select sname,avgScore from tb_student
inner join
(select sid,avg(score) as avgScore from tb_sc
group by sid) t
on stuid=sid;

-- 左外连接: 查询每个学生的姓名和选课数量
select sname,totle from tb_student,
(select sid,count(sid) as totle from tb_sc
group by sid) t
where sid=stuid; 

-- 左外连接:左表不满足连表条件的记录也要查询出来
select sname,if(total is not null,total,0) from tb_student 
left outer join
(select sid,count(sid) as total from tb_sc
group by sid) t2
on stuid=sid

-- 右外连接
select sname,if(total is not null,total,0) from
(select sid,count(sid) as total from tb_sc
group by sid)t2 right outer join tb_student t1
on stuid=sid;

-- 分页查询(只有MySQL支持)
select sname,cname,score
from tb_sc,tb_student,tb_course
where sid=stuid and cid=courseid
limit 0,5; -- (从0条开始,查5条,计数规则和索引相似)

-- 经验:尽可能不适用distinct去重和in集合运算
-- SQL优化
-- 想去掉distinct和in运算可以使用exists和not exists操作
select ename,job from tbemp t1
where exists (select 'x' from tbemp t2 where t1.empno=t2.mgr);

索引

创建索引(索引相当于是一个目录,它可以加快查询提升查询效率)
create index idx_emp_ename on TbEmp(ename);
查看索引
show index from TbEmp;
删除索引
drop index idx_emp_ename
索引:用空间换取时间 
创建索引后增删改都会变慢,只有查询会变快
那个字段查询的次数最多,就将索引建在这个字段上

视图

创建视图
create or replace view 视图名 as 查询语句 ;
查看视图
select * from 视图名;
通过视图可以将用户对表的查询权限限制在某些列上
也就是说不同的用户可以看到原始表的不同列的数据
grant select on a.视图名 to user

存储过程

函数和过程
作用:分装重复的操作
区别:函数可以产生返回值而过程没有
函数和过程都是存储在数据库服务器端编译好的代码,所以直接调用函数和过程其执行效率比直接向数据库发出SQL语句更高.
如果希望简化调用并改善性能就可以考虑使用存储过程

创建存储过程
drop procedure if exists sp_dept_avg_sal
create procedure sp_dept_avg_sal(
	deptNo integer,	   -- 作用:传入部门标号,返回平均工资
	out avgSal float   -- out 输出参数
)
begin
select avg(sal) into avgSal from TbEmp where dno=dnoNo;
end;
调用存储过程
call sp_dept_avg_sal(20 @avgSal) -- MySQL变量名必须以@开头
select @avgSal;

在python中操作MySQL

在pip中 pip install pymysql
import pymysql

# Connection(连接) / Cursor(游标)
def main():
    #创建Connection对象
    conn =  pymysql.connect(host='localhost',port=3306,user='root',passwd='zly1995422',db='hrs',charset='utf8')# 主机名 端口号 用户名 密码 库名 编码方式
    try:
        # 创建游标对象
        #Cursor对象支持上下文语法可以放在with中
        with conn.cursor() as cursor:
            # 向数据库发出语句
            #cursor.executemany()是一次性执行多语句
            #execute的返回值为受影响的行数
            dno= input('部门编号:')
            dname = input('部门名称:')
            dlog = input('部门所在地:')
            result = cursor.execute('insert into tbdept values (%s,%s,%s)',(dno,dname,dlog)) #安全性更高 占位符写法
            # result = cursor.execute('insert into tbdept values (%(no)s,%(name)s,%(loc)s)',{'no':dno,'name':dname,'loc':dlog}) 用字典来写
            print(result)
            # 手动提交之前的操作
            # conn.commit()
    except:
    	conn.rollback()
    finally:
        conn.close()

if __name__ == '__main__':
    main()

在python中使用MySQL查询

import pymysql

# Connection(连接) / Cursor(游标)
def main():
    #创建Connection对象
    conn = pymysql.connect(host='localhost',port=3306,user='root',passwd='zly1995422',db='hrs',charset='utf8')
    try:
        # 创建游标对象
        #Cursor对象支持上下文语法可以放在with中
        with conn.cursor() as cursor:
            # 向数据库发出语句
            #cursor.executemany()是一次性执行多语句
            #execute的返回值为受影响的行数
            #一般不使用fetchall()
            cursor.execute('select dno,dname,dloc from tbdept')
            result = cursor.fetchone() #cursor.fetchmany读取指定的条数
            # cursor.fetchmany的返回值为元祖,想要特定的元素可以使用下标运算
            print(result[0])
            '''
            如果想取出所有可以
            result = cursor.fetchone()
            while result:
                print result
                result = cursor.fetchone()
            '''
            # 手动提交之前的操作
            # conn.commit()
    finally:
        conn.close()

if __name__ == '__main__':
    main()

将游标获取得值转化为字典,方便访问

import pymysql

from text3 import Dept


def main():
    conn = pymysql.connect(host='localhost',port=3306,user='root',passwd='zly1995422',db='hrs',charset='utf8',cursorclass=pymysql.cursors.DictCursor)
    # cursorclass=pymysql.cursors.DictCursor 指定游标的类型,此时拿出的result就是字典了
    try:
        with conn.cursor() as cursor:
            cursor.execute('select dno,dname,dloc from tbdept')
            result = cursor.fetchone()
            while result:
                dept = Dept(**result)
                print(dept.name)
                result = cursor.fetchone()
            # conn.commit()
    finally:
        conn.close()

if __name__ == '__main__':
    main()
    
 在另一个表中
 class Dept(object):
    def __init__(self,dno=None,dname=None,dloc=None,**kwargs):  # 要和表中的列名保持一致,赋予None值假设在查询过程中没有查该列也不会报错
        self._no=dno
        self._name=dname
        self._loc=dloc

    @property
    def no(self):
        return self._no

    @property
    def name(self):
        return self._name

    @property
    def loc(self):
        return self._loc


关系型数据库 - 关系模型
Python程序  - 对象模型
ORM - Object Relation Mapping 对象关系映射
Alchemy 第三方库 完成对象关系的双向转换

常见报错

Cannot connect 不能连接
常见错误:host写错 port写错 服务器没有启动
Access denied 访问被拒绝
常见错误:user写错 passwd写错 账号不允许远程连接
Unknown database 数据库名字写错了
MySQL syntax Error / unknow 
SQL 语句错误
默认情况root 只能本地连接,不能远程连接, 主机改为 % 

事务(Transaction/tx)

原子性操作(不可分割的操作)
如 有A,B,C,D,E 五件事 做了A,B 但是C事件失败了 此时要撤销A,B操作 并且不执行C,D,E操作
# 事务的特点:--ACID特性
1:原子性(Atomicity):不可分割,要么全成功要么全失败
2:一致性(Consistency):事务前后数据状态要保持一致  
3:隔离性(Isolation):多个事务不能看到对方的中间状态(提交或者回滚之前的状态)
4:持久性(Duration):事务完成后数据要持久化(事务的影响要反应在物理存储上)

def main():
    #创建Connection对象
    conn =  pymysql.connect(host='localhost',port=3306,user='root',passwd='zly1995422',db='hrs',charset='utf8')# 主机名 端口号 用户名 密码 库名 编码方式
    try:
        # 创建游标对象
        #Cursor对象支持上下文语法可以放在with中
        with conn.cursor() as cursor:
            # 向数据库发出语句
            #cursor.executemany()是一次性执行多语句
            #execute的返回值为受影响的行数
            dno= input('部门编号:')
            dname = input('部门名称:')
            dlog = input('部门所在地:')
            result = cursor.execute('insert into tbdept values (%s,%s,%s)',(dno,dname,dlog)) #安全性更高 占位符写法
            #
            print(result)
            # 手动提交之前的操作
            # 如果事务中所有的操作都成功了,则最后手动提交事务
            # conn.commit()
    except:
    	# 如果事务中的操作有任何一个发生了异常错误,则回滚事务
    	conn.rollback()
    finally:
        conn.close()

if __name__ == '__main__':
    main()
    
    
begin;
update tb_account set balance=balance-1000 where addid='1111';
update tb_account set balance=balance+1000 where addid='1122';
rollback; -- 撤销
commit; -- 提交

非关系型数据库

2008 --- Big Data  大数据时代
-- 关系型数据库(锁) -数据价值高强一致性
用NoSQL对MySQL进行补充
-- NoSQL的常见数据库
-- Redis --高速缓存 -键值对数据库
   MongoDB --存放价值不高结构不严谨的数据 -文档数据库
   Neo4j --社交网站 -图数据库(适合做数据间的关联挖掘)
   HBase --列族数据库 (将数据存放在列中)

Redis

修改配置文件
启动Redis: redis-server myredis.conf &  在后台运行
如果想关闭 可以直接kill 进程号 注意:不要用kill -9   数据会丢失
或者 jobs fg %后台号  拿到前台之后 Ctrl+c
172.16.51.47
! 注意,记得关闭Linux下的防火墙
用客户端连接 redis-cli -h 47.98.171.73 -p 11223  (-h公网ip,-p端口号)

Redis的操作指令

redisdoc.com

set key values 设置键名 和值
get key 取key的值
del key 删除键
set foo hello ex 300  设置300秒后删除键
ttl key 查看剩余存活时间
(-2表示键不存在,-1表示键恒存在)
expire username 15 设置已经存在的键剩余时间
bgsave 后台保存
select num 切换库
flushdb 将库中所有数据清除
flushall  删除所有库的所有数据
dbsize 查看库中键值对的数量
shutdown save 关闭服务器并保存
shutdown nosave 关闭服务器不保存数据
incr key +1
incrby key 50  加50
incrbyfloat key 1.23 加1.23
-- 投票类的应用不能用关系型数据库的updata,因为效率会很低,这时就要用到redis 的 incr
strlen username  返回值的长度
append 追加内容
type key  查键的类型

数据类型

字符串(String)
哈希(Hash)
列表(List)
集合(Set)
有序集合(SortedSet)
地理位置(GEO)

哈希

类似字典中嵌套字典,适合保存对象
hset student1 age 38
hset student1 name zhulinyi
hget student1 name
hgetall student  拿出所有键值
! 如果写汉字 会存入utf-8编码
删除哈希的一条信息
hdel student1 name
删除哈希里的所有信息
del student1

hexists 20 name  查看20里有没有name这个字段
有则返回1,无则返回0
hincrby 20 dno 20(增加数)  给20部门的dno增加20

列表

lpush foo(key) 10 20 30 40
lrange foo 0 -1
'40' '30' '20' '10'
lrange foo 0 0  取第一个
lrange foo 1 1  取第二个
rpush foo 10 20 30 40  放右边
'10' '20' '30' '40'
rpop foo 从右边删除一个  删除后元素就不在列表中了
lindex foo num 按索引查看元素
linsert foo before 元素 值   在指定位置插入
lrem foo 2 999 删除列表中2个999

应用场景:生产者,消费者模型微博应用,关注人发了帖子,放入消息队列,做到发消息的人和收消息的人不用耦合.

集合

不能放重复的元素
sadd foo 10 10 20 
smembers foo
-- 10 20
sinter 集合1 集合2 (求交际)
sunion 集合1 集合2 (求并集)
srem foo 20  删除集合中的元素
scard foo  返回集合中的个数

有序集合

zadd foo 100 hello 75 good 102 world 300 apple
取元素会根据给的值进行排序 
zrange foo 0 -1  (由低到高)  zrevrange foo 0 -1 (由高到低)
zincrby foo 400 hello  给hello加400

在Python中使用redis

导入redis模块
import redis

def main():
    client = redis.Redis(host='47.98.171.73',port=11223 ,password='zly1995422')
    if client.ping():
        print(client.keys('*'))
        print(client.get('fun').decode('utf-8'))
        print(list(map(lambda x:x.decode('utf-8'),
                       client.zrange('foo',start=0,end=-1))))

一主三从 读写分离

* 读写分离
  * 一台 master 写操作   三台  slave(奴隶)读取  实验
  * slaveof [IP]    120.77.2.217 11223  给该IP 做slave
  * info replication  查看连接情况查看
  * 更改 config 文件   265 写入slaveof IP port  272   写入 master密码
  * cp myredis.config  更改端口可以在一个电脑上开多个redis服务器



* master 停止服务时 , 让其他的slave 扮演 master 
  * 让自动完成  哨兵   sentinel.config
    * 更改 sentinel.config     复制一份更改配置
      *  15 - bind 内网地址       绑定内网地址 ,访问用公网地址 
      * 17 -  protect-mode yes
      * 70 行sentinel monitor master + IP + port 1(票数,哨兵数/2) 开端口
      * 73 - 改名字和密码  master
    * 启动哨兵
      * redid-server sentinel.conf  --sentinel  -  
    * 脚本  - -LUA 定义新的命令    
    * 集群   --Cluster   分区操作, 将多个节点变为一个节点 , 轮转
      * yum install rubby
      
 哨兵配置     
    bind 172.18.61.250
    port 26379
    sentinel monitor mymaster 120.77.222.217 11225 1
    sentinel down-after-milliseconds mymaster 5000 
    sentinel auth-pass mymaster 1qaz2wsx

建表语句总结

create table ihome_house(
id int not null auto_increment,   #设置id非空并且自增
primary key(id),     #将id设置为主键
create_time datetime,    #设置创建时间类型
user_id int not null,
foreign key(user_id) REFERENCES ihome_user(id),  #关联ihome_user的id属性为外键
capacity int default 1  #设置默认值
)

Mongodb使用指南

MongoDB是2009年问世的一个面向文档的数据库管理系统,由C++语言编写,旨在为Web应用提供可扩展的高性能数据存储解决方案。虽然在划分类别的时候后,MongoDB被认为是NoSQL的产品,但是它更像一个介于关系数据库和非关系数据库之间的产品,在非关系数据库中它功能最丰富,最像关系数据库。

MongoDB将数据存储为一个文档,一个文档由一系列的“键值对”组成,其文档类似于JSON对象,但是MongoDB对JSON进行了二进制处理(能够更快的定位key和value),因此其文档的存储格式称为BSON。关于JSON和BSON的差别大家可以看看MongoDB官方网站的文章《JSON and BSON》。

目前,MongoDB已经提供了对Windows、MacOS、Linux、Solaris等多个平台的支持,而且也提供了多种开发语言的驱动程序,Python当然是其中之一。

Windows:
安装Mongodb之后需要创建data文件夹和db文件夹
进入bin目录
输入如下指令运行  :
mongod --dbpath D:\mongodb\data\db

linux:
wget获取mongodo
wget地址:wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-amazon-3.6.5.tgz
gunzip解压缩
gunzip是个使用广泛的解压缩程序,它用于解开被gzip压缩过的文件

解压,并指定安装到刚创建的mongodb-3.6.5中,并去除掉第一级的目录结构(--strip-components number参数)

mkdir mongodb-3.6.5

tar -xvf mongodb-linux-x86_64-amazon-3.6.5.tar --strip-components 1 -C mongodb-3.6.5/
3.4 设置环境变量,启动mongod
启动mongod:

export PATH=$PATH:~/mongodb-3.6.5/bin
mkdir -p /data/db
mongod --bind_ip 45.76.206.145

启动mongo,然后就可以愉快的使用mongodb进行玩耍啦:
mongo --port 45.76.206.145


设置配置文件mongodb.conf
vi mongodb.conf

dbpath = /home/mongodb/data/db #数据文件存放目录

logpath = /home/mongodb/logs/mongodb.log #日志文件存放目录
port = 27017  #端口
fork = true  #以守护程序的方式启用,即在后台运行
nohttpinterface = true
auth=true
bind_ip=0.0.0.0
启动mongo命令: mongod -f mongodb.conf

sql和mongodb对比

SQL			mONGOdb			解释
database	database		数据库/数据库
table		collection		二维表/集合
row			document		记录(行)/文档
column		field			字段(列)/域
index		index			索引/索引
table joins    --			表连接/嵌套文档
primary key	primary key		主键/主键(_id字段)

常用指令

show dbs  展示数据库
use db 创建并切换到数据库
db.dropDatabase()  删除数据库
db.createCollection('colleges')  创建colleges集合
show collections 查看所有集合
db.colleges.drop() 删除colleges集合

向集合中插入文档
db.test.insert({s_id:1,name:'朱林易',age:18})

查看所有文档
db.student.find()

更新s_id为1的文档
db.students.update({'s_id':1},{'$set':{'age':16}})

插入或更新s_id为3的文档
db.students.update({s_id:3},{'$set':{'name':'小妲己', tel: '13022221333'}})

>> // 查询s_id大于2的文档只显示name和tel字段
> db.students.find({s_id: {'$gt': 2}}, {_id: 0, name: 1, tel: 1}).pretty()

>> // 查询s_id大于2的文档除了不显示name和tel字段的其他字段
> db.students.find({s_id:{'$gt':2}}, {s_id:0, name:0, _id:0})
{ "gender" : "女", "tel" : "13022221333" }

>> // 查询s_id大于2的文档只显示_id和name和tel字段
> db.students.find({s_id:{'$gt':2}}, {s_id:1, name:1, _id:1})
{ "_id" : ObjectId("5b24b30d4717832ad090f2f5"), "s_id" : 3, "name" : "小妲己" }

筛选查询:
>>// 查询学生文档跳过第1条文档只查1条文档
> db.students.find().skip(1).limit(1).pretty()
{
	"_id" : ObjectId("5b24b0ba165a0f78dbf82a14"),
	"s_id" : 2,
	"name" : "王帅帅",
	"tel" : "12334566789",
	"gender" : "男"
}


> // 对查询结果进行排序(1表示升序,-1表示降序)
> db.students.find().sort({s_id: -1})
{ "_id" : ObjectId("5b24b30d4717832ad090f2f5"), "s_id" : 3, "gender" : "女", "name" : "小妲己", "tel" : "13022221333" }
{ "_id" : ObjectId("5b24b01f165a0f78dbf82a12"), "s_id" : 2, "name" : "王帅帅", "tel" : "12334566789", "gender" : "男" }
{ "_id" : ObjectId("5b24b0ba165a0f78dbf82a14"), "s_id" : 2, "name" : "王帅帅", "tel" : "12334566789", "gender" : "男" }
{ "_id" : ObjectId("5b24b0dc165a0f78dbf82a15"), "s_id" : 1, "name" : "王大帅", "tel" : "12334566786", "age" : 16 }