1.1 数据库简介
数据库简介:
- 用途:用于存储生活的几乎一切数据
- 概念:数据库服务器、数据库、数据表、一行数据(一条)、一列数据(字段)
- 分类:关系型数据库(
MySql
,Oracle
,SQL Server
)、非关系型数据库(Redis
,MongoDB
) SQL
:Structured Query Language
,结构化查询语言SQL
分类:数据定义语言(DDL
)、数据操作语言(DML
)、数据查询语言(DQL
)、数据控制语言(DCL
)、数据事务语言(DTL
)
RDBMS
(关系数据库管理系统(Relational Database Management System
))术语:
- 数据库: 数据库是一些关联表的集合。
- 数据表: 表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。
- 列: 一列(数据元素) 包含了相同类型的数据, 例如邮政编码的数据。
- 行:一行(=元组,或记录)是一组相关的数据,例如一条用户订阅的数据。
- 冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。
- 主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。
- 外键:外键用于关联两个表。
- 复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。
- 索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
- 参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。
MySQL
是一个关系型数据库管理系统,由瑞典 MySQL AB
公司开发,目前属于 Oracle
公司。MySQL
是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
1.2. MySQL
(Ubuntu
)的安装
安装:
sudo apt-get install mysql-server
(若出现问题,应该删除自己添加的系统服务)安全配置:
sudo mysql_secure_installation
连接测试:
mysql -h 主机 -u 用户名(默认root) -p
其他:端口3306;提出
\h
或help
;所有命令都;
结尾
1.3. 数据库定义语言(DDL
)
数据类型:
- 整型(
_int
):tinyint
:有符号(-128, 127),无符号(0, 255),一个字节;smallint
:有符号(-32768, 32767),无符号(0, 65535),两个字节;mediumint
:3个字节,范围(-8388608~8388607);int
:4个字节,范围(-2147483648~2147483647);bigint
:8个字节,范围(+-9.22*10的18次方);- 注意:
tinyint
(4)中的4并不表示存储的长度,只有字段指定zerofill
是有用,如0002
- 浮点型(
float
,double
):float(m, d)
:单精度浮点数,4个字节,m
表示总位数,d
表示小数位数;double(m, d)
:双精度浮点数,8个字节,m
表示总位置,d
表示小数位数
- 定点数:
decimal(m, d)
:参数m
<65是总个数,d
<30且d
<m
是小数位,以字符串的形式存储浮点数,用于金融领域等要求严格的场景 - 字符串(
char
,varchar
,_text
):char(n)
:固定长度,最多255个字符;varchar(n)
:固定长度,最多65535个长度;tinytext
:可变长度,最多255个字符;text
:可变长度,最多65535个字符;mediumtext
:可变长度,最多2的24次方-1个字符;longtext
:可变长度,最多2的32次方-1个字符- 注意:
char(n)
若存入字符数小于n
,则以空格补于其后,查询之时再将空格去掉。所以char类型存储的字符串末尾不能有空格,varchar
不限于此; - 注意:
char(n)
固定长度,char(4)
不管是存入几个字符,都将占用4个字节,varchar
是存入的实际字符数+1个字节(n<=255)或2个字节(n>255),所以varchar(4)
,存入3个字符将占用4个字节; - 注意:
char
类型的字符串检索速度要比varchar
类型的快。
- 二进制数据(
_Blob
):_Blob
和_text
存储方式不同,_Text
以文本方式存储,英文存储区分大小写,而_Blob
是以二进制方式存储,不分大小写;_Blob
存储的数据只能整体读出;_Text
可以指定字符集,_Blob
不用指定字符集
- 日期时间类型(
date
,time
,datetime
,timestamp
):date
:日期,以YYYY-MM-DD
的格式显示,如’2019-11-19’;time
:时间,以HH:MM:SS
的格式显示,如’15:44:36’;datetime
:日期时间,以YYYY-MM-DD HH:MM:SS
的格式显示,如’2019-11-19 15:44:36’;timestamp
:以YYYY-MM-DD
的格式显示,自动存储记录修改时间,数据会随其他字段修改的时候自动刷新
- 整型(
数据类型的属性:
NULL
:数据列可包含NULL
值;NOT NULL
:数据列不包含NULL
值;DEFAULT
:默认值;PRIMARY KEY
:主键;AUTO_INCREMENT
:自动递增,适用于整数类型;UNSIGNED
:无符号;CHARACTER SET name
:指定字符集
数据库引擎:常见的
MySQL
数据库引擎有InnoDB
,MyIsam
,Memory
,Mrg_Myisam
,Blackhole
等。InnoDB
:事务型存储引擎,提供了对数据库ACID
事务的支持,并实现了SQL
标准的四种隔离级别,具有行级锁定及外键支持,该引擎的设计目标便是处理大容量数据的数据库系统,MySQL
在运行时InnoDB
会在内存中建立缓冲池,用于缓存数据及索引;MyIsam
:MySQL主流引擎之一,不支持事务操作,不支持行锁及外键,效率较低;Memory(Heap)
:MEMORY
类型的表访问非常得快,因为它的数据是放在内存中的,并且默认使用HASH
索引,但是一旦服务关闭,表中的数据就会丢失掉;HEAP
允许只驻留在内存里的临时表格。驻留在内存里让HEAP
要比ISAM
和MYISAM
都快,但是它所管理的数据是不稳定的,而且如果在关机之前没有进行保存,那么所有的数据都会丢失;Mrg_MyIsam
:一个相同的可以被当作一个来用的MyISAM
表的集合,它将MyIsam
引擎的多个表聚合起来,但是它的内部没有数据,真正的数据依然是MyIsam
引擎的表中,但是可以直接进行查询、删除更新等操作;Blackhole
:任何写入到此引擎的数据均会被丢弃掉,不做实际存储;Select
语句的内容永远是空,它会丢弃所有的插入的数据,服务器会记录下Blackhole
表的日志,所以可以用于复制数据到备份数据库。
数据库索引:用于快速找出在某个列中有一特定值的行
- 普通索引(
index()
):MySQL
中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点; - 唯一索引(
unique()
):索引列中的值必须是唯一的,但是允许为空值; - 主键索引(
primary key()
):是一种特殊的唯一索引,不允许有空值; - 组合索引:在表中的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用,使用组合索引时遵循最左前缀集合;
- 全文索引:只有在
MyISAM
引擎上才能使用,只能在CHAR
,VARCHAR
,TEXT
类型字段上使用全文索引; - 空间索引:对空间数据类型的字段建立的索引,
MySQL
中的空间数据类型有四种,GEOMETRY
、POINT
、LINESTRING
、POLYGON
。在创建空间索引时,使用SPATIAL
关键字。要求,引擎为MyISAM
,创建空间索引的列,必须将其声明为NOT NULL
。
- 普通索引(
很多选项都可以在创建表时指定,如:
1 | create table user( |
添加索引:
1 | alter table user add index(em); # 给em字段添加普通索引 |
1.4. 数据库操作语言(DML
)
- 创建一张
star
表:
1 | create table star( |
插入数据:
- 方式1:不指定字段,按照数据表的数据添加一条数据的全部字段
1
insert into star values(1,'黄晓明',200000,'山东',28,0);
可以同时插入多条数据,每条一个小括号
- 方式2:指定字段,只需要传递指定字段的值
1
insert into star(name,money,age,sex,province) values('小岳岳',4000000, 33, 0, '河南');
可以同时插入多条数据,每条一个小括号
查询数据:
1 | select * from star; |
- 删除数据:删除操作一定不要忘了指定条件,否则后果自负。
1 | delete from star where id = 1; |
- 修改数据:修改操作一定不要忘了指定条件,否则后果自负。
1 | update star set age=22, money=8000000 where id=6; |
1.5. 数据库查询语言(DQL
)
基础查询:
select * from star;
指定字段查询:
select id,name,money from star;
排除重复记录:
select distinct name from star;
(使用distinct
修饰的字段组合不能重复)指定条件查询:
1 | select id,name,money from star where id > 4; |
结果集排序:
select id,name,money from star order by money desc;
order by
:指定排序字段,asc
表示升序,默认的,desc
表示降序- 也可以多字段排序,先按照前面的字段排序,再按照后面字段排序。
select id,name,money,age from star order by money desc,age asc;
限制结果集:
1 | select id,name,money from star limit 3; # 取3条数据 |
- 常用的集合函数
函数 | 功能 |
---|---|
count | 统计个数 |
sum | 求和 |
max | 最大值 |
min | 最小值 |
avg | 平均值 |
- 使用count时指定任何字段都行
- 使用其他函数时必须要指定字段
1 | select count(*) from star; |
as
可以给字段其别名
- 分组操作
1 | select * from star group by sex; # 分组 |
- 结果集过滤:
1 | select count(*) as c,province from star group by province having c>1; |
搜索所有记录,然后按照省份分组,统计成员大于1的省份
1.6. 数据控制语言(DCL
)
1.7. 多表联合查询
- 隐式内连接:没有出现
join
关键的连接,select 字段 from 表1, 表2 where 关联条件;
1 | select username, name from user, goods where user.gid = goods.gid; |
查看用户买的商品名
- 显示内连接:会出现
join
关键字,后面的条件使用on
,select 字段 from 表1 [inner/cross] join 表2 on user.gid = goods.gid;
1 | select username, name from user [inner/cross] join goods on user.gid = goods.gid; |
功能同上
- 外左连接:以左表为主,
select 字段 from 表1 left [outer] join 表2 on 关联条件;
1 | select username, name from user left [outer] join goods on user.gid = goods.gid; |
以左表为主,显示左边所有内容,右表不匹配的选项显示
NULL
- 外右连接:以右表为主,
select 字段 from 表1 right [outer] join 表2 on 关联条件;
1 | select username, name from user right [outer] join goods on user.gid = goods.gid; |
以右表为主,显示右边所有内容,左表不匹配的选项显示
NULL
1.8. 多表联合操作
子(嵌套)查询操作
- 说明:一条
sql
语句的查询结果作为另一条sql
语句的条件 - 示例:
select * from user where gid in (select gid from goods);
- 说明:一条
联合更新(同时更新多个表的数据)
- 示例:
update user u, good g set u.gid=0, g.price=8000 where u.gid = g.gid and u.id=1
- 示例:
1.9. 事务处理语言(DTL
)
事务:
MySQL
使用INNODB
数据库引擎,用来维持数据库的完整性,常用来管理insert
、delete
、update
开启事务:禁止自动提交,
set autocommit=0;
操作回滚:出现异常时使用,
rollback;
提交操作:没有异常,
commit;
1.10. 外键索引(约束)
- 所谓外键就是一个表的主键作为了另一个表的关联字段,然后在添加一点设置就成为了外键,可以简化多个关联表之间的操作,如:删除一个另一个跟着删除
示例:一个表示用户组的表t_group
,一个用户表t_user
1 | create table t_group( |
约束行为:
NO ACTION
或RESTRICT
:删除或修改时不做任何操作,直接报错SET NULL
:删除或更新时,都设置为null
CASCADE
:删除或更新时,同时删除或更新从表的数据
1.11. 数据清空(DELETE
与TRUNCATE
)
delete from 表名;
:再次插入数据时,自增字段的值接着清空前的数据增加truncate table 表名;
:删除数据,同时将AUTO_INCREMENT
的初始值设为1
1.12. 数据库的备份与恢复
备份:
mysqldump -uroot -p test > test.sql
恢复:
mysql -uroot -p test < test.sql
1.13. Python
操作MySql
Python
操作MySQL
有5中方式,MySQLdb
、mysqlclient
、PyMySQL
、peewee
、SQLAlchemy
,在Python
的Web
框架Flask
和Django
中都采用orm
进行封。
1.13.1. MySQLdb
MySQLdb
又叫MySQL-python
,是Python
连接MySQL
最流行的一个驱动,很多框架都也是基于此库进行开发,遗憾的是它只支持Python2.x
,而且安装的时候有很多前置条件,因为它是基于C
开发的库,在Windows
平台安装非常不友好,经常出现失败的情况,现在基本不推荐使用,取代的是它的衍生版本。
1 | 前置条件 |
1 | import Mysqldb |
1.13.2. mysqlclient
由于MySQL-python(MySQLdb)
年久失修,后来出现了它的Fork
版本mysqlclient
,完全兼容MySQLdb
,同时支持Python3.x
,是Django ORM
的依赖工具,如果你想使用原生SQL
来操作数据库,那么推荐此驱动。安装方式和MySQLdb
是一样的,Windows
可以在https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient
网站找到对应版本的whl
包下载安装。
- 安装方式:
pip install mysqlclient
, 如果安装出现问题,需要安装Python3.x-dev
、libmysqlclient-dev
1.13.3. PyMySQL
PyMySQL
是纯Python
实现的驱动,速度上比不上MySQLdb
和mysqlclient
,最大的特点可能就是它的安装方式没那么繁琐,同时也兼容MySQL-python
- 安装方式:
pip install PyMySQL
,为了兼容mysqldb
,只需要加入pymysql.install_as_MySQLdb()
1 | import pymysql |
1.13.4. peewee
写原生SQL
的过程非常繁琐,代码重复,没有面向对象思维,继而诞生了很多封装wrapper
包和ORM
框架,ORM
是Python
对象与数据库关系表的一种映射关系,有了 ORM
你不再需要写SQL
语句。提高了写代码的速度,同时兼容多种数据库系统,如sqlite
, mysql
、postgresql
,付出的代价可能就是性能上的一些损失。如果你对 Django
自带的ORM
熟悉的话,那么peewee
的学习成本几乎为零。它是Python
中是最流行的 ORM
框架。
安装:
pip install peewee
MySQL
数据库连接:db = MySQLDatabase(database='test', host='localhost', port=3306, user='root', passwd='jiang')
Sqlite
数据库连接:db = SqliteDatabase(database=dbpath)
,dbpath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test.db'
创建数据表:
模型类名.create_table()
插入数据:
- 一般的
create
插入数据:类名.create(username='lajos')
- 事务插入:
1
2
3
4
5
6
7
8
9
10data = [
{
"username": "lajos",
"age": 14
},
...
]
with db.atomic():
for i in data:
User.create(**i)insert_many()
插入多条数据:1
2
3
4
5
6
7
8
9
10data = [
{
"username": "lajos",
"age": 14
},
...
]
with db.atomic():
for i in range(0, len(data), 100)
User.insert_many(data[i: i+100]).excute()
- 一般的
查询数据:可以使用
get()
和filter()
,也可以使用select()
1 | import datetime |
1.13.5. SQLAlchemy
如果想找一种既支持原生SQL
,又支持ORM
的工具,那么SQLAlchemy
是最好的选择,它非常接近Java
中的Hibernate
框架。安装使用pip install sqlalchemy
- 原生
SQL
使用:
1 | import time |
ORM
使用
使用ORM
方式创建数据表
1 | import datetime |
使用ORM
方式操作数据库
1 | from SqlALchemy.models import Users |
filter
与filter_by
的区别:filter
传入的参数要用这样的格式:类名.列明,判断要用==
表示,session.query(Users).filter(Users.name =='Martin').filter(Users.age == 19).all()
;filter_by
使用的语法和Python
更接近,session.query(Users).filter(name='Martin', age=19).all()
1.13.6. Flask-SQLAlchemy
SQLAlchemy
是一个关系型数据库框架,它提供了高层的ORM
和底层的原生数据库的操作,让开发者不用直接和SQL
语句打交道,而是通过Python
对象来操作数据库,在舍弃一些性能开销的同时,换来的是开发效率的较大提升。一句话:就是对数据库的抽象!Flask-SQLAlchemy
是一个简化了SQLAlchemy
操作的flask
扩展,是SQLAlchemy
的具体实现,封装了对数据库的基本操作。举例:如果说动物园是SQLAlchemy
,那Flask-SQLAlchemy
只是其中的一只。
1.14 常见问题
Linux 20.04
采用sudo apt-get install mysql-server
时,安装的版本其实是mysql 8.0
,安装成功后无法使用root
账户进入数据库?(1)查看默认配置文件:
1
2
3
4
5
6
7
8
9
10
11
12sudo cat /etc/mysql/debian.cnf
Automatically generated for Debian scripts. DO NOT TOUCH!
[client]
host = localhost
user = debian-sys-maint
password = qe7CxSdH2HczVtwL
socket = /var/run/mysqld/mysqld.sock
[mysql_upgrade]
host = localhost
user = debian-sys-maint
password = qe7CxSdH2HczVtwL
socket = /var/run/mysqld/mysqld.sock(2)以默认配置登录
mysql
,mysql -udebian-sys-maint -p
,然后输入密码qe7CxSdH2HczVtwL
(3)更改
root
密码:1
2
3
4
5
6use mysql;
下一行,密码改为了yourpassword,可以设置成其他的
update mysql.user set authentication_string=password('yourpassword') where user='root' and Host ='localhost';
update user set plugin="mysql_native_password";
flush privileges;
quit;(4)重启
mysql
:sudo service mysql restart
Mysql
数据库远程主机无法连接是什么问题?(1)需要开启用户的访问权限
1
2
3
4
5
6mysql –uroot –p
use mysql;
update user set host = '%' where user = 'test';
grant all privileges on test.* to 'test'@'%' identified by '123456';
flush privileges;
quit;(2)需要修改
mysqld.cnf
中的ip
绑定1
2
3
4
5sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address = 0.0.0.0
保存退出
重启服务
sudo service mysql restart(3)进入服务器后台,添加相应的安全策略组规则(入方向),例如阿里云服务器后台配置:
授权策略 | 优先级 | 协议类型 | 端口范围 | 授权对象 | 描述 |
---|---|---|---|---|---|
允许 | 1 | 自定义TCP | 目的:3306/3306 | 源:0.0.0.0/0 | MySQL数据库连接 |
- 本文作者: Lajos
- 本文链接: https://www.lajos.top/2020/05/12/No-1-Python与数据库-MySql/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!