从来没有接触过数据库的小白在线瑟瑟发抖。。。。。。。。。
人类在进化的过程中,创造了数字、文字、符号等来进行数据的记录,但是承受着认 知能力和创造能力的提 升,数据量越来越大,对于数据的记录和准确查找,成为了一个 重大难题。
数据库系统解决的问题:持久化存储,优化读写,保证数据的有效性。
计算机诞生后,数据开始在计算机中存储并计算,并设计出了数据库系统
(1)关系型数据库
关系型数据库:
指采用了关系模型来组织数据的数据库。关系模型指的就是二维表格模型,而一 个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。
主流的关系型数据库有:
Oracle、Microsoft SQL Server、MySQL、PostgreSQL,SQLite、MariaDB(MySQL的一个分 支)Microsoft Access、SAP
(2)非关系型数据库
非关系型数据库:
指非关系型的,分布式的,以键值对存储且结构不固定,可以减少一些 时间和空间的开销。非关系型数据库都是针对某些特定的应用需求,主要分为以下几类:
(1)面向海量数据访问的面向文档数据库:MongoDB、Amazon DynamoDB、Couchbase等。
(2)面向高性能并发读写的key-value数据库: Redis、 Memcached等。
(3) 面向搜索数据内容的搜索引擎:Elasticsearch,Splunk,Solr,MarkLogic和Sphinx等。
(4)面向可扩展性的分布式数据库:Cassandra,HBase等
E表示entry,实体,一个实体转换为数据库中的一个表
R表示relationship,关系关系有: 一对一,一对多,多对多
范式:
经过研究和对使用中问题的总结,对于设计数据库提出了一些规范,这些规范被称为范式
说明:关系型数据库有六种范式。一般说来,数据库只需满足第三范式(3NF)就行了。
• 第一范式(1NF):列不可拆分 , 即无重复的域。
特点:有主关键字、主键不能为空、主键不能重复,字段不可以再分。
• 第二范式(2NF):有唯一标识 ,即每个表有且仅有一个主关键字,其他数据元素与主关键字一一对应。
特点:满足第一范式的前提下,消除部分函数依赖,也就是说除主键外的每一列,都必须完全依赖与主键,不能有某些列跟主键没有关系。
• 第三范式(3NF):引用主键 ,即每列数据都与主键直接相关,不能有其他依赖关系
特点:不存在非主属性对码的传递性依赖以及部分性依赖
三大范式只是一般设计数据库的基本理念,可以建立冗余较小、结构合理的数据库。如果有特殊情况,当然要特殊对待,数据库设计最重要的是看需求跟性能,需求>性能>表结构。所以不能一味的去追求范式建立数据库。
举例说明:
不满足第一范式:
(1)
联系方式还可以再分,修改为:
(2)
进货,销售还可以再分 ,修改为:
不满足第二范式:
(1)
班级地址部分依赖于关键字班级编号, 所以要变为两个表:
(2)数据冗余过大,插入异常,删除异常,修改异常的问题
不满足第三范式:
完全满足了第二范式,但是奖金等级和奖学金存在传递依赖,更改为:
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗 下产品。MySQL 是最流行的关系型数据库管理系统之一。
MariaDB,据说是MySQL被甲骨文公司收购后,他的创始人担心MySQL就此没落,又创立出来的一个分支,maria是他的第四个女儿的名字,MariaDB使用起来与MySQL没差。
cs架构:客户端–服务器端b
s架构:浏览器端–服务器端
MySQL属于cs架构
服务端为mtsql sever,分为三层:
(1)连接层: 用于客户端限制
(2)SQL层:一些SQL语句的定义
(3)存储引擎层:以什么方式存储的。
数据库存储引擎是数据库底层软件组织,进行创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,
MySQL的核心就是存储引擎。查看使用的引擎: show engines 。 默认的数据库引擎为InnoDB
(1)
安装:
yum search mariadb
yum install mariadb_server.x86_64 -y
安装成功后开启mariadb服务:
systemctl start mariadb
可以查看状态:
systemctl status mariadb
进入mysql:
mysql
关闭服务:system stop mariadb
开机自动启动: systemctl enable mariadb
此时安装好mysql后进入是不需要密码的,因此我们来设置安全性密码:
mysql_secure_installation
初始没有密码,直接回车
一路yes
Ok 以后进入mysql:
mysql -u用户名 -p密码
退出: ctrl + d
(2)设置允许远程连接
当别人可以通过远程连接访问你的数据库
关闭mysql服务器的防火墙:
systemctl stop firewalld
systemctl disable firewalld
用户授权:任意一台主机(%)以root身份远程登录,密码为westos,访问数据库的所有内容(* . *)
grant all privileges on * . * to root@’%’ identified by ‘westos’
*. *表示所有数据库中的所有内容,也可改为指定数据库里的内容,例如:mysql. * (mysql数据库里的所有内容,*代表所有)
%表示所有主机,也可改为指定主机,例如:172.25.254.23
通过 select Host,User,Password from mysql.user 可以查看到允许访问的信息
注意,SQL语句要在每句末尾加分号 ;
1、
显示主机的所有的数据库:
show datdbases;
进入指定数据库:
use 数据库名;
显示该数据库中的数据库表:
show tables;
数据库就相当与是一个文件夹,里表有很多数据库表
2、创建数据库:
create database 数据库名称 default charset = ‘utf8’
3、进入数据库:
use 数据库名称
4、查看当前使用的数据库:
select database();
5、删除数据库:
drop database 数据库名称
我们创建好的数据库现在是空的,啥也没有,要在里面创建需要的数据库表
一个数据库就是一个完整的业务单元,可以包含多张表,数据被存储在表中在表中为了更加准确的存储数据,保证数据的正确有效,可以在创建表的时候,为表添加一些强制性的验证, 包括数据字段的类型、约束。
1、查看当前数据库中的所有表:
show tables;
2、创建表:
create table 表名称(第1列属性名称 字段类型 约束 , 第2列属性名称 字段类型 约束 … )
其中,
字段类型:
• 数字:int,decimal, float
• 字符串:varchar,text
• 日期:datetime
• 布尔:bool
约束:可以不写
• 主键 primary key
• 非空 not null
• 惟一 unique
• 默认 default
• 外键 foreign key
• 自动增长 auto_increment
3、修改表:
增加:
alter table 表名称 add 列名 字段类型 约束
修改属性名称:
alter table 表名称 change 要修改的属性名 修改后的属性名 类型 约束
删除某个属性:
alter table 表名称 drop 属性名称
4、删除表
drop 表名称
5、修改表的名称
rename table 要修改的表名称 to 新的表名称
6、查看表的结构
desc 表名称
7、查看表的创建语句
show create table 表名称
1、增加;
(1)全列插入
insert into 表名称 values(每列对应要添加的数值)
(2)缺省插入
insert into 表名称(某列) values()
(3)同时插入多条
insert into 表名称values()()…Insert into 表名称(列…) values()()
2、修改:
update 表名称 set 某列=某值 … where 条件
3、删除:
delete from 表名称 where 条件
4、备份与恢复
数据备份 | mysql dump -u用户名 -p密码 数据库名 > 备份文件.sql |
---|---|
恢复数据 | mysql -u用户名 -p密码 数据库名 < 备份文件.sql |
5、查询
select * from 表名称
*表示所有字段 查询表中的所有信息
(1)查询部分:
select 列名1,列名2… from 表名称
(2)查询并起别名
select 列名 as 新的名称 from 表名称
(3)消除重复行
select distinct 列名 from 表名称
(4)根据条件查询
select * from 表名 where 条件
where条件:
比较运算符 | 等于=,不等于!=,大于等于>=,大于>,小于等于<=,小于< |
---|---|
逻辑运算符 | 逻辑与and,逻辑或or,逻辑非not |
空判断 | 判空 is null,判非空is not null |
模糊查询 | like ‘%’ %代表多个任意字符,like ‘_’ _代表一个任意字符 |
范围查询 | in 表示在一个非连续的范围内,between…and… 表示在一个连续的范围内 |
(5)分组
select 列1,列2… 聚合条件 from 表名 group by 列1,列2…
• 按照字段分组,表示此字段相同的数据会被放到一个组中
• 分组后,只能查询出相同的数据列,对于有差异的数据列无法出现在结果集中
• 可以对分组后的数据进行统计,做聚合运算
聚合函数:
count(*) | 求数量 |
---|---|
max(列) | 求此列的最大值 |
min(列) | 求此列的最小值 |
sum(列) | 求此列的和 |
avg(列) | 求此列的平均值 |
对比where和having:
• where是对from后面指定的表进行数据筛选,属于对原始数据的筛选
• having是对group by的结果进行筛选,所以某个数据是通过统计计算后进行筛选的话,就需要用having
(6)排序
为了方便查看数据,可以队数据进行排序
升序:asc ,默认升序
select * from 表名 order by 列名 asc
降序:desc
select * from 表名 order by 列名 desc
可以根据多个列排序:
select * from 表名 order by 列1 asc , 列2 desc
表示 :将行数据按照列1进行排序,如果某些行列1的值相同时,则按照列2排序,以此类推
(7)获取部分行
select * from 表名 limit start , count
表示 :从start索引开始,获取count条数据
(8)多表查询
左拼接 | 表1 left join 表2 | 以表1为准拼接,缺少的置空,多余的删除 |
---|---|---|
右拼接 | 表1 right join 表2 | 以表2的为准拼接,缺少的置空,多余的删除 |
等值拼接 | 表1 inner 表2 | 拼接相同的内容,多余的删掉 |
查询总结:
完整的select语句:
select distinct * from 表名
where....
group by ... having...
order by ...
limit start,count
注意: 实际使用中,只是语句中某些部分的组合,而不是全部
执行顺序为:
from 表名
where …
group by …
select distinct *
having …
order by …
limit star,count
PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,
Python2中则使用MySQLdb。
下载:
pip install pymysql
使用时导入 import pymysql
步骤:
建立连接(连上数据库)—— 创建游标(给数据库发送指令,用来执行sql语句)——关闭游标——关闭连接
import pymysql
#(1)创建数据库连接
conn = pymysql.connect(host='主机名', user='用户名', password='密码',
db='数据库名',port=3306, autocommit=True, charset='utf8')
#(2)创建游标(用来执行sql语句)
cur = conn.cursor()
#(3)执行sql语句
insert_sql = 'insert into users(username) values ('user1');' # 在users表中插入user1
cur.execute(insert_sql)
# conn.commit() #把操作提交到数据库中,因为创建连接时写了 autocommit=True 自动提交,所以这里不用再写
print("插入数据成功")
#(4)关闭游标
cur.close()
#(5)关闭连接
conn.close()
查看connrct 函数的源代码,发现他有 中 有__ enter __ 和 __exit __函数,是个上下文管理器,所以可以用with打开、
看源代码发现 connect最后返回的是一个游标
所以起名字就 with … as cur
然后直接开始执行sql语句
import pymysql
# 使用with语句时, pymysql.connect返回的是数据库游标
with pymysql.connect(host='主机名', user='用户名', password='密码',
db='数据库名', port=3306, autocommit=True, charset='utf8') as cur:
# 3). 执行sql语句(增删改)
insert_sql = 'insert into users(username) values ("user2");'
cur.execute(insert_sql)
print("插入数据成功")
显示一条:
cur.fetchone()
显示多条:
cur.fetchmany(显示的数据条数)
全部显示:
cur.fetchall()
import pymysql
with pymysql.connect(host = '主机名', user = '用户名', password = '密码',
db = '数据库名', port = 3306, autocommit = True, charset = 'utf8') as cur:
query_sql = 'select * from users where username like "westos%";'
result = cur.execute(query_sql) # 返回的是影响的数据条数
print("符合条件的记录数:", result)
# #如果要显示出来信息
# print(cur.fetchone())
# print(cur.fetchmany(2)) 接着上一次显示
users_info = cur.fetchall()
# 以表格方式打印
from prettytable import PrettyTable
table = PrettyTable(field_names=['编号', '用户名', '密码'])
for user in users_info:
table.add_row(user)
print(table)
user = [('westos'+str(i) , 'password'+str(i)) for i in range(20)]
# user = [(westos0,password0), (westos1,password1)............]
with pymysql.connect(host = '主机名', user = '用户名', password = '密码',
db = 'Blog', port = 3306, autocommit = True, charset = 'utf8') as cur:
insert_sql = 'insert into users(username, password) values (%s, %s);'
cur.executemany(insert_sql,user)
#是去找的 %user[0] : (westos0 , password0)
SQLite是内嵌在Python中的轻量级、基于磁盘文件袋额数据库管理系统(就是一个文件),
不需要安装和配置服务,支持使用SQL语句来访问数据库。该数据库使用C语言开发,支持大多数SQL91标准,
支持原子的、一致的、独立的和持久的事务,不支持外键限制;通过数据库级的独占性和共享性锁定来实现独立事务,
当多个线程同时访问同一个数据库并试图写入数据时,每一时刻只有一个线程可以写入数据。
SQLite支持最大140TB大小的单个数据库,每个数据库完全存储在单个磁盘文件中,
以B+树数据结构的形式存储,一个数据库就是一个文件,通过直接复制数据库文件就可以实现数据库的备份。
如果需要使用可视化管理工具,可以下载并使用SQLiteManager、SQLite Database Browser 或其他类似工具。
import sqlite3
# 1). 创建连接
conn = sqlite3.connect(database='users.sqlite')
# 2). 创建游标
cur = conn.cursor()
# 3). 操作
# if not exists如果数据库标不存在时创建表,否则不做操作。
create_sql = 'create table if not exists userinfo1 (id int auto_increment primary key , name varchar(10) unique, passwd varchar(10) default "123");'
cur.execute(create_sql)
insert_sql = 'insert into userinfo1(name) values("user2");'
cur.execute(insert_sql)
# 数据操作(增删改)一定需要提交。
conn.commit()
select_sql = 'select * from userinfo1'
cur.execute(select_sql)
print("查询结果: ", cur.fetchall())
cur.close()
conn.close()