一、数据库介绍
数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据。我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢。所以,现在我们使用关系型数据库管理系统(RDBMS)来存储和管理的大数据量。所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。
RDBMS即关系数据库管理系统(Relational Database Management System)的特点:
1.数据以表格的形式出现
2.每行为各种记录名称
3.每列为记录名称所对应的数据域
4.许多的行和列组成一张表单
5.若干的表单组成database
6.若干术语:
  • 主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。
  • 外键:外键用于关联两个表。
  • 复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。
  • 索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
  • 参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。
MySQL支持大型数据库,支持5000万条记录的数据仓库,32位系统表文件最大可支持4GB,64位系统支持最大的表文件为8TB。
 
 
二、mysql常用管理命令
  • USE 数据库名 :选择要操作的Mysql数据库,使用该命令后所有Mysql命令都只针对该数据库。

  • SHOW DATABASES: 列出 MySQL 数据库管理系统的数据库列表。

  • SHOW TABLES: #显示指定数据库的所有表,使用该命令前需要使用 use命令来选择要操作的数据库。

  • SHOW COLUMNS FROM 数据表: #显示数据表的属性,属性类型,主键信息 ,是否为 NULL,默认值等其他信息。

  • create database testdb charset "utf8"; #创建一个叫testdb的数据库,且让其支持中文

  • drop database testdb; #删除数据库

  • SHOW INDEX FROM 数据表:显示数据表的详细索引信息,包括PRIMARY KEY(主键)。

 
三、mysql数据类型
1 数值类型
类型 大小 范围(有符号) 范围(无符号) 用途
TINYINT 1 字节 (-128,127) (0,255) 小整数值
SMALLINT 2 字节 (-32 768,32 767) (0,65 535) 大整数值
MEDIUMINT 3 字节 (-8 388 608,8 388 607) (0,16 777 215) 大整数值
INT或INTEGER 4 字节 (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值
BIGINT 8 字节 (-9 233 372 036 854 775 808,9 223 372 036 854 775 807) (0,18 446 744 073 709 551 615) 极大整数值
FLOAT 4 字节 (-3.402 823 466 E+38,1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 0,(1.175 494 351 E-38,3.402 823 466 E+38) 单精度
浮点数值
DOUBLE 8 字节 (1.797 693 134 862 315 7 E+308,2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 双精度
浮点数值
DECIMAL 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 依赖于M和D的值 依赖于M和D的值 小数值
 
 2 日期和时间类型
类型 大小
(字节)
范围 格式 用途
DATE 3 1000-01-01/9999-12-31 YYYY-MM-DD 日期值
TIME 3 '-838:59:59'/'838:59:59' HH:MM:SS 时间值或持续时间
YEAR 1 1901/2155 YYYY 年份值
DATETIME 8 1000-01-01 00:00:00/9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 混合日期和时间值
TIMESTAMP 4 1970-01-01 00:00:00/2037 年某时 YYYYMMDD HHMMSS 混合日期和时间值,时间戳
 
3 字符串
类型 大小 用途
CHAR 0-255字节 定长字符串
VARCHAR 0-65535 字节 变长字符串
TINYBLOB 0-255字节 不超过 255 个字符的二进制字符串
TINYTEXT 0-255字节 短文本字符串
BLOB 0-65 535字节 二进制形式的长文本数据
TEXT 0-65 535字节 长文本数据
MEDIUMBLOB 0-16 777 215字节 二进制形式的中等长度文本数据
MEDIUMTEXT 0-16 777 215字节 中等长度文本数据
LONGBLOB 0-4 294 967 295字节 二进制形式的极大文本数据
LONGTEXT 0-4 294 967 295字节 极大文本数据
 
 
四、事务
1 定义
事务由单独单元的一个或多个SQL语句组成,在这个单元中,每个MySQL语句是相互依赖的。而整个单独单元作为一个不可分割的整体,如果单元中某条SQL语句一旦执行失败或产生错误,整个单元将会回滚。所有受到影响的数据将返回到事物开始以前的状态;如果单元中的所有SQL语句均执行成功,则事物被顺利执行
 
2 事务特点
  • 在MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务
  • 事务处理可以用来维护数据库的完整性,保证成批的SQL语句要么全部执行,要么全部不执行
  • 事务用来管理insert,update,delete语句
 
3 事务四大特性
  • a、事务的原子性:一组事务,要么成功;要么撤回。
  • b、稳定性 : 有非法数据(外键约束之类),事务撤回。
  • c、隔离性:事务独立运行。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。
  • d、可靠性:软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改。可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit选项 决定什么时候吧事务保存到日志里。
 
 
五、索引
1 定义
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。上述SQL语句,在没有索引的情况下,数据库会遍历全部200条数据后选择符合条件的;而有了相应的索引之后,数据库会直接在索引中查找符合条件的选项。如果我们把SQL语句换成“SELECT * FROM article WHERE id=2000000”,那么你是希望数据库按照顺序读取完200万行数据以后给你结果还是直接在索引中定位呢?上面的两个图片鲜明的用时对比已经给出了答案(注:一般数据库默认都会为主键生成索引)。
2 索引的分类
普通索引、唯一索引、主键索引、全文索引、单列索引、多列索引、组合索引
3 常用索引命令
alter table table_name add index index_name (column_list) ;#增加普通索引
alter table table_name add unique (column_list) ; #增加唯一索引
alter table table_name add primary key (column_list) ; #增加主键索引,要保证主键不为空
create index index_name on table_name (column_list) ;#创建普通索引
create unique index index_name on table_name (column_list) ; #创建唯一索引
drop index index_name on table_name ; #删除索引

alter table table_name drop index index_name ; #删除索引
alter table table_name drop primary key ; #删除主键索引
SHOW INDEX FROM table_name\G #显示索引信息
4 索引的弊端
首先,索引要占用磁盘空间。通常情况下,这个问题不是很突出。但是,如果你创建每一种可能列组合的索引,索引文件体积的增长速度将远远超过数据文件。如果你有一个很大的表,索引文件的大小可能达到操作系统允许的最大文件限制。第二,对于需要写入数据的操作,比如DELETE、UPDATE以及INSERT操作,索引会降低它们的速度。这是因为MySQL不仅要把改动数据写入数据文件,而且它还要把这些改动写入索引文件。 
 
 
六、pymysql
mysql_conn.py
#!/usr/bin/env python
#Author is wspikh
# -*- coding: encoding -*-
import pymysql
# 创建连接
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='1234', db='mysql')
# 创建游标
cursor = conn.cursor()
# 执行SQL,并返回收影响行数,执行多条exectuemany
effect_row = cursor.execute("select user,password from USER")
# 提交
conn.commit()
print(effect_row)
# 打印前2行记录
print(cursor.fetchmany(2))
# 打印所有结果
#print(cursor.fetchall())
# 关闭游标
cursor.close()
# 关闭连接
conn.close()

注:在fetch数据时按照顺序进行,可以使用cursor.scroll(num,mode)来移动游标位置,如:

  • cursor.scroll(1,mode='relative')  # 相对当前位置移动
  • cursor.scroll(2,mode='absolute') # 相对绝对位置移动

fetch数据类型

关于默认获取的数据是元祖类型,如果想要或者字典类型的数据,即:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pymysql
  
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
  
# 游标设置为字典类型
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
r = cursor.execute("call p1()")
  
result = cursor.fetchone()
  
conn.commit()
cursor.close()
conn.close()
 
 
七、ORM sqlachemy学习
1 ORM介绍
orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却都是关系型的,为了保证一致的使用习惯,通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用编程语言对数据库进行操作的时候可以直接使用编程语言的对象模型进行操作就可以了,而不用直接使用sql语言

 
2 sqlalchemy安装

orm的优点:

  1. 隐藏了数据访问细节,“封闭”的通用数据库交互,ORM的核心。他使得我们的通用数据库交互变得简单易行,并且完全不用考虑该死的SQL语句。快速开发,由此而来。
  2. ORM使我们构造固化数据结构变得简单易行。

缺点:

  1. 无可避免的,自动化意味着映射和关联管理,代价是牺牲性能(早期,这是所有不喜欢ORM人的共同点)。现在的各种ORM框架都在尝试使用各种方法来减轻这块(LazyLoad,Cache),效果还是很显著的。
 
3 sqlalchemy基本使用

Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如:
pymysql
    mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
 
orm-simply.py
#!/usr/bin/env python
#Author is wspikh
# -*- coding: encoding -*-
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker

engine = create_engine("mysql+pymysql://root:1234@localhost/oldboydb?charset=utf8",
                        echo=False) #echo=True日志打印,?charset=utf8代表支持中文
Base = declarative_base()  # 生成orm基类
class User(Base):
    __tablename__ = 'user'  # 表名
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    password = Column(String(64))

Base.metadata.create_all(engine)  # 创建表结构

Session_class = sessionmaker(bind=engine)  # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
Session = Session_class()  # 生成session实例,相当于游标

user_obj = User(name="alex", password="alex3714")  # 生成你要创建的数据对象
user_obj_2 = User(name="chenronghua",password="chenronghua") # 生成你要创建的数据对象
#print(user_obj.name, user_obj.id)  # 此时还没创建对象呢,不信你打印一下id发现还是None

Session.add(user_obj)  # 把要创建的数据对象添加到这个session里, 一会统一创建
Session.add(user_obj_2)  # 把要创建的数据对象添加到这个session里, 一会统一创建
#print(user_obj.name, user_obj.id)  # 此时也依然还没创建

Session.commit()  # 现此才统一提交,创建数据

# 查询
print(Session.query(User.id,User.name).filter_by(name ="chenronghua").all())

# 修改
#my_user.name = "oldboy"
#my_user.password = "oldboy"

#获取所有数据
print(Session.query(User.id,User.name).filter(User.name =="alex").all())
 
# 分组
print(Session.query(func.count(User.name),User.name).group_by(User.name).all() )
# 统计
my_user_count = Session.query(User).filter(User.name.like("a%")).count()
print("名字为alex的数量为: %s" %my_user_count)
my_user2_count = Session.query(User).filter_by(name ="chenronghua").count()
print("名字为chenronghua的数量为: %s" %my_user2_count)
 
orm-biaoguanlian.py
#!/usr/bin/env python
#Author is wspikh
# -*- coding: encoding -*-
#!/usr/bin/env python
#Author is wspikh
# -*- coding: encoding -*-
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship

engine = create_engine("mysql+pymysql://root:1234@localhost/test",
                       encoding='utf-8', echo=False) #echo=True日志打印

Base = declarative_base()  # 生成orm基类
class User(Base):
    __tablename__ = 'user'  # 表名
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    password = Column(String(64))
class Address(Base):
    __tablename__ = 'addresses'
    id = Column(Integer, primary_key=True)
    email_address = Column(String(32), nullable=False)
    user_id = Column(Integer, ForeignKey('user.id'))# 和User表建立关系

    user = relationship("User", backref="addresses")  # 这个nb,允许你在user表里通过backref字段反向查出所有它在addresses表里的关联项

    def __repr__(self):
        return "<Address(email_address='%s')>" % self.email_addres

Base.metadata.create_all(engine)  # 创建表结构

Session_class = sessionmaker(bind=engine)  # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
Session = Session_class()  # 生成session实例,相当于游标

#user_obj = User(name="alex",password="alex3714")
#add_obj = Address(email_address='wspkh@live.com',user_id = 3)

#Session.add(user_obj)  # 把要创建的数据对象添加到这个session里, 一会统一创建
#Session.add(add_obj)  # 把要创建的数据对象添加到这个session里, 一会统一创建
#查询
obj = Session.query(User).first()
for i in obj.addresses:  # 通过user对象反查关联的addresses记录
    print(i)

addr_obj = Session.query(Address).first()
print(addr_obj.user.name)  # 在addr_obj里直接查关联的user表
Session.commit()
 
4 多外键关联
orm-duobiaoguanlian.py
#!/usr/bin/env python
#Author is wspikh
# -*- coding: encoding -*-
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy import Integer, ForeignKey, String, Column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy.orm import sessionmaker

engine = create_engine("mysql+pymysql://root:1234@localhost/oldboydb",
                       encoding='utf-8', echo=False) #echo=True日志打印
Base = declarative_base()
class Customer(Base):
    __tablename__ = 'customer'
    id = Column(Integer, primary_key=True)
    name = Column(String(32))

    billing_address_id = Column(Integer, ForeignKey("address.id"))
    shipping_address_id = Column(Integer, ForeignKey("address.id"))

    billing_address = relationship("Address", foreign_keys=[billing_address_id])
    shipping_address = relationship("Address", foreign_keys=[shipping_address_id])
class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer, primary_key=True)
    street = Column(String(32))
    city = Column(String(32))
    state = Column(String(32))
Base.metadata.create_all(engine)  # 创建表结构
Session_class = sessionmaker(bind=engine)  # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
Session = Session_class()  # 生成session实例,相当于游标

cut_obj1 = Customer(id=1,name="wspkh",billing_address_id=10,shipping_address_id=10,billing_address="haitian",shipping_address="letai")
cut_obj2 = Customer(id=2,name="kh",billing_address_id=11,shipping_address_id=11,billing_address="aobei",shipping_address="dongsheng")
addr_obj1 = Address(id=10,street="yuxing",city="sjz",state="hebei")
addr_obj2 = Address(id=11,street="tangu",city="sjz",state="hebei")
Session.add_all([cut_obj1,cut_obj2,addr_obj1,addr_obj2])
Session.commit()  # 现此才统一提交,创建数据
 
5 多对多关系
orm-duoduiduo.py
#!/usr/bin/env python
#Author is wspikh
# -*- coding: encoding -*-
#一本书可以有多个作者,一个作者又可以出版多本书
from sqlalchemy import Table, Column, Integer,String,DATE, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
engine = create_engine("mysql+pymysql://root:1234@localhost/oldboydb?charset=utf8",
                       encoding='utf-8', echo=False) #echo=True日志打印

Base = declarative_base()
book_m2m_author = Table('book_m2m_author', Base.metadata,
                        Column('book_id',Integer,ForeignKey('books.id')),
                        Column('author_id',Integer,ForeignKey('authors.id')),
                        )

class Book(Base):
    __tablename__ = 'books'
    id = Column(Integer,primary_key=True)
    name = Column(String(64))
    pub_date = Column(DATE)
    authors = relationship('Author',secondary=book_m2m_author,backref='books')

    def __repr__(self):
        return self.name

class Author(Base):
    __tablename__ = 'authors'
    id = Column(Integer, primary_key=True)
    name = Column(String(32))

    def __repr__(self):
        return self.name

Base.metadata.create_all(engine)  # 创建表结构

Session_class = sessionmaker(bind=engine)  # 创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
s = Session_class()  # 生成session实例

#b1 = Book(name="Fllow Alex Study Python")
#b2 = Book(name="Fllow Alex Search Girl")
#b3 = Book(name="Fllow Alex Study ZB")
#b4 = Book(name="Fllow Alex Driver Car")

#作者添加的顺序有问题?
#a1 = Author(name="Alex")
#a2 = Author(name="Jack")
#a3 = Author(name="Rain")

#b1.authors = [a1, a2]
#b2.authors = [a1, a2, a3]
 
#s.add_all([b1, b2, b3, b4, a1, a2, a3])

print('--------通过书表查关联的作者---------')

book_obj = s.query(Book).filter_by(name="Fllow Alex Study Python").first()
print(book_obj.name, book_obj.authors)

print('--------通过作者表查关联的书---------')
author_obj = s.query(Author).filter_by(name="Alex").first()
print(author_obj.name, author_obj.books)
s.commit()
 
 
八、补充
1 Inner join其实就是2个表的交集:select from INNER JOIN on a.a = b.b;
2 left join 其实是获取左边表a的所有记录,而不管右边表b中存在不存在:select from LEFT JOIN on a.a = b.b;
3 right join 其实是获取右边表b的所有记录,而不管左边表a中存在不存在 select from RIGHT JOIN on a.a = b.b;
4 full join mysql不直接支持,但是可以这样实现:select from left join on a.a = b.b UNION select from right join on a.a = b.b;

Python的平凡之路(12)的更多相关文章

  1. Python的平凡之路(8)

    (本文是对平凡之路(7)的补充等) 一.动态导入模块 import importlib __import__('import_lib.metaclass') #这是解释器自己内部用的 #importl ...

  2. Python的平凡之路(16)

    一.HTML+CSS补充 0.常用页面布局 <!DOCTYPE html> <html lang="en"><head> <meta ch ...

  3. Python的平凡之路(13)

    一.Python的paramiko模块介绍 Python 的paramiko模块,该模块和SSH用于连接远程服务器并执行相关操作 SSH client 用于连接远程服务器并执行基本命令 基于用户名和密 ...

  4. Python的平凡之路(11)

    一. rabbitmq 1 进程Queue:  父进程与子进程进行交互,或者同属于同一父进程下多个子进程进行交互 2 队列通信:   send1.py #!/usr/bin/env python#Au ...

  5. Python的平凡之路(10)

    异步IO 数据库 队列 缓存 1.Gevent协程 定义:用户态的轻量级线程.协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下 ...

  6. Python的平凡之路(9)

    一.Paramiko模块练习 1. Paramiko模块介绍 Paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接   2 .SSHclie ...

  7. Python的平凡之路(5)

    一.模块介绍 定义: 模块--用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),本质就是.py结尾的python文件(文件名test.py,模块名test) 包—用来从逻辑上组织 ...

  8. Python的平凡之路(2)

    一.标准库(sys & os):   Python 的标准库(standard library) 是随着 Python 一起安装在你的电脑中的,是 Python 的一部分 (当然也有特殊情况. ...

  9. Python的平凡之路(20)

    (提问复习为主) 一.Django请求的生命周期      武彦涛:           路由系统 -> 视图函数(获取模板+数据=>渲染) -> 字符串返回给用户     二.路由 ...

随机推荐

  1. spring框架学习(五)注解

    注解Annotation,是一种类似注释的机制,在代码中添加注解可以在之后某时间使用这些信息.跟注释不同的是,注释是给我们看的,Java虚拟机不会编译,注解也是不编译的,但是我们可以通过反射机制去读取 ...

  2. android adb常用命令

    android adb命令: adb root --获取root.adb remount --获取文件操作权限(push)adb shell pm list package 获取包名列表com.mqt ...

  3. 个人学习随笔(psi-blast随笔)

    psi-blast学习 最近自己学习了一些新工具,最近在学习关于蛋白质相互作用位点的预测,在学习中,接触了几个新的工具,下面说说自己正在学习的psi-blast. 首先要说我用psi-blast用来做 ...

  4. JAVA字符串05之课程问题解决

    (一)古罗马皇帝凯撒在打仗时曾经使用过以下方法加密军事情报:请编写一个程序,使用上述算法加密或解密用户输入的英文字串. 1.设计思想:首先选择是加密字符串还是解密字符串,两种算法相似.如果要加密字符串 ...

  5. flume坑之channel.transactionCapacity和HdfsSink.batchSize

    不说过程了,直接说结果!一对相连接的channel-HdfsSink,无意间配置如下:...agent.channels.common-channel.transactionCapacity=10.. ...

  6. Hprose question

    1 在服务端 接口的开发中 如果定义了index()方法 中间不能够有参数,否则报错. 2 接口方法中的参数 最好使用单参数 如fun($uid ) 或者 如果需要多个参数 fun($param){$ ...

  7. 解决 笔记本键盘打字母却跳出数字来,每次都要按一遍Fn+Num LK 的问题

    方法一. 开始-运行,输入“Regedit"命令进入注册表 HKEY_USERS\.DEFAULT\Control Panel\Keyboard 将 InitialKeyboardIndic ...

  8. linux 常用命令学习记录

    rm -f *.sh 2.grep -rn "enng" * 查找文件内容包含enng的文件(注意:文件名有xian的不会查询出) find . ! -name "*.s ...

  9. JavaScript 面向对象(一) —— 基础篇

    学好JS的面向对象,能很大程度上提高代码的重用率,像jQuery,easyui等,这篇博客主要从细节上一步步讲JS中如何有效地创建对象,也可以看到常见的创建对象的方式,最后也会附上一些JS面向对象的案 ...

  10. easyui的textbox赋值小结

    使用的系统中有个后台,需要填充单号,如下图: 每次往框里面填充都是一样的数据,复制.粘贴,而且当人数颇多的时候,就是体力活. 于是就想到通过执行js代码,自动填充这些数据. chrome下F12,查看 ...