专否 写文章

BlackA,Talk is cheap,Show me the code.

Nov 11, 2018
Follow

Flask 学习笔记 #7 -- 数据库基础

之前我们涉及的登录操作都是简单的用URL参数来模拟的,而在实际应用中,程序需要在用户注册时把用户的账户和密码保存起来,然后在处理登录请求时读取这些信息。这一节我们就来学习如何在Flask程序中存取数据。

1、从文件系统到数据库

你可能最先想到的是使用Python的文件系统,当注册的时候把用户提交的账户密码按某种格式保存到一个文本文件中,然后在用户登录时从文件中把已经写入的信息全部读取出来,再逐条检索,判断用户的输入账户密码是否正确(还记得刚学C语言时老师让写的学生成绩管理系统吗?)实际上,早期的网站正是这样做的:

早期的数据管理使用的是文件系统

然而,传统的文件系统有很大的局限性:首先效率就是个大问题,因为文件只能按顺序访问,当网站的用户较少时还可以接受,当网站有很多用户时,数据文件就会变得很大,从文件中检索一条信息就会变得越来越慢,这将会导致仅仅一个用户登录操作网站就会挂起很长时间。其次我们再来看看数据完整性问题,传统的文件系统不会对数据的有效性进行检查,也不会消除数据冗余,也就是说数据文件中会有很多重复的数据。除了这些,还有数据的安全性,并发访问,热备份等等一系列问题是传统的文件系统无法解决的。于是,能够统一管理和共享数据的数据库管理系统(DBMS)应运而生。

数据库管理系统重新定义了数据的管理方式,通过数据库,程序不再需要直接和数据文件打交道,而是使用数据库管理系统统一定义的接口来存取数据,由数据库管理系统处理诸如数据备份,有效性检查,安全控制,并发访问等等一系列底层的操作。另外,数据库管理系统采用复杂的数据模型来存取数据,在提高了数据的存取效率的同时减少了数据冗余。总的来说,使用数据库可以大大的降低我们的开发难度:

通过数据库管理系统提供的接口操纵数据库


2、常见的数据库

知道了我们为什么需要使用数据库技术,接下来我们来看看常见数据库的有哪些。数据库技术从最早出现的网状数据库,层次数据库,发展到今天我们常用的关系数据库、非关系数据库,在短短的半个世纪内形成了坚实的理论基础和丰富的商业产品。现在我们常用的数据库主要分为两类:关系数据库(SQL,Structured Query Language)和非关系数据库(NoSQL,Not Only SQL)

关系数据库(SQL):

1、Oracle数据库:Oracle数据库是甲骨文公司开发的大型关系型数据库管理系统,是数据库领域的老大,长年占据着市场占有率第一的位置。具有性能优越、安全性高、适应性高、并行性高等优点。但由于其昂贵的价格,往往只有银行、金融、电商等对数据实时性、安全性要求极高的大型网站才会使用。

2、MySQL:MySQL由瑞典MySQL AB 公司开发,目前属于Oracle旗下产品( 该公司被Sun收购,Sun公司又被Oracle收购 )。MySQL是最流行的关系型数据库管理系统之一。具有功能强大、使用简单、运行速度快、可靠性高、跨平台性好、安全保密性强等优点。除此之外,由于其免费开源的特性,使其成为现在中小型网站最常用的数据库之一。

3、SQL Server:SQL Server最初是由Microsoft, Sybase和Ashton-Tate三家公司为IBM公司的OS/2操作系统开发的,后来由于OS/2项目的失败,三家公司分道扬镳,Microsoft将SQL Server移植到了Windows平台上,开发出了Microsoft SQL Server,Sybase则较专注于SQL Server在UNⅨ操作系统上的应用。Microsoft SQL Server功能强大、与Windows平台结合紧密,属于中型数据库,企业版收费较高。

4、SQLite:SQLite是D.Richard Hipp用C语言编写的开源嵌入式数据库引擎。说它是嵌入式数据库,是因为它没有像上面的三种数据库一样采用数据库服务器的形式,而是与应用程序处在同一个进程,也就是说这种数据库嵌入到了应用程序进程中。SQLite体积小,轻量,跨平台型好,配置十分简单,适合数据规模比较小的应用(比如 Android 的 APP)。另外在Python中已经内置了SQLite3。

非关系数据库(NoSQL):

1、Redis:Redis是一个开源的、使用ANSI C编写的、支持网络交互的、可基于内存也可持久化的 键-值 对数据库。由意大利人Salvatore Sanfilippo编写。Redis可以用作数据库和消息队列,但由于其数据储存在内存中,存取速度极快,所以Redis最常见的应用场景是作为缓存,而不是数据库和消息队列。

2、Memcached:Memcached是Live Journal公司的Brad Fitzpatric开发的一款软件。是一个自由开源的,高性能,分布式内存对象缓存系统。一般用来通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。

3、MongoDB:MongoDB是一个由C++语言编写的、基于分布式文件存储的非关系数据库,同时,它也是所有非关系数据库中最像关系数据库的。MongoDB是一个文档型数据库,它用 ” 文档 “ 来储存数据,” 文档 “ 的概念有点类似关系数据库中的行(但远比 ”行“ 的功能强大),多个文档构成集合(类似关系数据库的表),多个集合构成数据库。MongoDB采用 键-值 对的形式存储数据,使得它的效率很高,它非常适合用在要求高性能,高伸缩性的场景。

3、在Flask中操作数据库

知道了我们为什么要使用数据库,以及常见的数据库有哪些,接下来我们就来看看如何在Flask程序中访问数据库,这里我选用了SQLite数据库,因为它以及集成在Python中,不需要额外安装驱动程序,对初学者比较友好,如果你想在你的网站中使用MySQL等功能更强大的数据库,可以参考廖雪峰老师的文章,(另外多说一句,在Python中使用其他数据库和使用SQLite的区别不大,特别如果使用的是ORM的话,区别仅仅是驱动程序安装的不同)

在Flask中使用数据库有两种常见的方式,一种是使用较为底层的DB-API(Python数据库接口规范),另一种是使用ORM(对象关系映射):

DB-API:

DB-API 是一个标准的Python数据库编程接口,目前的API版本( 2.0 )定义在PEP249文档中,它提供了简单、标准化的数据库接口,Python 所有的数据库驱动程序都在一定程度上遵守 Python DB-API 规范。DB-API 定义了一系列必须的对象和数据库存取方式,以便为了各种底层数据库系统和多种多样的数据接口程序提供一致的访问接口,使在不同数据库之间移植代码成为一件轻松的事情。

使用 DB-API 需要先导入提供对应 API 的 Python 数据库驱动,之后我们需要连接到数据库,连接到数据库后我们需要建立一个游标对象,接下来可以通过游标对象执行一些SQL语句来操纵数据库(注:SQL->Structured Query Language结构化查询语言,SQL是用于访问和处理数据库的标准的计算机语言),最后我们需要关闭游标和数据库。

下面这个例子我们使用Python自带的SQLite数据库新建了一个表并向表中插入了一条数据:

# 使用DB-API的第一步是导入驱动
# 导入SQLite驱动
import sqlite3

# 连接到SQLite数据库
# 文件名是mydb
# 如果数据库不存在将自动创建
conn = sqlite3.connect("mydb.db")

# 建立游标对象
cursor = conn.cursor()

# 通过游标对象执行SQL语句
# 这句SQL的作用是新建一个表
cursor.execute("create table user (id varchar(20) primary key, name varchar(20))")
# 向表中插入一条数据
cursor.execute("insert into user (id, name) values ('1', 'blacka')")

# 关闭游标对象
cursor.close()
# 提交更改
conn.commit()
# 关闭数据库连接
conn.close()

下面是这段程序的运行结果:

ORM:

ORM(Object Relational Mapping,对象关系映射)是一种把面向对象的编程语言中对象的概念和关系数据库中表的概念对应起来的技术。具体来说就是定义一个对象,就对应关系数据库中的一张表,生成一个对象的实例,就对应这表中的一条记录。这样,我们在存取数据库的时候,就不用再去编写复杂的SQL语句,只需要简单的操作对象的属性和方法,由ORM层来生成具体的SQL语句来操作数据库。ORM技术在应用程序和关系数据库之间提供了一座桥梁(中间层),应用程序的对象型数据和关系数据库中的关系型数据通过这座桥梁(中间层)来相互转化。

使用ORM可以隐藏我们对数据访问的细节,也就是说我们可以不使用或者使用很少的SQL语句来实现对数据库的访问,这对初学者很方便,而且使用ORM可以提高我们的开发效率并且提高程序的抽象性。当然使用ORM也有一些缺点,首先肯定会损失一定的性能,其次对于一些复杂的程序ORM还是有些力不从心,但是这并不影响我们使用,在接下来的几节中,我们将会学习如何在Flask应用程序中使用ORM框架。

喜欢这个文章 | 分享 | 新建跟帖