什么是关系型数据库?
关系型数据库
又称为关系型数据库管理系统
(RDBMS),它是利用数据概念实现对数据处理的算法,达到对数据及其快速的增删改查操作。
既然被称为关系型
数据库,那么它的关系在哪里体现呢?
举一个例子吧。
比如我现在有表单A
和 表单B
其中:
表单A
中有一个名为user_id的字段
表单B
中也有一个名为user_id的字段
现在我把他们建立一种联系,当我去修改表单A
的user_id的值时,表单B
中的user_id的值也会自动进行修改,因为他们建立的一种关系
,因为这种关系,使得数据具有一致性。
千万数据中,获取有数条直接,在运维或者开发哥哥的神操作下,他们冥冥中被安排的明明白白。
非关系型数据库
正如它的名字,每条数据间都是独立存在的,没撒子关系哩。
RDBMS 术语
在上一篇文章 第四发 数据库入门 中,我提到的数据库
,表单
,行
,列
都是RDBMS中的一些术语。现在我继续补充一些。
冗余: 不考虑数据大小,去提高查询数据的速度。举一个例子,比如我现在有两个表单,一个叫A
,一个叫B
,而在A
和B
中,有好几个字段是相关联的,如果这时候我们数据量很大,还的要进行极其频繁的数据查询,数据库查询的速度一定会慢下来。在极其频繁的查询中,因为很多字段都是相关联的,每次都要进行很多次跨表查询,所以速度会慢下来。如果我们这时候取消几个字段关系,把B
中的字段写到A
里边,把A
里边的写到B
里边。这样虽然取消了关系,但是两个表中数据重复了,所以数据库大小就会变大,但是这时候就会减少跨表查询,数据库查询速度就很上来。所以,在数据库中,有时候查询慢的原因未必是数据量太大,而是拥有极其复杂的字段关系。
主键: 你可以理解为主要关键字.主键在当前表单的当前字段是唯一的
比如数据库通常都是在第一个字段是 ID
,这个通常就是一个主键,它默认会自增长。它在名为ID
的字段下是不会重复的,每行的值与其他行的值不会重复。
外键: 主要用于两个表直接的关联. 强行举例,比如我现在有一个名为A
和 B
的表单,在A
中有一个名为 username的字段,在B
中有一个名为user_email的字段,这时username去关联user_email的字段,这时的username字段就叫做外键.
索引: 利用一定的算法方法,对专门的字段进行优化,使其加快查询速率。
接下来,来看Mysql的使用。
为了后期我们方便使用,我先在这里教大家创建一个mysql账户。
我们使用默认的root
超级管理员用户登录后,是这样的。
这时,我们要创建一个专门针对一个名为test
的库创建一个用户,让这个用户只对test
库有增删改查的权限。
我决定这个用户的用户名和密码都设置为 xeanyu
我们来解析一下 grant all on test.* to 'xeanyu'@'localhost' identified by "xeanyu";
其中
grant
是Mysql一个专门控制权限的命令
all
指的是所有权限
test.*
test是数据库名字,然后后边的 .*
是指当前所有表
'xeanyu'@'localhost'
其中前面的xeanyu指的是用户名,而localhost指的是这个用户名能在哪里进行登录,这里的localhost是本地。
identified by "xeanyu"
指的是设置密码为xeanyu
请根据自己的情况做决定,记得命令后边有一个分号!!
然后我们退出数据库,使用xeanyu的数据库账户登录一下。
可以看到,我们使用新创建的用户名成功登录了。
这是胜利的第一步!
Mysql数据库简单的一些命令
- show databases; 显示当前用户下能操作的所有数据库。
- use [数据库名称]; 切换数据库
- show tables; 显示当前数据库下的所有表单
- create database [数据库名称] charset utf8mb4; 创建一个名为[数据库名称]的数据库,且编码为utf8.如果不指定编码,可能只能支持拉丁文。
- drop database [数据库名称]; 删除数据库[名称]
- truncate table [表名]; 清空表单所有数据
- delete table [表名]; 删除表单
- desc [表名]; 查看表结构
- select [字段名或者用*代替所有] from [表单名]; 查看[表单名]中的[字段名或者用*代替所有]的数据。
Mysql 创建一个表单
我们先来手撸一个表结构(以后就不用了,放❤)
可以看到,重点在于最后的创建表结构。
我们分析一下那个Sql代码。
1
2
3
4
5
6
|
create table User(
id int auto_increment,
user_name char(32) not null,
user_pass char(64) not null,
user_age int null,
primary key(id));
|
其中id
user_name
user_pass
user_age
字段,其中在代码的最后一行,指明了字段id
是主键,在代码第二行,从auto_increment
看出指明了字段id
自增长。而其中多次出现 not null
,它的意思是不容许空,而null
的意思是容许为空。
通常字段格式就是: 字段名
字段类型
字段属性
我们使用 desc User
看出User
表单中的表单结构.
向User表单插入第一条数据
我们来分析一下插入语句。
insert into User (user_name,user_pass,user_age) values("XeanYu","XeanYu",18);
我们分看下
其中insert
和 into
就不用说了,固定的。
其中User
是表单名,(user_name,user_pass,user_age)
其中是三个对应User
中的三个字段,有人问,为什么不给id
字段赋值?因为id
字段是自增长的主键。
然后values("XeanYu","XeanYu",18)
其中三个值对应三个user_name,user_pass,user_age三个字段。
这时候有人估计看咸鱼不爽了,想要找事。如果我把id
字段的值强行写进去呢,比如我就写个1,重复的话,数据库能拿我怎么样呢?咸鱼我准备实施反击计划。
看到了吧。Mysql都看你不爽了,人家主键在对应字段下面是数据唯一的!
有人可能还要问啦,如果我把id
改成其他数字行吗?我要回答,当然可以,只要主键的值不重复,一切都好说。
可以看到,其实主键的值就是在上一行主键的值 +1
Mysql简单数据查询
我们已经了解了简单的语句查询。
我们稍微生个级别。
比如我要user_age
为18的几行数据怎么办?也就是说年龄18的用户怎么筛选出来?
可以看到,我们用where user_age = 18
过滤出了我们需要的数据。
继续升级,如果我不要看到id
这个字段的内容咋办?
我们可以去更改select
所选择的字段进行输出。
由于有三个完全相同资料的用户,我想直接跳过前两个进行输出怎么搞?
这个时候我们就要清楚偏移量大哥了.
可以看到,我们多了两个东西limit
offset
这两个东西
limit
: 显示条数
offset
: 跳过几条开始查询
Mysql简单的数据修改更新
假如我想修改麻花藤的user_pass
字段的值怎么办呢?
直接上图
update
[表名]
set
[字段修改语句]
where
条件;
Mysql 简单的降序升序
比如我现在有一堆新日志,但是现在数据库的从小到大的排列方法,我想把顺序倒转过来,我该怎么搞呢?
好了,Mysql的基本知识就写到这里,等咸鱼哪天突然发疯给大家疯狂讲Mysql吧。
接下来就讲Python和Mysql直接的操作。
Python操作Mysql
有一个这样的库,专门针对关系型数据库而有的模块。
他就是Sqlalchemy
它是一个ORM框架,是由Mako的作者创建的。
我们先使用pip3来安装一下。
1
2
3
4
|
pip3 install Sqlalchemy --index http://pypi.douban.com/simple --trusted-host pypi.douban.com # 我们需要的主要模块
pip3 install pymysql --index http://pypi.douban.com/simple --trusted-host pypi.douban.com # 用于Sqlalchemy与mysql直接的驱动问题
# 考虑到Python官方的PYPI仓库安装很慢,所以我们使用豆瓣的PYPI仓库。当然,如果你有梯子,可以直接pip,不用带参数。
# 其实这里的pymysql也可以进行Python操作Mysql,但是后边我们要用Sqlalchemy做大事情!
|
在上边的内容里边,我们已经建立了一个针对数据库 test
的用户,现在这个用户就要派上用场了。
现在,我如果要用Python获取数据库test
下的 User
的所有数据。
废话不多说,直接上代码。
1
2
3
4
5
6
7
8
9
10
11
12
|
__author__ = 'XeanYu'
from sqlalchemy import create_engine
from pymysql import install_as_MySQLdb
install_as_MySQLdb()
engine = create_engine("mysql://xeanyu:xeanyu@127.0.0.1/test")
con = engine.connect() # 去连接数据库,返回一个连接后的实例
raw = con.execute("select * from User") # 注意,使用Python去操作数据库,写Sql命令时可以不带分号。
for i in raw: # 这里会返回一个raw,raw中每个元素是每行值所组成的的元组(tuple)
print(i)
|
第2~4行:其中create_engine
是用于连接数据库的,它会返回一个实例,但是这个时候并未连接。而第二行中的install_as_MySQLdb
是一个处理包的函数,原本Mysqldb是不支持Python3的,后来有了Pymysql,但是还有很多模块需要Mysqldb,所以就在这里进行了包上的处理,第三行所执行的函数,就是可以让那些需要Mysqldb
的模块可以获取到Mysqldb
包。
第6行: 这里需要重点讲下,这里的create_engine
连接数据库的格式是
dialect+driver://username:password@host:port/database_name
其中 dialect
指的是数据库程序,比如我用mysql,或者其他数据库名称,比如sqllite,postgersql等等。
其中driver
是数据库程序的驱动,如果不指定,Sqlalchemy默认会是Mysqldb
,这也是我为什么要用 install_as_MySQLdb
的原因。
其中username
是数据库用户名,比如我们创建的 xeanyu 这个用户,xeanyu就是用户名
其中 password
是用户密码
其中host
和 port
是数据库地址和端口,其中port
不指定则默认根据dialect
去默认。
其中database_name
是数据库名称
所以我们根据以上格式,我们去连接数据库。
第8行: 我们根据create_engine给我们返回给我们的实例去连接数据库,进行connect()
第9行: 我们又根据connect() 返回给我们的连接实例,去进行数据库的操作, select * from User
其中不必带上分号,它会返回一个迭代器,我们把这个迭代器赋值给raw
第11~12行: 我们输出我们查询的东西。
OK了,今天就说到这里。下节我们细说。