01-数据库管理服务
数据库管理系统
数据库介绍
数据是应用的核心
按照结构组织、存储和管理数据的参仓库
可视为电子化的文件柜(增删改查)
数据挖掘透视表象背后的真相
- 关系型数据库
- 库、表、字段、记录
- SQL
- 非关系型数据库NoSQL
- 大数据技术的发展暴露出关系型数据库的问题
- 存储不同格式的数据类型(文件型数据)
- 图形数据库、文档数据库、键值对数据库、大表
- NoSQL并非取代SQL,而是互补
数据库管理系统
- Database Management System (DBMS)
- 操纵和管理数据库的软件
- 功能作用
- 数据定义 , 定义数据结构及完整性机密性约束
- 数据操作
- 运行管理,多用户、安全性、存取限制、事务管理、自动恢复
- 组织与存储 分类管理各种数据
- 数据保护 恢复、并发控制、完整性、机密性
- 数据库维护 数据载入、转换、重组重构
- 通信 OS接口、网络通信
MySQL安装配置
1 | sudo apt install mysql-server |
安全配置
1 | sudo mysql_secure_installation |
root账号密码登录
1 | sudo mysql |
1 | --创建账户 |
网络访问账号
1 | --进入mysql库 |
1 | sudo netstat -pantu | grep 3306 |
此时mysql只是监听在127.0.0.1这个本机地址,需要更改配置文件
1 | sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf |
找到bind-address 后面改为网卡ip地址 sudo systemctl restart mysql.service
再次进入mysql,执行select @@validate_password_policy
,此时密码等级提升到了MEDIUM
SQL语句
1 | --当前账户 |
创建表
1 | mysql> create table users(id int not null primary key auto_increment, |
表数据描述:
包含4列:id、uname、pass、age
- int(5):数据类型为整数(长度5)
- not null:字段不能为空
- primary key:主键(不能包含重复数据)
- auto_increment:自动增长
- char(25):固定长字符串(是字符数,不是字节数)
- varchar(20):可变长字符串
- text:最大64KB文本可变长字符串
- date:日期值(年,月,日)
- time:时间值(时,分,秒)
- enum(’value1’, ‘value2’):枚举值列表
插入数据
1 | insert into users values(null ,'cwz', '123', 20); --要与字段名一一对应 |
查看表结构
1 | desc users; |
查询
1 | select * from users; # 查询所有信息 |
修改数据
1 | update users set age=18 where id=2; |
删除数据
1 | delete from users where id=2; |
删除表
1 | drop table users; |
删除库
1 | drop database test; |
查看数据引擎
1 | show engines; |
修改表名
1 | alter table users rename user; |
修改字段数据类型
1 | alter table user modify uname varchar(30); |
修改字段名
1 | alter table user change uname username varchar(30); |
增加字段
1 | alter table user add tel char(20) not null after pass; |
删除字段
1 | alter table user drop tel; |
数据库备份
备份数据库、表
1 | mysqldump -uroot -p test > db_bak.sql # 备份库 |
备份指定数据
1 | echo 'select * from user;' > q.sql |
在mysql界面备份
1 | mysql> show variables like "%secure%"; |
在终端导入
1 | mysqladmin -u root -p create db2; # 创建库db2 |
在MySQL中导入csv文件
1 | load data infile '/var/lib/mysql-files/a.csv' into table user; |
MariaDB
与MySQL类似,是MySQL的开源版本
安装
1 | sudo apt install mariadb-server |
安全设置
1 | mysql_secure_installation |
改为密码认证
1 | sudo mysql |
配置文件
1 | /etc/mysql/mariadb.conf.d/50-server.cnf |
数据库主从复制
如果服务器的硬件出现问题了,就会对企业有很大影响。所以数据库需要定期备份。
复制Replication
- Master——>Slave # 主备服务器,master坏了,slave可以读,升级成为Master
- 限定所有库、指定库、表进行复制
MySQL的主从复制是MySQL本身自带的一个功能,不需要额外的第三方软件就可以实现,其复制功能并不是copy文件来实现的,而是借助binlog日志文件里面的SQL命令实现的主从复制,可以理解为我再Master端执行了一条SQL命令,那么在Salve端同样会执行一遍,从而达到主从复制的,同步数据的效果。
主从复制原理
MySQL中有一种日志叫做 bin 日志(二进制日志)。这个日志会记录下所有修改了数据库的SQL 语句
MySQL的主从复制是MySQL本身自带的一个功能,不需要额外的第三方软件就可以实现,其复制功能并不是copy文件来实现的,而是借助binlog日志文件里面的SQL命令实现的主从复制。可以理解为我在Master端执行了一条SQL命令,那么在Salve端同样会执行一遍,从而达到主从复制的效果。
- 从库生成两个线程,一个I/O线程,一个SQL线程;I/O线程去请求主库 的binlog,并将得到的 binlog日志 写到relay log(中继日志) 文件中;
主库会生成一个 log dump 线程,用来给从库 I/O线程传binlog; SQL 线程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致。
bin-log 二进制日志
- 所有DB事件写入bin-log
- Slave从Master读取bin-log
复制过程
- 主节点必须启用二进制日志,记录任何修改了数据库数据的事件。
- 从节点开启一个线程(I/O Thread)把自己扮演成 mysql 的客户端,通过 mysql 协议,请求主节点的二进制日志文件中的事件
- 主节点启动一个线程(dump Thread),检查自己二进制日志中的事件,跟对方请求的位置对比,如果不带请求位置参数,则主节点就会从第一个日志文件中的第一个事件一个一个发送给从节点。
- 从节点接收到主节点发送过来的数据把它放置到中继日志(Relay log)文件中。并记录该次请求到主节点的具体哪一个二进制日志文件内部的哪一个位置。
- 从节点启动另外一个线程(sql Thread ),把 Relay log 中的事件读取出来,并在本地再执行一次。
主从复制中线程的作用
从节点
- I/O Thread: 从 Master 节点请求二进制日志事件,并保存于中继日志中。
- Sql Thread: 从Relay log 中读取日志事件并在本地完成重放。
- 如果从节点需要作为其他节点的主节点时,是需要开启二进制日志文件的。这种情况叫做级联复制。如果只是作为从节点,则不需要创建二进制文件。
主节点
- Dump Thread:为每个 Slave 的 I/O Thread 启动一个 dump 线程,用于向从节点发送二进制事件。
MySQL复制的特点
- 异步复制:主节点中一个用户请求一个写操作时,主节点不需要把写的数据在本地操作完成同时发送给从服务器并等待从服务器反馈写入完成,再响应用户。主节点只需要把写入操作在本地完成,就响应用户。但是,从节点中的数据有可能会落后主节点,可以使用(很多软件来检查是否落后)
- 主从数据不一致。
用途
- 扩展:Slave分担master负载
- 分析:数据分析不影响Master
- 备份:作为一种数据备份手段
- 分布:异地保存数据副本(应用访问本地库)
安装两台独立的MariaDB服务器
- 复制前用导入导出数据库的方式保持M / S数据一致
- 复制前锁定库(禁止写入)
- flush tables with read lock;
复制Master
1 | sudo vi /etc/mysql/conf.d/mysql.cnf |
配置Master
1 | sudo mysql |
最后重启MariaDB服务
配置Slave
1 | sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf |
1 | sudo mysql |
打开MASTER锁
1 | -- 如果在做复制配置之前,锁定了数据库表,可以解锁: |
查看SLAVE状态
1 | start slave; |
这样数据同步就完成了,可以在master这边修改数据,slave可以实时同步
配置调优工具包
1 | sudo apt install mysqltuner |
Postgresql
- 下一代关系型数据库
- 高并发情况下性能优于MySQL
- 侦听端口 TCP 5432
- 安装
sudo apt install postgresql
- 身份认证
- 默认使用IDENT身份认证方式
- 使用与操作系统同名的数据库账号
sudo -u postgres psql temlpate1
修改密码
1 | alter user postgrep with encrypted password 'your_password'; |
配置文件
1 | /etc/postgresql/<version>/main # 配置文件目录 |
NoSQL概览与Mongdb
NoSQL介绍
NoSQL是一类数据库的统称
- 每种NoSQL数据库为特定目的而设计
- NoSQL不是也不可能成为SQL数据库的代替者
- 适用于大数据集、高并发、大流量的应用场景
- 并非完全不用SQL语句
NoSQL的共性
- 存储结构化数据、但不存储数据关系
优点:
- 处理巨大数据集
- 按需扩展(横向增加主句节点)
- 硬件透明,TOC低(传统小机)
- 数据模型松散,方便修改,不下线,快速dirty修复
缺点:
- 大部分来自于小型开源项目,缺少技术支持,学习曲线陡峭,部署周期长
- 并不总是符合ACID(原子性、一致性、隔离性、持久性)
- 不保证即时正确记录,多主复制无法保证最新数据(适合互联网,不适合金融)
- NoSQL,没有绝对优势
- 使用已知的技术栈,需要时再迁移(过早优化是万恶之源)
Berkeley DB
Cassandra
Memcached/MemcacheDB
Redis
Riak
Document Stores
CouchDB
MongoDB
安装配置MongoDB
1 | sudo apt install mongodb |
登录
1 | mongo 直接本机登录 |
mongodb组织数据的基本形式
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
mongodb操作
库的管理语句
显示所有的库 show dbs
1
2
3
4> show dbs
admin (empty)
local 0.078GB
>切换数据库 use 数据库名
1
2
3> use mydb
switched to db mydb
>查看所在库 db
1
2
3
4
5
6
7
8
9
10> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
mydb 0.000GB
> show collections
users
>删除库 db.dropDatabase()
1
2
3> db.dropDatabase()
{ "dropped" : "test", "ok" : 1 }
>
MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中。
集合的管理语句
创建集合
1
2
3> db.createCollection('student')
{ "ok" : 1 }
>显示当前集合
1
2
3
4> show collections
student
system.indexes
>删除集合
1 | > db.student.drop() |
数据的增删改查操作
- 插入数据插入多条数据
1
2
3> db.student.insert({name:'reese',age:29})
WriteResult({ "nInserted" : 1 })
>1
2
3
4
5
6
7
8
9
10
11
12
13
14> db.student.insert([
... {name:'neo',age:59,sex:'男'},
... {name:'cwz',sex:'男',age:20,addr:'mon'}])
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 2,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
> 查询数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35> db.users.find()
{ "_id" : ObjectId("5db841899ea8d30495ed512b"), "name" : "neo", "uid" : "1001" }
{ "_id" : ObjectId("5db842269ea8d30495ed512c"), "name" : "lisi", "uid" : 1003, "gid" : [ 1001, 1002, 1003 ] }
>
> db.users.findOne({uid:1003})
{
"_id" : ObjectId("5db842269ea8d30495ed512c"),
"name" : "lisi",
"uid" : 1003,
"gid" : [
1001,
1002,
1003
]
}
> db.users.findOne({uid:{$gt:1002}}) # gt great than 大于
{
"_id" : ObjectId("5db842269ea8d30495ed512c"),
"name" : "lisi",
"uid" : 1003,
"gid" : [
1001,
1002,
1003
]
}
>
# 默认自动生成_id 字段美观查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20> db.student.find().pretty()
{
"_id" : ObjectId("5b6a3edbbb74e74630ea80f9"),
"name" : "reese",
"age" : 29
}
{
"_id" : ObjectId("5b6a4088bb74e74630ea80fa"),
"name" : "neo",
"age" : 59,
"sex" : "男"
}
{
"_id" : ObjectId("5b6a4088bb74e74630ea80fb"),
"name" : "cwz",
"sex" : "男",
"age" : 20,
"addr" : "mon"
}
>修改数据
全文档更新,普通更新1
2
3> db.student.update({name:'cwz'},{xx:'yy'})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
>
指定更新,只会更新第一条数据1
2> db.student.update({name:'reese'},{$set:{age:46}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
全部更新1
2> db.student.update({name:'reese'},{$set:{age:34},{multi:true})
- 删除数据
1
2
3
4
5
6
7> db.student.remove({name:'cwz'})
# 不加参数会删除所有数据
> db.student.remove({name:'cwz'},{justone:1})
# 删除一条数据
python操作mongodb
建立连接1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import pymongo
# 建立连接
client = pymongo.MongoClient('127.0.0.1', 27017)
# 获取数据库
db = client['test']
# 获取集合
col = db['student']
# 测试一下是否成功
data = col.find()
print(data)
主要方法:
- insert_one
- insert_many
- update_one
- update_many
- delete_one
- delete_many
- find_one
- find
find_one1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import pymongo
# 建立连接
client = pymongo.MongoClient('127.0.0.1', 27017)
# 获取数据库
db = client['test']
# 获取集合
col = db['student']
# 测试一下是否成功
data = col.find_one()
print(data)
# 打印结果:
{'_id': ObjectId('5b6a3edbbb74e74630ea80f9'), 'age': 46.0, 'name': 'reese'}