【数据库】SQL语法
https://blog.csdn.net/weixin_42915286/article/details/85339284
MySQL:
5K QPS
一般抗到2K就差不多了
数据库原理
SQL是什么?
SQL代表结构化查询语言(Structured Query Language)。SQL是用于访问数据库的标准化语言。
SQL包含三个部分:
- 数据定义语言包含定义数据库及其对象的语句,例如表,视图,触发器,存储过程等;
- 数据操作语言包含允许您更新和查询数据的语句。
- 数据控制语言允许授予用户权限访问数据库中特定数据的权限。
关系型数据库 与 非关系型数据库
当前数据库分为 关系型数据库 和 非关系型数据库
(关系型 与 分布式 相对立);
1.关系型数据库
关系型数据库:指采用了关系模型(即表结构:二维表格模型)来组织数据 的 数据库。
(非关系型数据库:指非关系型的,分布式的,且一般不保证遵循ACID原则的数据存储系统。)
关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。
关系模型中常用的概念:
关系:(表名)一张二维表,每个关系都具有一个关系名,也就是表名
元组:(行)二维表中的一行,在数据库中被称为记录
属性:(列)/(字段) 二维表中的一列,在数据库中被称为字段
域:(属性取值范围) 属性的取值范围,也就是数据库中某一列的取值限制
关键字:一组可以唯一标识元组的属性,数据库中常称为主键 Primary Key,由一个或多个列组成
关系模式:(表结构) 指对关系的描述。其格式为:关系名(属性1,属性2, … … ,属性N),在数据库中成为表结构
码:表中可以唯一确定一个元组的某个属性(或者属性组),如果这样的码有不止一个,那么大家都叫候选码,我们从候选码中挑一个出来做老大,它就叫主码。
传递依赖:
关系型数据库的优点:
1.容易理解:二维表结构是非常贴近逻辑世界的一个概念,关系模型相对网状、层次等其他模型来说更容易理解
2.使用方便:通用的SQL语言使得操作关系型数据库非常方便
3.易于维护:丰富的完整性(实体完整性、参照完整性和用户定义的完整性)大大减低了数据冗余和数据不一致的概率;
关系型数据库存在的问题:
1.网站的用户并发性非常高,往往达到每秒上万次读写请求,对于传统关系型数据库来说,硬盘I/O是一个很大的瓶颈;
2.网站每天产生的数据量是巨大的,对于关系型数据库来说,在一张包含海量数据的表中查询,效率是非常低的;
3.在基于web的结构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。当需要对数据库系统进行升级和扩展时,往往需要停机维护和数据迁移。
4.性能欠佳:在关系型数据库中,导致性能欠佳的最主要原因是多表的关联查询,以及复杂的数据分析类型的复杂SQL报表查询。为了保证数据库的ACID特性,必须尽量按照其要求的范式进行设计,关系型数据库中的表都是存储一个格式化的数据结构。
数据库事务必须具备ACID特性,ACID分别是Atomicity原子性,Consistency一致性,
Isolation隔离性,Durability持久性。
当今十大主流的关系型数据库:
Oracle,Microsoft SQL Server,MySQL,PostgreSQL,DB2,
Microsoft Access, SQLite,Teradata,MariaDB(MySQL的一个分支),SAP
2.非关系型数据库
非关系型数据库:指非关系型的,分布式的,且一般不保证遵循ACID原则的数据存储系统。
(严格上来说不是数据库,而是 数据结构化存储方法的集合)
非关系型数据库结构:
非关系型数据库以键值对存储,且结构不固定,每一个元组可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对,不局限于固定的结构,可以减少一些时间和空间的开销。
优点:
1.用户可以根据需要去添加自己需要的字段,为了获取用户的不同信息,不像关系型数据库中,要对多表进行关联查询。仅需要根据id取出相应的value就可以完成查询。
2.适用于SNS(Social Networking Services)中,例如facebook,微博。系统的升级,功能的增加,往往意味着数据结构巨大变动,这一点关系型数据库难以应付,需要新的结构化数据存储。由于不可能用一种数据结构化存储应付所有的新的需求,因此,非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合。
不足:
1.只适合存储一些较为简单的数据;
2.对于需要进行较复杂查询的数据,关系型数据库显的更为合适;
3.不适合 持久存储海量数据;
非关系型数据库的分类:
非关系型数据库都是针对某些特定的应用需求出现的,因此,对于该类应用,具有极高的性能。依据结构化方法以及应用场合的不同,主要分为以下几类:
面向高性能并发读写的key-value数据库:
key-value数据库的主要特点是具有极高的并发读写性能
Key-value数据库是一种以键值对存储数据的一种数据库,类似Java中的map。可以将整个数据库理解为一个大的map,每个键都会对应一个唯一的值。
主流代表:
Redis, Amazon DynamoDB, Memcached,MangoDB
Microsoft Azure Cosmos DB和Hazelcast
提问:属于关系型数据库的是?
A.Oracle
B.MySQL
C.Redis
D.MongoDB
答:
AB
数据库的事务属性:ACID原则
事务:数据库中一个单独的执行单元;
事务必须满足4个属性:
1.Atomicity 原子性
事务是一个不可分割的整体,为保证事务的总体目标,事务必须具有原子性;
当数据修改时,要么全执行,要么全不执行;即不允许事务部分完成,避免了只执行这些操作的一部分而带来的错误;
比如:网购付款环节,由于遭遇停电,环节出了差错,不允许发生用户已付款,但订单未被生成的情况;原子性要求事务必须被完整执行;
2.Consistency 一致性
一个事务执行前后,数据库必须保持一致性状态;
如银行转帐,转账前后,两个账户的金额总和必须保持一致,不允许发生由于并发操作带来的数据丢失、读脏数据、产生幽灵数据;
3.Isolation 隔离性
当两个或多个事务并发执行时,为保证数据的安全性,讲一个事务内部的操作与事务操作隔离起来,不被其他正在进行的事务看到;
数据库有4种类型的事务隔离级别:
1).不提交的读 READ_UNCOMMITTED
2).提交的读 READ_COMMITTED
3).可重复的读 REPETABLE_READ
4).串行化 SERIALIZABLE
4.Durability 持久性(永久性)
事务完成后,DBMS保证他对数据库中的数据的修改是永久性的,当系统或者介质发生故障时,该修改也永久保持。持久性一般通过数据库备份和恢复来保证;
综上,数据库事务属性ACID都是由数据库管理系统来进行保证,程序员在整个运行过程中,无需考虑实现ACID;
范式 Normal Form (NF)
转自:http://blog.chinaunix.net/uid-10073362-id-225057.html
范式是符合某一种级别的关系模式的集合。
数据库范式是数据库设计中必不可少的知识;
没有对范式的理解,就无法设计出高效率、优雅的数据库,甚至设计出错误的数据库。而想要理解并掌握范式却并不是那么容易。教科书中一般以关系代数的方法来解释数据库范式。这样做虽然能够十分准确的表达数据库范式,但比较抽象,不太直观,不便于理解,更难以记忆。
本章用较为直白的语言介绍范式,旨在便于理解和记忆,这样做可能会出现一些不精确的表述。
首先要明白,范式的包含关系:
一个数据库设计如果符合第二范式,一定也符合第一范式;
如果符合第三范式,一定也符合第二范式……
(1).1NF 第一范式
指数据表中每一列都是 【不可分】 的基本数据项;
重点是【不可分】(即原子性):
这让我想起自己以前设计一个“学生成绩表”时所遇到的问题:
表格中:sno=1的学生有四门成绩,那么如何妥善把这四门成绩放入表格?
当初的想法是:把四门成绩全部挤在sno=1的这一行中;但结果可想而知,无法做到;
经过指点后才知,应该配置四个sno=1的行,分别把四门成绩配置在这四行中。
最初的想法违背了第一范式“不可分”的原则,也就不叫关系型数据库了。
————————————————————
(2).2NF 第二范式
必须先满足1NF,且要求数据库表中每个实例或行必须可以被唯一区分;
符合1NF,并且,非主属性完全依赖于码。(注意是完全依赖不能是部分依赖,设有函数依赖W→A,若存在XW为码,有X→A成立,那么称W→A是局部依赖,否则就称W→A是完全函数依赖)
一个学生上一门课,一定是特定某个老师教。所以 (学生,课程)->老师;
一个学生上一门课,一定在特定某个教室。所以 (学生,课程)->教室;
一个学生上一门课,他老师的职称可以确定。所以 (学生,课程)->老师职称;
一个学生上一门课,一定是特定某个教材。所以 (学生,课程)->教材
一个学生上一门课,一定在特定时间。所以 (学生,课程)->上课时间
因此 (学生,课程) 是一个码。
但,一个教材一定是由一个课程指定的(课程:一年级语文 指定了教材:《小学语文1》);
那么就有:
课程->教材
回过头看, (学生,课程) 是个码,上方的结论中却是:课程指定了教材;这就叫做不完全依赖,或者说部分依赖;
出现这样的情况,就不满足第二范式。
那应该怎么解决呢?投影分解,将一个表分解成两个或若干个表:
把教材列放在另一张表,两张表中都有课程列;
新关系通过学生表中的外关键字:课程 联系,在需要时进行连接;
————————————————————
(3).3NF 第三范式
符合2NF,并且,消除传递依赖(也就是每个非主属性都不传递依赖于候选键,判断传递函数依赖,指的是如果存在"A → B → C"的决定关系,则C传递函数依赖于A。)
上面的“学生上课新表”符合2NF,但是它有传递依赖!在哪呢?
(学生,课程)-> 老师
(老师)-> 老师职称
看上去,职称和(学生,课程)没有一点关系;
然而,(学生,课程)-> (老师)
所以这是一个依赖传递;
依赖传递带来的问题:
1、老师升级了,变教授了,要改数据库,表中有N条,改了N次……(修改异常)
2、没人选这个老师的课了,老师的职称也没了记录……(删除异常)
3、新来一个老师,还没分配教什么课,他的职称记到哪?……(插入异常)
那应该怎么解决呢?和上面一样,投影分解:
第二范式(2NF)和第三范式(3NF)的概念很容易混淆,区分它们的关键点在于:
2NF:非主键列是否完全依赖于主键,还是依赖于主键的一部分;
3NF:非主键列是直接依赖于主键,还是直接依赖于非主键列。
简单总结1/2/3范式:
第一范式(1NF)无重复的列(原子性);原子性,字段不可再分割;
第二范式(2NF)属性完全依赖于主键;完全依赖,没有部分依赖;
第三范式(3NF)属性不依赖于其它非主属性;没有传递依赖。
举个例子:
◆ 第二范式(2NF):
考虑一个订单明细表:【OrderDetail】
(
OrderID,ProductID,UnitPrice,Discount,Quantity,ProductName
)。
因为我们知道在一个订单中可以订购多种产品,所以单单一个 OrderID 是不足以成为主键的,主键应该是(
OrderID,ProductID
);
显而易见 Discount(折扣),Quantity(数量)完全依赖(取决)于主键(OderID,ProductID),而 UnitPrice(总价),ProductName(产品名) 只依赖于 ProductID。所以 OrderDetail 表存在部分依赖,不符合 2NF。不符合 2NF 的设计容易产生冗余数据。
可以把【OrderDetail】表拆分为:
【OrderDetail】(
OrderID,ProductID,Discount,Quantity
)和
【Product】(
ProductID,UnitPrice,ProductName
)
来消除原订单表中UnitPrice,ProductName多次重复的情况。
OrderID,ProductID
→ 完全依赖的列
ProductID
→ ProductName,UnitPrice(部分依赖)
部分依赖:因为依赖的是主键中的一部分;
◆ 第三范式(3NF):
考虑一个订单表【Order】
(
OrderID,OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity
)
主键是(
OrderID
);
其中
OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity
等非主键列都完全依赖于主键(
OrderID
),所以符合 2NF;
不过问题是
CustomerName
(买家姓名),
CustomerAddr
(收获地址),
CustomerCity
(收货城市) 直接依赖的是
CustomerID
(非主键列),而不是直接依赖于主键,它传递依赖于主键,所以不符合 3NF。
通过拆分【Order】为
【Order】(
OrderID,OrderDate,CustomerID
)和
【Customer】(
CustomerID,CustomerName,CustomerAddr,CustomerCity
)
从而达到 3NF。
OrderID
→ 完全依赖的列
CustomerID
→
CustomerName
,
CustomerAddr
,
CustomerCity
(传递依赖)
传递依赖:因为依赖跟主键无关,隔着一个参数进行了依赖:
OrderID
→
CustomerID
→
CustomerName
,
CustomerAddr
,
CustomerCity
————————————————————
(4).BCNF
符合3NF,并且,主属性不依赖于主属性(也就是不存在任何字段对任一候选关键字段的传递函数依赖)
BC范式既检查非主属性,又检查主属性。当只检查非主属性时,就成了第三范式。满足BC范式的关系都必然满足第三范式。
还可以这么说:若一个关系达到了第三范式,并且它只有一个候选码,或者它的每个候选码都是单属性,则该关系自然达到BC范式。
给你举个例子:假设仓库管理关系表 (仓库ID, 存储物品ID, 管理员ID, 数量),且有一个管理员只在一个仓库工作;一个仓库可以存储多种物品。
这个数据库表中存在如下决定关系:
(仓库ID, 存储物品ID) →(管理员ID, 数量)
(管理员ID, 存储物品ID) → (仓库ID, 数量)
所以,(仓库ID, 存储物品ID)和(管理员ID, 存储物品ID)都是StorehouseManage的候选关键字,表中的唯一非关键字段为数量,它是符合第三范式的。但是,由于存在如下决定关系:
(仓库ID) → (管理员ID)
(管理员ID) → (仓库ID)
即存在关键字段决定关键字段的情况,所以其不符合BCNF范式。它会出现如下异常情况:
(1) 删除异常:
当仓库被清空后,所有"存储物品ID"和"数量"信息被删除的同时,"仓库ID"和"管理员ID"信息也被删除了。
(2) 插入异常:
当仓库没有存储任何物品时,无法给仓库分配管理员。
(3) 更新异常:
如果仓库换了管理员,则表中所有行的管理员ID都要修改。
把仓库管理关系表分解为二个关系表:
仓库管理:StorehouseManage(仓库ID, 管理员ID);
仓库:Storehouse(仓库ID, 存储物品ID, 数量)。
这样的数据库表是符合BCNF范式的,消除了删除异常、插入异常和更新异常。
一般,一个数据库设计符合3NF或BCNF就可以了。
————————————————————
(5).4NF 第四范式
在BC范式以上还有第四范式、第五范式。
·第四范式:要求把同一表内的多对多关系删除。
·第五范式:从最终结构重新建立原始结构。
其实数据库设计范式这方面重点掌握的就是1NF、2NF、3NF、BCNF
四种范式之间存在如下关系:
这里主要区别3NF和BCNF,一句话就是3NF是要满足不存在非主属性对候选码的传递函数依赖,BCNF是要满足不存在任一属性(包含非主属性和主属性)对候选码的传递函数依赖。