Quantcast
Channel: CodeSection,代码区,数据库(综合) - CodeSec
Viewing all articles
Browse latest Browse all 6262

数据库知识体系+sql语句实现存储过程和函数+应用程序接口

$
0
0

按存储模型分为:关系次数据库、网络次数据库、层次数据库。不同的数据库的是按不同的数据结构组织和联系的

数据结构:数据的组织形式与数据之间的联系 用ds=(D, R)其中D表示数据,R表示数据间的联系。

数据结构类型:数据结构类型分为数据的逻辑结构和数据的物理结构

逻辑结构:以数据的组织形式和联系方式,来观察数据与分析数据,不考虑存储位置

物理结构:数据在计算机存储结构

管理技术发展历程:

顺序存取 随机存取 数据共享和集中 群集、共享 数据独立 满足复杂的数据类型 管理技术发生变化:不再仅是存储和管理 需要明确存储结构,指出存取路径 不需要 数 据,而是转变为用户所需要的数据管理方式

穿孔卡片--》磁带----------》磁盘----------------》网状数据库-------------》层次数据库--->关系数据库--------》面向对象数据库--------------》数据仓库

常用的数据库分类和数据仓库

关系型数据库:oracle sqlserver mysql access

非关系型数据库分类如下:

键值存储数据库:Redis Memcached

以键值形式存储,类似哈希表,以key为切入点带入哈希函数key=func(key)(直接定址法 数据分析法 平方取中法 除留余数法 随机数法),用那种方式的哈希函数根据以下条件:1 计算哈希函数所需的时间 2 关键字的长度 3 哈希表的大小 4 关键字的分布情况5记录的查找范围,得到新的key,如果相同的key(数组地址),即冲突,处理的方法有:1 开放定址法 2再哈希法 3链地址法4建立一个公共溢出区。不同就直接访问数据。

特点:简单、易部署、高并发

文档存储数据库:mongodb couchDB

面向文档数据库会将数据以文档形式存储。每个文档都是自包含的数据单元,是一系列数据项的集合。每个数据项都有一个名词与对应值,值既可以是简单的数据类型,如字符串、数字和日期等;也可以是复杂的类型,如有序列表和关联对象。数据存储的最小单位是文档,同一个表中存储的文档属性可以是不同的,数据可以使用XML、JSON等多种形式存储。也就是逻辑结构为:文档-------》数据项-----键-----》值。数据项之间允许嵌套。

特点:比键值数据库查询效率高

列存储数据库:Hbase

把相关数据项(属性)存储在同一个列族中,不相关就放在不同的列族。

特点:用于分布式存储海量数据(分布式就是计算机网络中的不同节点间可以相互访问,同时它在自己节点上又是独立的)

图数据库:Neo4J,inforGrid

数据以图的方式存储,每个实体被视作为顶点,它们之间的关系视为边。

关系数据库中的基本概念:

简介:

安装

架构与组件

目录结构

连接组成服务器对象与对象资源管理器

启动

数据库管理:

数据库对象

数据库文件及文件组

创建数据库

获取数据库信息

删除、修改数据库

事务日志

备份与还原

数据字典

数据库设计过程基本概念:

数据库设计规范:第一范式 (属性值是不可分割的最小单元)、第二范式 (非主属性完全依赖主键,不存在部分依赖)、第三范式(非主属性仅函数依赖主键,即不存在传递依赖)

关系:二维表

元组:每一行

属性:每一列,也叫字段

属性值:行与列交会处

超键:能唯一标识元组的属性集,一个超键可由一个属性或者多个属性组合,属性中可由多余的(有它或者没有都可以构成一个超键)

候选键:与超键一样,但它不包含多余属性

主键:一个关系(表)中可以有多个候选键(可有多个属性集{{属性,属性},{属性} ),选择其中一个候选键做为主键。

外键:某一个属性集在在另一张表中是主键,但在本表中不是主键 就称为外键

主属性:在任何候选键中的属性为主属性,否则为非主属性

数据库设计流程:

E-R:实体、属性、关系 表结构 数据存储在计算机上了 当数据量达到亿万级就要优化

需求分析-----》概念结构设计-------------》逻辑设计--------》物理设计---------------------》数据库性能优化,改进读、写性能

E-R:实体-关系模型


数据库知识体系+sql语句实现存储过程和函数+应用程序接口

表与表间关系:无、一对一(表A有一条记录、一对多、多对多

一对一:表A中的一条记录在表B中有一条记录与之对应。反过来,表B中的一条记录在表A中仅有一条记录与之对应。

一对多:表A中的一条记录在表B中有多条记录与之对应。反过来,表B中的一条记录在表A中仅有一条记录与之对应。

多对多:表A中的一条记录在表B中有多条记录与之对应。反过来,表B中的一条记录在表A中也有多条记录与之对应。
如果两个表之间没关系,则可以利用中间表发生关系。即中间表都有两表的外键。表A想取表B的数据可以通过中间表去取。大数据中两表之间不设外键,不发生直接关系。

数据类型

char 与nchar定长字符串。不足补空格,读写速度比varchar与nvarchar快

varchar与nvarchar 自动增长 n代表支持unicode 数据存储在表中

text与ntext保存大量文本(大于8KB),数据保存在另外空间

int smallint

double float

decimal[(p[,s])] numeric[(p[,s])]

datetime smalldatetime 'yyyy-mm-dd hh24:mi:ss'

image 位存储

binary[(n)] varbinary 二进制 大小是n+4字节

表结构

CREATE TABLE Seller IF NOT EXISTS ‘Seller'
(SaleID char(3) NOT NULL,
SaleName char(8) NOT NULL,
Sex char(2),
Birthday datetime,
HireDate datetime,
Address char(60),
Telephone char(13),
Note char(200)
)

约束: primary key foreign key default check unique

JOIN: 如果表中有至少一个匹配,则返回行 只显示匹配的
LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行 先显示匹配 再显示左表没匹配的 右表为null
RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
FULL JOIN: 只要其中一个表中存在匹配,就返回行 不管匹配不匹配都显示
并集UNION :SELECT column1, column2 FROM table1 UNION SELECT column1, column2 FROM table2
交集JOIN :SELECT * FROM table1 AS a JOIN table2 b ON a.name=b.name
差集NOT IN :SELECT * FROM table1 WHERE name NOT IN(SELECT name FROM table2)
笛卡尔积CROSS JOIN :SELECT * FROM table1 CROSS JOIN table2 ( 与 SELECT * FROM table1,table2相同)

注意:表空间分配,表分区

表结构修改

修改的操作包括:增加或删除列、修改列的名称、数据类型、数据长度、改变表的名称等。

ALTER TABLE table_name
{ ADD column_name date_type
[DEFAULT contant_expression][IDENTITY(SEED,INCREMENT)][NULL | NOT NULL]
| DROP COLUMN column_name
| ALTER COLUMN column_name new_datetype [NULL | NOT NULL ]
}

增删改查

insert

INSERT [ INTO ] table_name [ ( column_name [,…n] ) ]
VALUES ( expression | NULL | DEFAULT [,…n] )

delete、tracate、drop

DELETE [ ( column_name [,…n] ) ] [ FROM ] table_name
[ WHERE search_conditions] 注意:没有列表示删除表中的所有数据

TRACATE table_name 删除表中所有数据,是整个表直接操作,不写入日志,速度比delete快

DROP table_name IF EXISTS TABLE_NAME把表结构和数据都删了

update

UPDATE table_name
SET column_name=expression [,…n]
[ WHERE search_conditions ]

select

SELECT [ALL| DISTINCT] [TOP n [PERCENT] select_list [计算表达式]
[ INTO new_table ] FROM [table_nameA join_type|apply_type|pivot|unpivot]| ]table_nameB
[ON |AS]
[ WHERE search_condition ]
[ GROUP BY group_by_expression ]
[ HAVING search_condition ]
[ ORDER BY order_expression [ ASC | DESC ] ]

常用的查询条件:like '张%'、 in not in 、 IS NULL IS NOT NULL、NOT 、AND 、OR、 >=、EXISTS、BETWEEN a AND b、ALL、SOME、ANY.

外连接与内连接和笛卡尔乘积之间关系?

注意:查询顺序是from A---->JOIN B ----> on(筛选删除是暂时的,用于添加outer外部行)-------where(帅选删除是永久的)----->group by(分组)------>having(分组条件,不满足条件就删除) ------>select计算表达式-------->distinct----->top(还没排序,只是列出多少行,数据行已经确定)---->order by(排序)---->set-----游标 每一状态结果生成一个虚拟表原来操作。

函数:

内置函数:

聚合函数:

count(*) 计算元组个数

count(列名)计算某一列中的数据的个数

COUNT DISTINCT(列名)计算某一列不同值的个数

SUM(列名)计算某一列中值个总和

AVG(列名)计算某一列值的平均数

MIN(列名)求(字符、日期、属性列)的最小值

MAX(列名)

字符串函数

数学函数

日期函数

系统函数:

转换函数:

包:包一般是是函数和存储过程的封装,包含包头和包体

包头:定义函数和存储过程

包体:函数和存储过程的实现

自定义函数:(mysql)

DELIMITER // (修改默认结束符;)
CREATE FUNCTION addTwoNumber(x SMALLINT UNSIGNED, Y SMALLINT UNSIGNED)
RETURNS SMALLINT
BEGIN
DECLARE a, b SMALLINT UNSIGNED DEFAULT 10;
SET a = x, b = y;
RETURN a+b;
END//

自定义存储过程:(mysql)

CREATE PROCEDURE procedure_name (in p_id int unsigned, out userNums int unsigned ,inout int unsigned)
BEGIN
执行体
//in表示函数被调用执行时,参数值先确定
//out表示参数值可以在存储过程体重改变,并返回
//inout表示函数被调用时先指定,可以改变和返回

//特点:预编译速度快,灵活,减少网络流量(调用传几个参数 而不是大量的sql语句),安全(设置特定用户才能使用存储过程以及传参数形式防止sql注入攻击)

//不好是,大量存储过程占用空间和维护难,重新编译高耦合
END//

游标:游标分为静态游标(结果集是对数据库数据的一个备份,对结果集进行增删改查不改变数据库中数据)和动态游标ref

静态游标分为:显示游标与隐性游标

游标操作:

BEGIN
DECLARE no_more_record INT DEFAULT 0;
DECLARE pID BIGINT(20);
DECLARE pValue DECIMAL(15,5);
DECLARE cur_record CURSOR FOR SELECT colA, colB from tableABC;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_record = 1;
OPEN cur_record;
FETCH cur_record INTO pID, pValue;
WHILE no_more_record != 1 DO
INSERT INTO testTable(ID, Value)
VALUES (pID, pValue);
FETCH cur_record INTO pID, pValue;
END WHILE;
END

定义游标

DECLARE CURSOR cursor_name IS SELECT 结果集

打开游标

OPEN cursor_name

赋值变量

FETCH cursor_name INFO 行变量//fetch取当前游标指向的记录并赋值给行变量.

输出:行变量.属性(列名),即可把该记录下指定的列值输出

关闭游标

CLOSE cursor_name//关闭游标,关闭后就不能对其进行结果集操作

视图:数据库中虚拟的表 显示的数据是最新的 每次由数据库引擎(识别sql语法是否正确)通过sql语句重建

CREATE VIEW view_name AS SELECT column_names FROM table_name WHERE conditions;

事务和锁:保证数据安全

事务特点

1、事务的原子性
一组事务,要么成功;要么撤回。
2、稳定性
有非法数据(外键约束之类),事务撤回。
3、隔离性
事务独立运行。
一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。
事务的100%隔离,需要牺牲速度。
4、可靠性
软、硬件崩溃后,InnoDB数据表驱动会利用日志文件重构修改。

可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit选项 决定什么时候吧事务保存到日志里。

事务操作流程

开启事务
START TRANSACTION 或 BEGIN
提交事务(关闭事务)
COMMIT
放弃事务(关闭事务)
ROLLBACK
折返点
SAVEPOINT adqoo_1
ROLLBACK TO SAVEPOINT adqoo_1
发生在折返点 adqoo_1 之前的事务被提交,之后的被忽略

事务的终止

事务模式:

设置“自动提交”模式
SET AUTOCOMMIT = 0
每条SQL都是同一个事务的不同命令,之间由 COMMIT 或 ROLLBACK隔开
掉线后,没有 COMMIT 的事务都被放弃
事务锁定模式
系统默认: 不需要等待某事务结束,可直接查询到结果,但不能再进行修改、删除。
缺点:查询到的结果,可能是已经过期的。
优点:不需要等待某事务结束,可直接查询到结果。
需要用以下模式来设定锁定模式
1、SELECT …… LOCK IN SHARE MODE(共享锁)
查询到的数据,就是数据库在这一时刻的数据(其他已commit事务的结果,已经反应到这里了)
SELECT 必须等待,某个事务结束后才能执行
2、SELECT …… FOR UPDATE(排它锁)
例如 SELECT * FROM tablename WHERE id<200
那么id<200的数据,被查询到的数据,都将不能再进行修改、删除、SELECT …… LOCK IN SHARE MODE操作
一直到此事务结束
共享锁 和 排它锁 的区别:在于是否阻断其他客户发出的 SELECT …… LOCK IN SHARE MODE命令
3、INSERT / UPDATE / DELETE
所有关联数据都会被锁定,加上排它锁
4、防插入锁
例如 SELECT * FROM tablename WHERE id>200
那么id>200的记录无法被插入
5、死锁
自动识别死锁
先进来的进程被执行,后来的进程收到出错消息,并按ROLLBACK方式回滚
innodb_lock_wait_timeout = n 来设置最长等待时间,默认是50秒
事务隔离模式
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL
READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE
1、不带SESSION、GLOBAL的SET命令
只对下一个事务有效
2、SET SESSION
为当前会话设置隔离模式
3、SET GLOBAL
为以后新建的所有MYSQL连接设置隔离模式(当前连接不包括在内)
隔离模式
READ UNCOMMITTED
不隔离SELECT
其他事务未完成的修改(未COMMIT),其结果也考虑在内
READ COMMITTED
把其他事务的 COMMIT 修改考虑在内
同一个事务中,同一 SELECT 可能返回不同结果
REPEATABLE READ(默认)
不把其他事务的修改考虑在内,无论其他事务是否用COMMIT命令提交过
同一个事务中,同一 SELECT 返回同一结果(前提是本事务,不修改)
SERIALIZABLE
和REPEATABLE READ类似,给所有的SELECT都加上了 共享锁
出错处理
根据出错信息,执行相应的处理

索引:排序占用存储空间

触发器:保证数据正确性

在Java中使用数据库进行JDBC编程时,Java程序中通常应包含下述几部分内容:
(1) 在程序的首部用import语句将java.sql包引入程序:
import java.sql.*;
(2) 使用Class.forName( )方法加载相应数据库的JDBC驱动程序。若以加载jdbc-odbc桥为例,则相应的语句格式为:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
(3) 定义JDBC的URL对象。例如: String conURL="jdbc:odbc:TestDB";
其中TestDB是我们设置的要创建的数据源。
(4) 连接数据库。
Connection s=DriverManager.getConnection(conURL);
(5) 使用SQL语句对数据库进行操作。
(6) 使用close( )方法解除Java与数据库的连接并关闭数据库。
例如: s.close( );
数据库连接
步骤—1
创建一个以JDBC连接数据库的程序,包含7个步骤:
1、加载JDBC驱动程序:
在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),这通过java.lang.Class类的静态方法forName(String className)实现。例如:
try{
//加载MySql的驱动类
Class.forName("com.mysql.jdbc.Driver") ;
//加载oracle驱动
Class.forName("oracle.jdbc.driver.OracleDriver");
//加载sqlserver驱动
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
}catch(ClassNotFoundException e){
System.out.println("找不到驱动程序类 ,加载驱动失败!");
e.printStackTrace() ;
}
成功加载后,会将Driver类的实例注册到DriverManager类中。
步骤—2
提供JDBC连接的URL
?连接URL定义了连接数据库时的协议、子协议、数据源标识。
?书写形式:协议:子协议:数据源标识
协议:在JDBC中总是以jdbc开始
子协议:是桥连接的驱动程序或是数据库管理系统名称。
数据源标识:标记找到数据库来源的地址与连接端口。
例如:(MySql的连接URL)
jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=gbk ; //
useUnicode=true:表示使用Unicode字符集。如果characterEncoding设置为
gb2312或GBK,本参数必须设置为true.characterEncoding=gbk:字符编码方式。
也可表示为:
String url= "jdbc:mysql://localhost:3306/test"; //mysql
String url="jdbc:oracle:thin:@localhost:1521:orcl"; //orcl为数据库的SID
String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb"; //连接sqlserver的url
步骤—3
创建数据库的连接
. ?要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,该对象就代表一个数据库的连接
?使用DriverManager的getConnectin(String url , String username,String password)方法传入指定的欲连接的数据库的路径、数据库的用户名和密码来获得。
例如:
//连接MySql数据库,用户名和密码都是root
String url = "jdbc:mysql://localhost:3306/test" ;
String username = "root" ;
String password = "root" ;
try{
Connection con=DriverManager.getConnection(url,username,password);
}catch(SQLException se){
System.out.println("数据库连接失败!");
se.printStackTrace() ;
}
步骤—4
创建一个Statement
?要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3种类型:
1、执行静态SQL语句。通常通过Statement实例实现。
2、执行动态SQL语句。通常通过PreparedStatement实例实现。
3、执行数据库存储过程。通常通过CallableStatement实例实现。
具体的实现方式:
Statement stmt = con.createStatement() ;
PreparedStatement pstmt = con.prepareStatement(sql) ;
CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ;
步骤—5
执行SQL语句
Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate
和execute
1、ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句,返回一个结果集(ResultSet)对象。
2、int executeUpdate(String sqlString):用于执行INSERT、UPDATE或DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等 (返回影响到的数据记录数)
3、execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合语句。
具体实现的代码:
ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;
int rows = stmt.executeUpdate("INSERT INTO ...") ;
boolean flag = stmt.execute(String sql) ;
步骤—6
处理结果
两种情况:
1、执行更新返回的是本次操作影响到的记录数。
2、执行查询返回的结果是一个ResultSet对象。
? ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些行中数据的访问。
? 使用结果集(ResultSet)对象的访问方法获取数据:
while(rs.next()){
String name = rs.getString("name") ;
String pass = rs.getString(1) ; // 此方法比较高效(列是从左到右编号的,并且从列1开始)
}
步骤—7
关闭JDBC对象
操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声 明顺序相反:
1、关闭记录集
2、关闭声明
3、关闭连接对象

优化考虑的问题:存储大数据、减少I/0、cpu、内存、存取速度快、安全、共享、独立、扩展、减少冗余、接口,并发、管理与控制、数据结构


Viewing all articles
Browse latest Browse all 6262

Trending Articles