一、数据库

1、概念
计算机的发明:为了做科学计算,需要大量的数据输入和输出IO;
数据库:按照数据结构来组织、存储、管理数据的仓库;便于检索、快速定位、增删改查;
存储在内存、磁盘都可以,是否掉电丢失是另一回事;不管使用什么存储介质,数据库的数据模型才是其核心和基础;
功能:数据持久化的方案,有组织的存储并管理起来,保证掉电不丢失

2、诞生历程
为了实现输入输出,最先是打孔卡片、灯泡明灭,然后是磁带(顺序读取),1956年IBM磁盘驱动器(支持随机访问);
随着硬件存储技术的发展,大量的数据需要存储和管理,数据库管理系统DBMS诞生;不管使用什么存储介质,数据库的数据模型才是其核心和基础;
信息化基于硬件的发展,让存储不再成为瓶颈;

3、分类
按照数据模型分类:层次数据库,网状数据库,关系型数据库

1)层次数据库
以树型结构表示实体及其之间的联系;从根结点开始,关系只支持一对多;代表数据库IBM IMS;
弊端:因为树不允许交叉,数据存在大量冗余;

2)网状数据库
不是树型结构,是图,也是网,能描述一对多,多对多;
可以表示实体间多种复杂关系,这是层次数据模型无法做到的;比如一个结点可以有多个父结点,结点之间支持多对多关联;

3)关系型数据库
使用行、列组成的二维表来组织数据和关系,表中的行既可以描述数据实体,也可以描述实体间的关系(加的某一列);不需要关心存储的物理细节,专心于数据的逻辑/关系构建,即如何把业务数据转描述成关系、即如何把业务模型设计成关系模型;关系模型有严格的数学理论基础,1970年IBM的研究员E.F.Codd发表了关系模型的论文;

行Row:又称为记录Record,元祖
列Column:又称为字段Field,维度(数据分析领域)
基于关系模型构建的数据库系统统称为RDBMS,代表的有IBM DB2,Oracle甲骨文的Oracle和MySQL,微软的MS SQL;

4、Oracle甲骨文的发展
拉里·艾莉森(Larry Ellison)阅读了IBM的关系型数据库的论文,开发了Oracle1.0,直到1992年Oracle7才逐渐稳定下来,2001年商务9i版本才被广泛应用;
2009年4月,甲骨文(Oracle)公司宣布收购了SUN(计算机系统)公司,2010年1月成功收购;SUN公司有主机、操作系统和研发能力,拥有Java版权、MySQL;
2013年,甲骨文超过IBM,称为继微软之后全球第二大软件公司;

5、MySQL发展
1985年几个瑞典人开发了MyISAM的前身;
2000年,MySQL采用GPL协议开源,MySQL4.0开始支持MyISAM、InnoDB存储引擎;
2005年,MySQL5.0是里程碑版本;
2008年,MySQL被SUN公司收购;
2009年1月,在Oracle收购MySQL之前,从MySQL 5.5 开始一条新的GPL分支,起名MariaDB;

MySQL:引擎是插件化的,可以支持多种引擎;
MyISAM:不支持事务,插入、查询速度快;
InnoDB:支持事务,行级锁,MySQL5.5起的默认引擎;以前是表级锁,数据库是个server,是并发的,表级锁很影响并发效率;

6、NoSQL
NoSQL是对非SQL、非传统关系型数据库的统称;
2009年后,一般指非关系型、非分布式、不提供ACID的数据库设计模式;如Facebook、Twitter、微博都用到了NoSQL,如Redis,跟他们的业务相关,实时性、分布式、因人而异的在线分析,关系型数据库比较难解决;

随着互联网时代的到来,数据爆发式增长,数据库技术也要适应新的业务需求;
随着移动互联网时代、物联网时代的到来,数据规模更加庞大,大数据技术中NoSQL也同样重要;
很多业务是关系型数据库+NoSQL结合使用;

ACID:数据库事务正确执行的四个基本要素的缩写;包含原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability);
一个支持事务(Transaction)的数据库,必须要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易方的要求;

7、数据库热度

1)关系型数据库
Oracle:需要单独学的关系型数据库
建模模型和排名第二第三的MySQL、Microsoft SQL Server不太一样;
入门级传统关系型数据库:MySQL、MariaDB,关系型数据库得通一种;
DB2:IBM的,依然有很大市场;商业收费,可以不太关注;
SQLite:小型关系型数据库非常好用,C++写的,开源、效率很好,支持事务,想临时在手机、本地持久化一些数据开以考虑使用,开以关注;
Hive:也叫蜂窝、数据仓库,可以存储海量数据,主要用来做仓库、进行数据分析,而不是增删改查;
虽然归类到关系型数据库,但实质是NoSQL、大数据领域的数据仓库,可以存海量数据;支持数据查询、分析的唯一语言 - SQL语句;
PostgreSQL:关系型数据库,国内用的不太多;
Microsoft Access:关系型数据库,但是是桌面级,SQL语句也有点非标,不用太关注;

2)NoSQL
NoSQL - 文档型(Document store)、键值对型(key-value store)、列存储型(Wide column store)

MongoDB,是文档型数据库,存储的数据类型是海量,类似于Json(嵌套key-value)存储
Redis: KEY—VALUE STORE,二进制存储结构,本质上是key-value,value类型很多,好处在于时间复杂度O(1),而且Redis是内存数据库,基于内存、非常快,也有自己的持久化策略;Redis还可以做第三方消息存储队列,基于内存、速度非常快;在实时计算方面应用也很突出;
Cassandra:宽列存储数据库Wide column store,也叫列存数据库,好处是不限制列数,而传统关系型数据库是限定列的,添一列异常麻烦、影响物理存储;每一行是一条记录,用列存数据库解决海量数据、变化列的数量非常便利,大数据领域常用;国内用的较少;
HBase:列存储数据库;大数据领域用的较多;更推荐学习;
大数据领域常用的NoSQL技术、即非关系型数据库:列存数据库Cassandra和HBase,文档数据库MongoDB和键值对数据库Redis,都能存储海量数据;还能搭集群;
大多数NoSQL都是解决大数据的问题,因为移动互联网时代最需要解决的就是海量数据;需要学习的有MapReduce、Hadoop、zookeeper、Kafka、HBase、Hive,整个Hadoop生态圈的东西;
当数据之间的关系没那么强,只是记录,可以考虑MongoDB、或者Redis;当数据之间的关系没那么强:Redis(基于内存)、MongoDB(不基于内存,但效率不低);

3)搜索引擎
搜索引擎(Search Engine)不太叫NoSQL;因为有索引数据库,最关键技术是倒排索引,所以划分到数据库,但更常叫搜索引擎;
Elasticsearch:搜索引擎,ELK中的E,简写ES,非常有名的分布式搜索引擎;开发必知的技术;解决数据查询;写多读少的数据库都要考虑到搜索引擎;
Solr:搜索引擎,单机用;小型架构适用;大数据领域由Java写的基础库,底层用,效率高;
Splunk:搜索引擎,国内用的很少;

二、MySQL

1、一种关系型数据库管理软件,支持网络访问,默认服务端口3306;
基于TCP网络协议进行连接通信,应用层协议是mysql,即TCP连接之上MySQL数据通信使用mysql协议;
连接字符串:“server=127.0.0.1;uid=root;pwd=12345;database=test”
参考 https://dev.mysql.com/doc/connector-net/en/connector-net-6-10-connection-options.html

2、SQL语句
是结构化查询语言Structured Query Language,1987年被ISO组织标准化;数据处理和分析领域,只认SQL语言;所有主流的关系型数据库都支持SQL,NoSQL也有大部分支持SQL;

SQL语句分类

DDL数据定义语言
负责数据库定义、数据库对象定义,由CREATE、ALTER与DROP三个语法组成;
DML数据操作语言
负责对数据库对象的操作,CRUD增删改查;
DCL数据控制语言
负责数据库权限访问控制,由GRANT授权和REVOKE撤销两个指令组成;
TCL事务控制语言
负责处理ACID事务,支持commit提交、rollback回滚指令;

SQL语句大小写不敏感,即语法中的关键字不区分大小写,习惯上用大写;SQL语句末尾用分号结束;

三、DCL

GRANT授权、REVOKE撤销
/* 建议所有的字符串均加单引号*/
GRANT ALL ON test.* TO ‘root’@’%’ IDENTIFIED by ‘root’;
REVOKE ALL ON . FROM root;

四、DDL

1、删除用户
慎用,删除定义好的用户,日常工作中,所创建的用户和密码都应管理好;

2、创建数据库
创建一个数据库,如果不存在就创建它,设置其字符集和校验规则;
CHARACTER SET 指定字符集,有中文的话至少utf8;如果记录有特殊符号,建议utf8mb4,它是utf8的拓展,支持4字节,但需要MySQL5.5.3+的版本;可以对数据库设置字符集、相当于缺省字符集,也可以在创建表的时候再指定字符集;
COLLATE 指定字符集的校验规则,用来做字符串比较的(因为有排序);没写的话有默认校对规则

3、删除数据库
DROP DATABASE IF EXISTS gogs;

4、创建表
MySQL是行存储数据库,数据是一行行存的,必须要固定列数;为了避免关键字冲突,使用反引号标注名称,这样就能被认为是非关键字;
不推荐枚举类型,一般用整型;
每张表的引擎、字符集可以单独设置,这是个非常棒的设计;

CREATE TABLE employees (
emp_no int(11) NOT NULL,
birth_date date NOT NULL,
first_name varchar(14) NOT NULL,
last_name varchar(16) NOT NULL,
gender enum(‘M’,‘F’) NOT NULL,
hire_date date NOT NULL,
PRIMARY KEY (emp_no) – 定义约束
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

5、DESC
查看列信息
{DESCRIBE | DESC} tbl_name [col_name | wild]
‘%name’ 以name结尾,%代表0个或任意个;
DESC employees;
DESC employees ‘%name’;

五、数据库设计

考点:多表关联的统计,通常会用到分组聚合;

数据库跟操作系统无关;授权时经常在@后的IP地址保留前半部分网段,写小一点,更安全;
注意:密码不可能在数据库用明文存储,最常见的是MD5单项散列算法(现在已经不安全);
该算法不可逆,不能从算法角度逆推回明文,但可以暴力**;因为MD5提前算好了彩虹表、一查表就能暴力**(遍历所有字符生成密文,就能**到密码),但暴力**需要时间,密码越长越复杂,暴力**的时间越久,验证码和滑动小滑块都能延长暴力**的时间;

如果用单向散列算法,会把密码生成一个字符串,一般是32、64、或128个字符;暴力**得到hash值,**难易程度只跟密码难度相关,跟散列值位数无关;
避免修改删除字段、引起物理结构的变化;最佳设计方案是增加冗余的废字段,以防最后增加字段引起整张表的结构变化,很多手段都是设置保留字段;

1、PRIMARY KEY 主键
表中一列或者多列组成唯一的key,也就是通过这一个或者多个列能唯一标识一条记录;主键的列不能包含空值null;表中可以没有主键,但是一般设计中都会有主键;而且一般都采用额外增加一列id自增字段来唯一确定某一行,不推荐联合主键(多列做主键);
主键往往设置为整型、长整型,且自增AUTO_INCREMENT,用过的编号不回头;

2、索引 Index
为了快速检索,实现O(1),用空间换时间,只显著提高查询效率、即读取操作;可以对一列或者多列设置索引;索引之所以快,因为里面是B+树;
索引的缺点就是在索引库进行写入操作比较麻烦,拉低写入效率;如果频繁写入,要考虑索引加多少;也就是如果读多写少,可考虑大量用索引,经常查询的列可以考虑加个索引键,如果写多读少,索引要适量;

1)主键索引
主键会自动建立主键索引,主键本身就是为了快速定位唯一记录的;
2)唯一索引
表中的索引列组成的索引必须唯一,但可以为空,非空值必须唯一;也叫唯一键;
允许多个NULL值,但非NULL值必须唯一;
3)普通索引
没有唯一性的要求,就是建立了一个字典的目录而已;只是建立了B+树、可以快速检索;

3、约束Constraint

1)UNIQUE 唯一键约束
定义了唯一键索引,就定义了唯一键约束;要求非空值必须唯一,否则报错;
2)PRIMARY KEY 主键约束
定义了主键,就定义了主键约束;就要求主键不能为空、且唯一;
提到主键,就要想要自动建立主键索引,有主键约束;
3)Foreign Key 外键约束
外键:在B表中的列,关联A表中的主键,B表中的列就是外键;外键就会形成外键约束;
表A称为主表,表B称为从表;并不是主表有多少外键,从表就必须引用那么多,即表B的外键列是表A主键列的子集;

外键约束有有三种情况:插入、更新、删除;即对增删改有影响;
从表的增删改问题不大,只要从表外键的数据存在于A表主键就行,主表进行级联删除、SET NULL,限制(RESTRICT、NO ACTION)等操作时,从表要根据引用情况做一些动作;
插入规则、插入约束,不需要显示定义
如果表B插入一条数据,B的外键列插入了一个值,这个值必须是表A中存在的主键值;
更新规则
定义外键约束时指定该规则,有缺省规则;
删除规则
定义外键约束时指定该规则,有缺省规则;

外键约束的操作
CASCADE 级联删除:从父表删除或更新会自动删除或更新子表中匹配的行
SET NULL:从父表删除或更新行,会设置子表中的外键列为null,但必须保证子表列没有指定NOT NULL,也就是说子表的字段可以为null;
RESTRICT:即限制,如果父表删除或更新主键,子表引用了,则拒绝父表的删除或更新操作;用的较多;
NO ACTION:标准SQL关键字,在MySQL中与RESTRICT意义相同,默认行为也是拒绝对父表进行删除或更新操作;
外键约束是为了保证数据完整性、一致性,杜绝数据冗余、数据讹误;

4、视图
也称虚表、假表,不同于真的物理表,实际是由查询语句生成的表,可以通过视图进行CRUD增删改查操作,建议只用来查;查的慢一般是考虑用缓存、缓存是在内存,速度快;

视图作用
1)简化操作
将复杂查询SQL语句定义为视图,可以简化查询;把视图当表使用,把N张表的查询语句创建成视图;
2)数据安全
视图可以只显示真实表的部分列,或计算后的结果,隐藏真实表的数据;做到了数据隔离,隐藏了真正数据和字段;对核心业务常常只把视图暴露出来,也只给查的权限,极大的保证了安全性;实际使用视图更多是为了数据安全,不把核心表的字段暴露出来;建一个中间数据层供人访问;
实际更多使用建模工具创建数据库,会用到建模语言UML,建好模型再转化成数据库的表、Python中的类;

5、数据类型

int:一般id就选int,到了bigint级别就要考虑分表了,而不是纠结于int、bigint、smallint;bool也是tinyint,0是假,非0、包括负数是真;int最大42亿;
float:浮点数的数值较小,如果浮点数数值较大,建议用double;浮点数都是有精度的,并不是准确表达,有的无理数根本无法准确表达;
date:目前够用;datetime也够用;timestamp在2037年就到期了;
char:固定长度的优势是物理存储对仗整齐,用偏移量很快,即把字符串变成等长的、空间换时间,效率略高,省时;但用的很少;右边会补空格,以凑够字符数M;
varchar:变长字符串,省了空间,常用;不能突破行最大字节数,还要考虑到编码;
text:以文本算,65535个字符,够用了;
BLOB:大数据块字段,以字节算,存二进制;但存文本是文件系统的事,不是数据块,可以只存文件路径,所以text和BLOB基本不用,不建议把大文本大字节存在数据库,而是把相对路径存进去,存一个路径的字符串;大文本大字节不适合存放在关系型数据库的列之中;对文本的搜索一般不放在数据库里,太影响效率,而是放在搜索引擎、如ES;

6、数据库的内建函数
LENGTH函数:返回字节数

7、关系操作
关系:在关系数据库中,关系就是二维表;关系操作就是对表的操作;

关系数据库有三个重要概念
1)选择(selection)
又称为限制,是从关系中选择出满足给定条件的元祖;也就是语句中的select from where,对应一个横向的选择操作,选出一行行;
2)投影(projection)
在关系上投影就是从选择出的若干属性列组成新的关系;一般对应select后的字段,对应从纵向的列的输出,选出若干列;
3)连接(join)
指表与表直接的关系,将不同的两个关系连接成一个关系;输出一个关系;

六、DML

CRUD 增删改查

1、Insert

2、Update
很少用,但记住更新的时候一定要加WHERE条件,常常加IGNORE;

3、Delete
尽量少操作,目前一般是假删、逻辑删除、打标机,不是物理删除;

4、Select
FOR UPDATE会把行进行写锁定,这是排它锁;因为用的是InnoDB,行级锁;
如果查完就对数据做更新,记得加上锁;
查询条件最好还是用索引键,不管是主键、唯一键还是普通索引键,索引键的效率是最高的;或者是查询数字、等职匹配、字符串的前缀匹配;遇到非索引键的查询,可酌情考虑变成索引键,哪怕占空间;

1)查询子句
查询的结果成为结果集recordset,是一个集合;

2)LIMIT子句
常常叫做分页子句;
LIMIT常用于数据分页,数据集常常太大,所以一定要记得用LIMIT分页返回回来;

3)WHERE子句
<>:不等于,<=>(相等或都为空)
BETWEEN:闭区间;
LIKE:只有两个通配符,%指代任意个,_ 指代一个;LIKE语句尽量不要用,有性能问题,非常耗时,有大量IO;实际工作中会用搜索引擎,LIKE语句一般不用;如果用的话尽量做前缀匹配,即字母数字在前,后面是%,决不允许出现前面%后面字母,特别影响效率;
AND OR:短路操作符,会短路,为提高性能尽量早短路;如果很多表达式需要使用AND、OR计算逻辑表达式的值,建议使用小括号避免产生错误、也能使语句更易读;

4)ORDER BY子句
对查询结果进行排序,是拿到结果之后再开始排序;可以升序ASC、降序DESC;缺省升序;
多字段排序:ORDER BY 后的排序字段可以有多个,会优先按照第一个字段排序,如果有重复,再按照第二个字段;记住多个字段都得指定升序或降序;

5)DISTINCT
不返回重复记录
如果对多列进行去重,会把两列合起来(类似元祖),看是否重复;常用的是单列去重;

6)聚合函数
非常常用,SQL做的计算,用distinct比较少;
聚合:产生出一个数据;常常跟分组结合在一起;
用的最多是count;

7)分组查询
Group by子句,如果有条件,使用Having子句过滤分组、聚合过滤的结果;
如果GROUP BY 后有多个字段,则当成元祖看;
执行顺序:where初次过滤完之后,再分组GROUP BY,做聚合运算,最后再做having过滤;最后可以再加LIMIT和OFFSET;再对结果排序,ORDER BY 最后执行;

8)子查询
查询语句可以嵌套,内部查询就是子查询;有时遇到复杂表很麻烦,必须要用子查询;
子查询必须在一组小括号中;
子查询中不能使用order by;没有必要、无意义,因为是用来给外部查询提供数据源;
子查询会形成临时表,一般会对子查询的表重新命别名,有性能问题,但依然很常用,面试中常问;

子查询的常用典型场景:
子查询的表可以做临时表用;比如放在where in语句中;
子查询的结果集可以做数据源;比如放在from语句中,给别人用;
如果子查询的临时表用的很频繁,可以考虑改成视图;子查询用的不多,常用的就以上两种情形;

9)连接join
实际业务最常使用,因为面对的是多张表;多表关联查询才是常态,都要用到关联;
交叉连接 cross join
笛卡尔乘积,全部交叉,最大的问题在于乘法因数,一张表过大结果会超大,非常影响效率;不允许出现;笛卡尔乘积影响性能,尽量避免;
在MySQL中,CROSS JOIN 从语法上说与INNER JOIN 等同;

内连接 inner join
省略为join;有等值连接和自然连接两种;
等值连接On:只选某些field相等的元祖(行),使用On限定关联的结果,避免了笛卡尔乘积;等值条件的左右字段交换位置不会影响结果,只会影响显示的顺序;等值连接是最常用的连接,一定要加等值条件;常常选择多表主键,不要求on后的条件一定为主键,合理即可;
自然连接NATURAL JOIN:特殊的等值连接,自然的使用主键,不能自主选择条件;会去掉重复的列,比如emp_no;自然连接很少用,因为条件不自由;

外连接 outer join
可以省略为join;
分为左外连接,即左连接;右外连接,即右连接;全外连接;

左外连接、右外连接
SELECT * from employees RIGHT JOIN salaries ON employees.emp_no = salaries.emp_no;

左外连接:要求左表所有数据都显示,不能找到对应等值的数据也要保留,剩下的补null;
右外连接:要求右表所有数据都显示,不能找到对应等值的数据也要保留,剩下的补null;
实际生产中经常应用:例如查所有员工工资(可能有的员工未领工资也显示)
自连接
表自己和自己连接,同一张表取两个别名

遇到有层级结构的树状结构的情景,如部门表、员工表、机构结构图,有管理关系、从属关系的,这种层级的不交叉的树状结构,就可以考虑自连接;

七、事务Transaction

InnoDB引擎,支持事务;
事务,由若干条语句组成,指的是要做的一系列操作;要么全部执行,要么出错了全部回滚,这也叫原子性;

1、ACID
关系型数据库中支持事务,必须支持四个属性(ACID)

原子性:事务的工作单位
一致性:跟原子性密切相关,不能有中间状态,每个人看到的都是一致的状态,比如都是未完成、都是完成;也跟隔离性相关,隔离不好有可能被其他事务看到中间脏数据;
隔离性:事务并发过程中,对数据的访问是否隔离;
持久性:事务一旦提交,数据不能丢失、必须永久保存;比如掉电后发现已提交的事务未写磁盘然后开机后立即写磁盘;
ACID 仅限于传统的关系型数据库,做到支持ACID的数据库才能称为支持事务;原子性、一致性、持久性必须达到,隔离性可以调整;

2、隔离级别
隔离性不好,事务的操作就会相互影响,带来不同严重程度的后果;

隔离性不好带来的问题:
1)丢失更新 Lost Update
事务A和B,更新同一个数据,它们都读取了初始值100,A要减10,B要加100,A减10后更新为90,B加100更新为200,A的更新丢失了,就像从来没有减过10一样;
2)脏读
事务A和B,事务B读取到了事务A (这个数据可能是一个中间值,也可能事务A后来回滚事务);事务A是否最后提交并不关心,只要读取到了这个被修改的数据就是脏读;
3)不可重复读 Unrepeatable read
事务A在同一事务中执行相同的查询语句,得到了不同的结果,不能保证同一条查询语句重复读相同的结果,就是不可重复读;跟脏读有点像,但不保证读到的数据一定是未提交的;
例如,事务A查询了一次后,事务B修改了数据,事务A又查询了一次,发现数据不一致了;注意脏读讲的是可以读到相同的数据的,但是读取的是一个未提交的数据,不是提交的最终结果;
4)幻读 Phantom read
事务A中同一个查询要进行多次,事务B插入数据,导致A返回不同的结果集,如同幻觉,就是幻读;幻读可以理解为一种特殊的不可重复读、一种增加了数据的不可重复读;数据集有记录增加了;

数据库为解决上述问题,提出了隔离级别,级别由低到高如下:
数据库基础和ORM
MySQL默认可重复读,Oracle默认读已提交;
隔离级别越高,串行化越高,当前事务处理的中间结果对其他事物不可见程度越高,数据库执行效率越低;隔离级别越低,并行度越高,性能越高;

3、设置隔离级别

一个到数据库的连接就是一个会话,尽量设置会话级别;不要轻易GLOBAL级别,影响面太大;

SERIALIZABLE
串行,解决所有问题;

REPEATABLE READ
事务A中同一条查询语句返回同样的结果,就是可重复读数据;例如语句(select * from user),解决办法有:

  • 对select的数据加锁,不允许其他事务做删除、修改的操作;使得可重复读;
  • 第一次select的时候,对最后一次确认提交的事务的结果做快照;使得可重复读;

解决了不可重复读,但是有可能出现幻读,因为另一个事务可以增删数据,如果select * 的话依旧可以读到新增行的数据,而InnoDB是行级锁;MySQL默认级别;
但幻读常常可以容忍,不可重复读不能容忍,脏读更不能忍;

READ COMMITTED
在事务中,每次select可以读取到别的事务刚提交成功的新的数据;因为读到的是提交后的数据,解决了脏读,但是不能解决不可重复读和幻读的问题,因为其他事务前后修改或增删了数据;Oracle默认级别;

READ UNCOMMITTED
能读取到别的事务还没有提交的数据,完全没有隔离性可言,出现了脏读,当前其他问题都可能出现;几乎没人用;

4、事务语法
START TRANSACTION 或 BEGIN 开始一个事务
START TRANSACTION 是标准SQL语法,使用COMMIT 提交事务后,变更成为永久变更;
ROLLBACK 可以在提交事务之前,回滚变更,事务中的操作就如同没发生一样(原子性);
SET AUTOCOMMIT 语句可以禁用或启用默认的autocommit模式,用于当前连接;SET AUTOCOMMIT=0 禁用自动提交事务,如果开启自动提交,那么有一个修改表的语句执行后就会立即提交、把更新存储到磁盘,即使出错了也会自动回滚再继续;
实际工作中一般不会开启自动提交事务;因为实际工作中经常会批量更改,打开自动提交会有性能问题,最常做的是批量更改、一次提交;

八、数据仓库

1、数据仓库和数据库的区别

本质上数据仓库和数据库都是存放数据的地方,但是数据库关注数据的持久化、数据的关系,为业务系统提供支持,事务支持;数据仓库存储数据是为了分析或者发掘而设计的表结构,可以存储海量数据;最大的区别是使用场景;
数据库存储在线交易数据OLTP(联机事务处理OLTP,On-line Transaction Processing)即常称数据库为在线事务系统;往往用在线上做频繁的增删改,查的话因为有性能问题常常会借助NoSQL、搜索引擎、缓存系统的支持;
数据仓库存储历史数据用于分析OLAP(联机分析处理OLAP,On-line Analytical Processing)即常称数据仓库为在线分析系统;分析不是用来增删改,而是指导生产、分析决策,一般数据仓库用来囤积陈年数据,不建议增删改;

2、数据库
数据库里存放数据一般不宜过多,也不会存储图片、不管大图片小图片,数据库的表数据一旦过多就要考虑分区,有纵向切分的分表分库,横向切分的分表;

九、游标、存储过程和触发器

1、游标Cursor
操作查询的结果集的一种方法;
可以将游标当做一个指针,指向结果集中的某一行;

2、存储过程Store Procedure
数据库系统中,一段完成特定功能的SQL语句,编写成类似函数的方式,可以传参并调用,支持流程控制语句;需要手动调用;

3、触发器Trigger
由事件触发的特殊的存储过程,例如insert数据时触发,条件满足(insert提交成功)则触发程序;
触发器功能虽然强大,但会有性能问题,尤其是写入较多的时候;
存储过程和触发器这两种技术,虽然是数据库高级内容,但基本很少用了;

十、ORM

ORM,O指对象、R指关系、M指映射Mapping和模型Model;对象关系映射,对象和关系之间的映射,使用面向对象的方式来操作数据库;
使用ORM原则:先查后改,查到了持久化的数据后才能做更改、删除,然后再提交;
select、update、delete都要先查后操作,只有insert比较特别;

关系模型和Python对象之间的映射
table -> class 表映射为类,只有一个,定义一份就行了
row -> object 行映射为实例,对应类的一个个实例
column -> property 字段映射为类属性,定义一份

字段有名称、类型、是否主键、默认值、是否自增等特征,所以字段用类描述;
字段类要提供对数据的校验功能,例如声明字段是int类型,要判断数据是否是int;字段有多种类型,不同类型有差异,使用继承方式实现;
字段现在定义为类属性,类属性又适合用类来描述,这就是描述器了;
用到技术:数据描述器协议;

相关文章: