数据库介绍
为什么使用数据库
- 计算机的资源有限,因此不可能吧数据一直存储在内存中,而且内存一旦掉电数据就会不存在,我们需要吧内存中的数据保存在文件中,方便下次编辑,拷贝
- 但随着程序越来越复杂数据也会越来越大,管理这些数据就会变成编程中最难,最重要的问题
- 使用文件保存不安全,可能会被误删除,覆盖,而数据库的访问需要用户名密码及相应的权限和命令
- 文件读取数据并解析数据需要大量的重复代码,并且这种操作效率很低,从数据库中查询数据,只需要提供条件即可
- 文件中删除一条记录异常麻烦,而且不同的程序对于文件的操作不同,接口也不同,因此访问文件的代码不能被复用
- 对于这个问题就有人提出设想,统一文件的访问接口和访问方法,对文件进行统一管理,再增强对于数据管理读取的优化操作,使对数据的管理和使用又方便又快捷
什么是数据库
- 顾名思义,就是数据的仓库(电子文件柜),而对数据进行增加,删除,修改,查询等操作由数据库管理系统(DBMS)进行,对于数据库进行设计,维护,管理的人员叫DBA
数据库的类型
- 层次型数据库
- 数据的存储类似于一棵树,以上下层级关系来组织数据
- 网状型数据库
- 数据的存储类似于一幅图,各个的数据结点和其他结点都有连接关系
- 关系型数据库
- 关系模型就是一张二维表,任何数据都可以通过行号和列号确定,好理解,使用方便
目前主流的关系型数据库
- 商用:Oracle,SQL server,DB2
- 开源:MySQL
- 桌面:Access
- 嵌入式:SQLite,适合于手机,桌面程序
SQL语言介绍
什么是SQL语言
- SQL是结构化查询语言的缩写,用来操作数据库,主要对数据库进行增删改查,高级操作是对数据库进行管理维护
- 目前所有的关系数据库都支持SQL,因此我们只要学会SQL就能操作所有的数据库
- 虽然SQL已经被ANSI组织定义为标准,但不幸的是每个数据库对标准的支持都不太一致,大多数的数据库都进行了扩展
- 理论上SQL可以操作所有的数据库,但如果使用了某个数据库的扩展语句,换一个数据库后就不能再执行了
- 但是SQL的核心功能绝大多数库都支持
- 注意 SQL语言不区分大小写
SQL语言的分类
-
数据定义语言:用于建立,修改,删除数据库对象
CREATE
用于创建表或其他对象结构ALTER
用于修改表或其他对象结构DROP
用于删除表或其他对象TRUNCATE
用于删除表中的数据,保留表结构
-
数据操作语言:用于改变表中的数据
INSERT
将数据插入到表中UPDATE
修改表中已存在的数据DELETE
删除表中的数据
表中的数据改变后需要执行事物控制语言才能把改变应用到数据库中
-
事物控制语言:用来维护表中数据的一致性
COMMIT
提交,确认已经修改的数据ROLLBACK
回滚取消已经进行修改的数据改变SAVEPOINT
表存点,用于回滚到指定保存点
-
数据控制语言:用于执行权限的授予和回收操作
GRANT
用于给用户或角色授予权限REVOKE
用于回收用户或角色的权限
-
数据查询语言
SELECT
如何访问数据库
- 远程登录
ubuntu下开启telnetsudo apt-get install openbsd-inetd sudo apt-get install telnetd sudo /etc/init.d/openbsd-inetd restart sudo netstat -a | grep telnet telnet 120...
- telent
- ssh
- 客户端连接
- 连接名 自定义
- 用户名 student
- 密码 123456
- 保存口令
- 地址 192.168.6.66
- 端口 1521
- SID orcl
SQL中的数据类型
数据类型 | MySQL | Oracle | |
---|---|---|---|
boolean | N/A | Byte | 单字节数据,布尔类型 |
integer | Int/Integer | Number | 整数 |
float | Float | Number | 浮点型 |
string(fixed) | char | char | 定长字符串 |
string(variable) | Varchar | Varchar/Varchar2 | 变长字符串 |
date | date | date | 日期 |
- char(n) 表示字符串长度
- char(10) 数据是"123",依然存储10个字符
- 适合存储字符串长度波动不大的字符串
- 优点 速度快;缺点 浪费空间
- varchar(n) 表示字符串长度
- varchar(10) 数据是"123",依然存储4个字符
- 适合存储字符串长度不确定,波动比较大的字符串
- 优点:根据字符串长度进行存储,节约存储空间
- 缺点:与char比速度稍慢
- Oracle中的Number(P,S)
- P表示总位置,S表示小数点后面的位数
- Number(4) 表示4位整数
- Number(4,2) 小数点后最多两位
数据定义语言
-
创建表
CREATE TABLE 表名(字段名 字段类型,...);
- 例
CREATE TABLE Student( name char(20), sex boolean, age int, id char(8));
查看表结构
DESC 表名
-
修改表
- 修改表名
RENAME 旧表名 TO 新表名;
RENAME TABLE student TO Teacher;
- 增加列
ALTER TABLE 表名 ADD (字段名 字段类型)
ALTER TABLE Teacher ADD (id char(6));
注意 只能增加到表的末尾,不能插入到中间
- 删除列
ALTER TABLE 表名 DROP 字段名;
ALTER TABLE teacher DROP sex;
- 修改列
ALTER TBALE 表名 MODIFY (id char(8))
ALTER TABLE Teacher MODIFY age long;
- 修改表名
-
删除表
- 删除表数据,保留表结构
TRUNCATE 表名
- 删除表结构
DROP TABLE 表名
- 删除表数据,保留表结构
数据操作语言
- 插入数据
INSERT INTO 表名(字段名) VALUES(数据)
INSERT INTO Student(name,sex,age,id) VALUES("hehe",'m',18,190392);
注意 SQL中可以使用’'表示字符串
- 修改表数据
UPDATE 表名 SET 字段名=数据,... WHERE 条件;
UPDATE Student SET sex='w',name='haha', WHERE id=102192;
UPDATE Student SET sex='w',name='haha', WHERE not id=102192;
UPDATE Student SET sex='w',name='haha', WHERE not id=102192 or id=3923823;
- 删除表数据
DELETE TABLE 表名 WHERE 条件
DELETE TABLE teacher WHERE id=1293021;
事物控制语言
-
注意 数据自定义语言立即有效,不能进行事物控制,只有数据操作语言才能进行事物控制
-
在Oracle数据库,一个用户向表中插入数据(他自己能够查询到),其他用户并不能立即查询到,只有执行了COMMIT命令后其他用户才能查询到
-
INSERT INTO Student(name,sex,age,id) VALUES(‘xixi’,‘w’,19,192013);
COMMIT -
在MySQL数据库中,默认设置的 autocommit 一个用户插入的数据其他用户能立即看到
set session autocommit=0;//关闭当前连接的自动提交 set global autocommit=0;//关闭所有连接的自动提交,需要root权限 set session autocommit=0;//关闭当前连接的自动提交 set global autocommit=0;//关闭所有连接的自动提交,需要root权限
-
如果向表中插入了四条记录,此时如果直接rollback则四条记录都会消失,如果只想保留一条,两条,或三条,需要在每插入一个数据后设置一个保存点 使用
rollback to savepoint
回到任意一条记录后 -
当使用数据操作语言对数据进行更改后,如果没有进行COMMIT,那么就可以进行撤销(反悔),使用ROLLBACK命令可以把数据还原
数据查询语言
-
查询表中某些字段
SELECT 字段1,字段2,... FROM 表名;
- 例:查询姓名与年龄
SELECT name,age FROM Student;
- “*” 在SQL语言中也是通配符,代表所有字段
-
SQL中的数学运算
+ - * /
- 例:查询每个员工的平均工资
SELECT name,salary/30 FROM Teacher;
-
字段别名
- 为查询结果新取一个字段名
- 例:查询教师的年薪,并设置新的字段名
SELECT name,salary/30 yearsal FROM teacher
-
字符串操作
Oracle中使用 || 连接字符串,而在MySQL中是CONCAT
CONCAT(s1,s2,…)
返回连接参数产生的字符串,一个或多个待拼接的内容,任意一个为NULL在返回值为NULL- 例:教师名和科目
SELECT name||subject FROM teacher;//Oracle中 select concat(name,concat('_',subject)) name_sub from teach; select concat(name,'_',subject) name_sub from teach;
CONCAT_WS(x,s1,s2,…)
返回多个字符串拼接以后的字符串,每个字符串中间有个x
例:连接字符串,中间用_分隔SELECT CONCAT_WS(' ',name,subject,'hehe') FROM Teacher;
SUBSTRING(s,n,len) MID(s,n,len)
两个函数作用相同,从字符串s中返回一个第n个字符开始,长度为len的字符串
例:获取小马哥 编号SELECT MID(NAME,5,1) FROM Teacher;
LEFT(s,n) RIGHT(s,n)
前者返回字符串s从最左边开始的n个字符,后者返回字符串s从最右边开始的n个字符
例:获取小马哥名字,不要编号SELECT LEFT(name,4) FROM Teacher;
INSERT(s1,x,len,s2)
返回字符串s1,其子字符串起始于位置x的后len个字符被字符串2取代;SELECT INSERT('123456',3,2,'abc');
REPLACE(s,s1,s2)
返回一个字符串,用字符串s2替代字符串s中所有的字符串s1SELECT REPLACE('12345678','345','AbC');
LOCATE(s1,s2) POSITION(s1 IN s) INSTR(s,s1)
三个函数作用相同,返回字符串s1在字符串s中的开始位置(从第几个字符开始)SELECT LOCATE('123','ABCDD123DEF');
FIELD(s,s1,s2,…) 返回第一个字符串s匹配的字符串的位置
SELECT FIELD('123,'ABC','DEF','123','HEHE');
注意 SQL中下标从1开始
- 例:教师名和科目
-
排重显示
SELECT DISTINCT 字段 FROM 表名;
例:查询学习一共开设了多少科目SELECT DISTINCT subject FROM teacher;
-
条件查询
SELECT 字段 FROM 表名 WHERE 条件;
当WHERE条件为真时显示相关数据,配合相关比较运算符
> < >= <= = !=
例:查询所有S1科目的老师SELECT * FROM Teacher WHERE subject = 'S1';
例:所有不教S1科目的老师
SELECT * FROM Teacher WHERE subject != 'S1'; SELECT * FROM Teacher WHERE NOT subject = 'S1';
例:查询年薪超过8w的老师
SELECT * FROM Teacher WHERE salary > 80000;
注意 SQL中字符串可以直接使用比较运算符,与strcmp比较规指一致
范围比较
SELECT * FROM 表名 WHERE x BETWEEN n AND m;
显示x的值 在n到m之间的数据,不包括n,包括m (n,m]
例:查询月薪在6667~6669之间的教师信息SELECT * FROM Teacher WHERE salary BETWEEN 6667 AND 6669;
SELECT * FROM 表名 WHERE x IN(n1,n2,n3);
显示x值在(n1,n2,n3,…)列表中的相关数据
例:查询教授S1,S4,S5科目的老师信息SELECT * FROM Teacher WHERE subject IN('S1','S2','S3');
SELECT * FROM 表名 WHERE x LIKE str;
SQL中字符串可以进行模糊查询,str中可以使用通配符
- %代表任意多个字符, _代表一个字符
例:查询名字叫马哥开头的相关老师信息SELECT * FROM Teacher WHERE name LIKE 'mage%';
例:查询
注意 在SQL中支持逻辑运算符 AND OR NOT && ||
-
空值处理
- 在MySQL中,NULL是一种特殊数据,任何数据与空值进行计算结果为NULL
- IFNULL(x,n)如果x的值为NULL则用n来替代(Oracle中使用nvl函数)
例:查询员工中年薪
SELECT name,base_sal*ifnull(royalty,1)*12 FROM emp;
例:显示有年终奖的员工
SELECT * FROM emp WHERE royalty is not NULL;//不能使用!=
-
排序
- 是对查询的结果进行排序,而不是对数据库中的表进行排序
- SELECT 数据 FROM 表名 ORDER BY 字段 标准;
- 默认升序,DESC降序
例:按基本工资进行排序
- 默认升序,DESC降序
SELECT * FROM emp ORDER BY base_sal;
例:按年终奖降序
SELECT * FROM emp ORDER BY royalty DESC;
例:基本工资为第一排序字段,年终奖系数为第二排序字段
SELECT * FROM emp ORDER BY base_sal,royalty;
-
单行函数
- 对表中的数据每处理一行就返回一个结果
- UPER 小写转大写
SELECT id,UPER(name) FROM emp;
- LOWER 大写转小写
SELECT LOWER(POST) FROM emp;
- INITCAP 首字母大写,MySQL中不支持
SELECT id,INITCAP(name) FROM emp;
- LENGTH 计算字符串长度
SELECT id,LENGTH(name) FROM emp;
TO_CHAR 其他类型的数据转换成字符串,MySQL中不支持
-
组函数
- 一次查询只得到一个结果,如果在数据进行分组的情况下,一个分组只得到一个结果
COUNT 计数
例:统计101部门的员工数量
SELECT * FROM emp WHERE dept_id=101;
MAX 求最大值
例:求基本工资最高值SELECT MAX(base_sal) FROM emp;
MIN 求最小值
SUM 求和
例:求基本工资总支出SELECT SUM(base_sal) FROM emp;
AVG 求平均
例:求员工平均工资SELECT AVG(base_sal) FROM emp;
- 一次查询只得到一个结果,如果在数据进行分组的情况下,一个分组只得到一个结果
-
多表查询
- 根据员工表,部门表查询出每个员工的上班地址
SELECT emp.name,addr FROM emp,dept WHERE dept_id=dept.id;
-
分组查询
SELECT 组函数(字段) FROM 表名 GROUP BY 字段
例:每个部门的平均工资SELECT dept.name,AVG(sal) FROM emp,dept WHERE dept_id=dept.id GROUP BY dept_id;