数据库
关系型数据库特点
有行和列(又叫字段、域)
表设计-表关系
a) 一对一: 任意跳转一张表
b) 一对多: 在多的一张表中保存两张表直接的关系
c) 多对多: 通过一张中间表保存两张表直接的关系表与表之间关
数据库范式
一句话描述前3个范式:
- 字段原子性、非主键字段完全依赖于所有主键字段、普通字段之间毫无关联
数据库范式(normal form)
- 第一范式:
表中字段具有原子性,不可再分 - 第二范式:
1NF基础上,所有的 非码属性-普通字段 都必须 完全依赖于 候选码属性-(多)主键(的多个字段)。
即普通字段不能只依赖于其中一个主键字段,应该同时与主键的多个字段都有关(如果有多主键)。 - 第三范式:
在2NF的基础之上,所有非主属性不依赖于其他非主属性
即普通字段之间应该毫无关系,不能存在依赖和关联 - BCNF范式(了解即可)
- B和C是两个人名首字母开头
- 一个满足BCNF的关系模式的条件:
- 1.所有非主属性对每一个码都是完全函数依赖。
- 2.所有的主属性对每一个不包含它的码,也是完全函数依赖。
- 3.没有任何属性完全函数依赖于非码的任何一组属性。
- 第四范式:(略)
- 第五范式:(完美范式)(略)
范式的合理使用:
- 尽可能的符合范式是为了消除数据的冗余,合理利用数据库的存储空间,
- 但降低冗余的同时必然存在表的拆分,表的数量增加,出现多张表相互关联,表查询难度增加,多表查询增加
- 因此有时候需要冗余,通过一定的数据冗余减少join的操作,即通过减少表的数量减少关联提升查询效率。
范式案例
- 第一范式:
案例:不能将学生的姓名和年龄作为一个字段,应该分开 - 第二范式:
案例:
–问题表:(学号, 课程名称) → (姓名, 年龄, 成绩, 学分)
–其中,姓名、年龄与课程无关,成绩、学分与学号无关
—解决方案:将表中数据分离。分成课程表、学生表和选课关系 - 第三范式
案例:
–问题表:(学号)→ (姓名,年龄,性别,系别,系办地址、系办电话)
–其中,(学号) → (系别)→(系办地点,系办电话),普通字段存在依赖关联
—解决方案:将学生表和系别表分开
范式说明
- 不满足第二范式的要求,会出现如下问题:
- 数据冗余:同一门课程由n个学生来学习,学分就会重复出现n-1次,如果有一个学生学习m个课程,则学生的姓名和年龄会重复出现m-1次。
- 更新异常:如果课程的学分有变,则需要修改所有选修本课程学生的学分。
- 删除异常:如果一个学生学完了某一门选修课程,应该将他的选修记录从表中删除,但是删除该同学数据会造成该同学学分的丢失
mysql数据库1
数据库中的对象
有表,索引,视图,图表,缺省值,规则,触发器,用户,函数等。
-
表格
数据库中的表与我们日常生活中使用的表格类似,它也是由行(Row) 和列(Column)组成的。列由同类的信息组成,每列又称为一个字段,每列的标题称为字段名。行包括了若干列信息项。一行数据称为一个或一条记录,它表达有一定意义的信息组合。一个数据库表由一条或多条记录组成,没有记录的表称为空表。每个表中通常都有一个主关键字,用于唯一地确定一条记录。 -
索引
索引是根据指定的数据库表列建立起来的顺序。它提供了快速访问数据的途径,并且可监督表的数据,使其索引所指向的列中的数据不重复。如聚簇索引。 -
视图
视图看上去同表似乎一模一样,具有一组命名的字段和数据项,但它其实是一个虚拟的表,在数据库中并不实际存在。视图是由查询数据库表产生的,它限制了用户能看到和修改的数据。由此可见,视图可以用来控制用户对数据的访问,并能简化数据的显示,即通过视图只显示那些需要的数据信息。 -
图表
图表其实就是数据库表之间的关系示意图。利用它可以编辑表与表之间的关系。 -
缺省值
缺省值是当在表中创建列或插入数据时,对没有指定其具体值的列或列数据项赋予事先设定好的值。 -
规则
规则是对数据库表中数据信息的限制。它限定的是表的列。 -
触发器
触发器由事件来触发,可以查询其他表,而且可以包含复杂的SQL语句。它们主要用于强制服从复杂的业务规则或要求。也可用于强制引用完整性,以便在多个表中添加、更新或删除行时,保留在这些表之间所定义的关系。 -
用户
所谓用户就是有权限访问数据库的人。
同时需要自己登陆账号和密码。用户分为:管理员用户和普通用户。前者可对数据库进行修改删除,后者只能进行阅读查看等操作。 -
序列
序列定义存储在数据字典中,序列通过提供唯一数值的顺序表用于简化程序设计工作。 -
函数
函数与过程很类似,一般用于计算数据,声明为FUNCTION,需要描述返回类型,且PL/SQL块中至少有一个有效的RETURN语句;函数不能独立运行,必须作为表达式的一部分;在DML和DQL中可调用函数。
函数的目标是返回一个值。大多数函数都返回一个标量值(scalar value),标量值代表一个数据单元或一个简单值。实际上,函数可以返回任何数据类型,包括表、游标等可返回完整的多行结果集的类型。
视图
1、视图的概念、定义
- 视图是一个虚拟表,其内容由查询定义,是存储在数据库中的查询的SQL语句。
- 同真实的表一样,视图包含一系列带有名称的列和行数据。
- 但是,数据库中只存放了视图的定义,而并没有存放视图中的数据,这些数据存放在原来的表中。
- 使用视图查询数据时,数据库系统会从原来的表中取出对应的数据。因此,视图中的数据是依赖于原来的表中的数据的。
- 一旦表中的数据发生改变,显示在视图中的数据也会发生改变。同样对视图的更新,会影响到原来表的数据。
2、视图的作用----为什么用视图?
视图是在原有表或者视图的基础上重新定义的虚拟表,这可以从原有的表上选取对用户有用的信息,忽略次要信息,其作用类似于筛选。视图的作用归纳为如下几点:
- 使操作简单化
视图需要达到的目的就是所见即所需。视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。 - 增加数据的安全性
通过视图,用户只能查询和修改指定的数据。指定数据之外的信息,用户根本接触不到。这样可以防止敏感信息被未授权的用户查看,增强机密信息的安全性。 - 提高表的逻辑独立性
视图可以屏蔽原有表结构变化带来的影响。例如原有表增加列和删除未被引用的列,对视图不会造成影响。同样,如果修改表中的某些列,可以使用修改视图来解决这些列带来的影响。
索引
索引相关说明:
- 索引就是一个数据结构,我们把表中的记录用一个适合高效查找的数据结构来表示,目的就是让查询变得更高效。
- 数据库的引擎:
- 在mysql中使用最广泛的数据引擎是InnoDB 引擎,它里面用的是 B+ 树索引
- 二叉查找树–>平衡二叉树->B+ 树
- Innodb和MyISAM这两种引擎的区别:
- MyISAM类型的表强调的是性能,其执行速度比InnoDB类型更快,但是不提供事务支持,
- InnoDB提供事务支持以及外键。
索引分类
- 1、普通素引
这是最基本的索引,它设有任何根制. - 2、唯一索引
它与前面的普通素引类似,不同的就是:索引列的值必须难一,但允许有空值。如果是组合素引,则列值的组合必须难一。 - 3、主键素引
它是一种特殊的难一索引,不允许有空值。一般是在建表的时候同时创建主键素引。 - 4、聚簇索引
聚簇索引的索引顺序就是数据存储的物理存储顺序,这样能保证索引值相近的元组所存储的物理位置也相近。 - 5、全文索引(FULLTEXT)全文索引只能创建在数据类型为VARCHAR或TEXT的列上,建立全文索引后,能够在建立了全文索引的列上进行全文查找。全文索引只能在MyISAM存储引醉的表中创建。
- 6.实际工作使用中,索引可以建立在单一列上,称为单列索引,也可以建立在多个列上,称为组合素引。
哪些字段适合建立索引
- 表的主关键字—自动建立唯一索引
- 唯一约束的表字段
- 做表关联的字段
- 做排序的字段
- 做统计或分组的字段
数据库的索引操作
- 查看一个表中是否已经创建索引
show index from 表名; - 创建索引
create index 索引名 on 数据表(字段名称长度) - 删除索引
drop index 索引名称 on 数据表
索引的优点和缺点
-
优点:
- 1.最主要:加快数据的检索速度
- 2.唯一性索引可以保证数据库表中每一行数据的唯一性
- 3.加速表和表之间的连接
- 4.减少查询中分组和排序的时间
-
缺点:
- 1.创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加
- 2.索引本身占物理空间
- 3.当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度
存储过程
一,什么是数据库存储过程?
- 存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。
- 存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。
- 存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。
二,为什么要使用存储过程?
优点:
- 存储过程可封装,并隐藏复杂的商业逻辑。
- 存储过程可以回传值,并可以接受参数。
- 存储过程无法使用 SELECT 指令来运行,因为它是子程序,与查看表,数据表或用户定义函数不同。
- 存储过程可以用在数据检验,强制实行商业逻辑等。
缺点:
- 存储过程,往往定制化于特定的数据库上,因为支持的编程语言不同。当切换到其他厂商的数据库系统时,需要重写原有的存储过程。
- 存储过程的性能调校与撰写,受限于各种数据库系统。
三,存储过程的分类
- (1)数据库系统存储过程:数据库自带
- (2)用户自定义数据库存储过程:由用户根据需要自定义
四,MySql数据库存储过程
- 1、创建存储过程:
create procedure 存储过程名字() begin SQL语句/逻辑 end;
- 2、调用存储过程:
call 存储过程名字();
call 存储过程名字(@参数1,@参数2,@参数3,...);
- 3、删除存储过程:
drop procedure if exists 存储过程名字; - -这里存储过程名字后面没有()
数据库的事务(ACID)
1、什么是事务:
- 简单的说,事务是将一堆的SQL语句绑定在一起执行,结果是要么全都执行成功,要么全都执行失败。而且是都成功了才算成功,但凡有一条执行失败,就按全失败来处理!
2、事务的特性:
- 原子性(Atomicity):事务中的所有操作作为一个整体像原子一样不可分割,要么全部成功,要么全部失败。
- 一致性(Consistency):事务的执行结果必须使数据库从一个一致性状态到另一个一致性状态。
一致性状态是指:- 1.系统的状态满足数据的完整性约束(主码,参照完整性,check约束等)
- 2.系统的状态反应数据库本应描述的现实世界的真实状态,比如转账前后两个账户的金额总和应该保持不变。
- 隔离性(Isolation):并行的多个事务对数据库的操作存在一定级别的隔离。
- 持久性(Durability):事务一旦提交,其对数据库的更新就是持久的。任何事务或系统故障都不会导致数据丢失。
3、事务的并发读问题
- 脏读:
- 一个事务对表中记录的未成功修改,影响到了另一个事务对表中相关记录的读取
- 在一个事务中读取到另外一个事务中未提交的数据。
- 事务T1更新了一行记录,还未提交所做的修改,这个T2读取了更新后的数据,然后T1执行回滚操作,取消刚才的修改,所以T2读取的行就无效,也就是脏数据。
- 不可重复读取:
- 一个事务对表中记录的成功修改,影响到了另一个事务对表中相关记录的读取
- 在一个事务中读取到另外一个事务已提交的数据(在同一个事务中对同一数据的两次查询结果不一致,因为在两次查询期间,有其他事务对该数据进行了修改操作)
- 事务TI读取一行记录,紧接着事务T2修改了T1刚刚读取的记录,然后T1再次读取,发现与第一次读取的记录不同,这称为不可重复读。
- 幻读:
- 一个事务成功添加或删除了表的记录,影响到了另一个事务对表中相关记录的读取
- 在同一事务中,对同一张表的两次查询结果不一致,是因为在两次查询期间,有其他事务中对该表进行了插入或者删除操作
- 事务TI读取一条指定where条件的语句,返回结果集。此时事务T2插入一行新记录,恰好满足T1的where条件。然后T1使用相同的条件再次旬,结果集中可以看到T2插入的记录,这条新纪录则是幻读记录。
4、事务的隔离级别
- 1、READ UNCOMMITTED(读未提交数据)
不能防止任何并发读问题
安全性最差,但,性能最高 - 2、READ COMMITTED(读已提交数据)
可以防止脏读,但不能防止不可重复读和幻读。
安全性较差,但,性能较高
是Oracle默认的隔离级别 - 3、REPEATABLE READ(可重复读)
可以防止脏读、不可重复读,但不能防止幻读
安全性较高,但,性能较差
是MySQL默认的隔离级别 - 4、SERIALIZABLE(串行化)
可以防止一切并发读问题
安全性最高,但,性能最差
5、MySQL中的事务
-
在mysql中默认一条SQL语句就是一个事务。
-
如果希望将多条SQL放在一个事务中执行,可以手动开启事务,并手动结束事务
开启事务: start transaction;
结束事务:提交(commit) 和 回滚(rollback) -
例子:使用转账演示mysql中如何开启事务以及如何结束事务
– 开启事务
start transaction;
– A账户减去100元
update acc set money=money-100 where name=‘A’;
– B账户加上100元
update acc set money=money+100 where name=‘B’;
select * from acc;
– 回滚事务 | 提交事务
rollback; | commit;
select * from acc;
mysql数据库2
字段类型(type)
1、数值数据类型
-
整型
-
浮点型
2、字符串数据类型
3、日期和时间数据类型
字段约束
1、作用:
保证数据的完整性和一致性
2、包括:
- not null 表示该字段数据不能为空
- default 表示该字段的默认值
- unique 唯一(列唯一,组合唯一)
- primary key 主键 一张列表中只允许出现一个主键(not null + unique)
- auto-increment 自增长
- foregin key 外键 建立两个表之间的联系
语法:constraint fk_dep foreign key(关联列名) references 被关联表(被关联列) - on delete cascade 同步删除
- on update cascade 同步更新
数据库操作
1-操作数据库、操作表
创建数据库: create database 库名 charset utf8;
create database if not exists 库名 charset utf8;
查看所有数据库: show databases;
删除数据库: drop database 库名;
drop database if exists 库名;
进入/选择数据库: use 库名
创建stu表:
use mydb1;
create table stu(
id int,
name varchar(50),
gender varchar(10),
birthday date,
score double
);
删除表: drop table if exists 表名;
查看表: show tables;
查看表结构: desc 表名;
2-表记录的增、删、改、查
增
-- 如果是在cmd中执行插入记录的语句,先 set names gbk; 再插入记录!
-- 由于id已经设置了主键自增,所以在插入数据,id可以不用给值
insert into stu(id,name,gender,birthday,score) value
(null,'tom','male','2000-3-4',89);
insert into stu value(null,'john','male','2002-5-6',78);
insert into stu value(null,'andy','female','2004-7-6',91);
删
delete from stu; -- 删除stu表中的所有记录
delete from stu where id>2; -- 删除stu表中id大于2的记录
改
update stu set score=score+10;--修改stu表中所有学生的成绩,加10分特长分
update stu set score=83 where id=1;-- 修改stu表中编号为1的学生成绩,将成绩改为83分。
update stu set score=99,gender='male' where id=3;-- 修改3号学生的性别为 'male',成绩改为99;
查
select * from stu;-- 查询学生表中的所有记录
select name,sal,bonus from emp;-- 查询emp表中的所有员工,显示姓名,薪资,奖金
select dept,job from emp;-- 查询emp表中的所有部门和职位
select distinct dept,job from e;--在select之后、列名之前,使用DISTINCT 剔除重复的记录
3-内嵌函数(部分)
4-单表查询
1、WHERE子句查询
语法:SELECT 列名称 | * FROM 表名称 WHERE 列 运算符 值
WHERE子句后面跟的是条件,条件可以有多个,多个条件之间用连接词(or | and)进行连接
下面的运算符可在 WHERE 子句中使用:
--查询emp表中【薪资大于3000】的所有员工,显示员工姓名、薪资
select name,sal from emp where sal>3000;
--查询emp表中【总薪资(薪资+奖金)大于3500】的所有员工,显示员工姓名、总薪资
select name,sal+bonus from emp
where sal+bonus > 3500;
--查询emp表中【薪资在3000和4500之间】的员工,显示员工姓名和薪资
select name, sal from emp
where sal>=3000 and sal<=4500;
--查询emp表中【薪资为 1400、1600、1800】的员工,显示员工姓名和薪资
select name,sal from emp
where sal=1400 or sal=1600 or sal=1800;
2、模糊查询
语法:SELECT 列 | * FROM 表名 WHERE 列名 LIKE 值
LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式。
可以和通配符(%、)配合使用,其中 "%"表示0或多个任意的字符 , ""表示一个任意的字符 。
-- 查询emp表中姓名中以"刘"字开头的员工,显示员工姓名。
select name from emp where name like '刘%';
-- 查询emp表中姓名中包含"涛"字的员工,显示员工姓名。
select name from emp where name like '%涛%';
--查询emp表中姓名以"刘"开头,并且姓名为两个字的员工,显示员工姓名。
select name from emp where name like '刘_';
select name from emp where name like '刘__';
3、多行函数查询
多行函数也叫做聚合(聚集)函数,根据某一列或所有列进行统计
提示:
(1)多行函数不能用在where子句中
(2)多行函数和是否分组有关,分组与否会直接影响多行函数的执行结果。
(3)多行函数在统计时会对null值进行过滤,直接将null值丢弃,不参与统计。
--统计emp表中薪资大于3000的员工个数
select count(*) from emp where sal>3000; -- 7
select count(id) from emp where sal>3000; -- 7
--求emp表中的最高薪资
select max(sal) from emp; -- 返回最高薪资,5000
--统计emp表中所有员工的薪资总和(不包含奖金)
select sum(sal) from emp; -- 薪资总和:39650
select sum(bonus) from emp; -- 奖金总和:5900,多行函数对null会处理,直接丢弃,不参与统计
--统计emp表员工的平均薪资(不包含奖金)
select avg(sal) from emp; -- 39650/12
--统计emp表中的人数
select count(*) from emp; -- 12
4、分组查询
语法:SELECT 列 | * FROM 表名 [WHERE子句] GROUP BY 列;
GROUP BY 语句根据一个或多个列,对where语句后的结果集进行分组。
在分组的列上我们可以使用 COUNT,SUM,AVG,MAX,MIN等函数。
-- 根据部门对员工进行分组
select name,dept from emp group by dept;
-- 统计分组后,每组的人数
select count(*) from emp group by dept; -- 3个组,所以会统计出三个结果
-- 根据job进行分组,统计每个组的人数(每个职位的人数)
select job,count(*) from emp group by job;
-- 如果不分组,直接使用max(sal),这是统计整个emp表中的最高薪资
select max(sal) from emp; -- 5000;
-- 如果根据部门分组,可以分为三个组,再使用max(sal),就是统计每个组的最高薪资
select dept, max(sal) from emp group by dept;
提示:
分组查询中如果有条件判断需要把关键字WHERE换成HAVING
5、排序查询
语法:SELECT 列名 FROM 表名 ORDER BY 列名 [ASC|DESC]
使用 ORDER BY 子句将结果集中记录根据指定的列排序后再返回
--对emp表中所有员工的薪资进行升序(从低到高)排序,显示员工姓名、薪资。
select name,sal from emp order by sal asc;
-- 默认是升序,asc可以省略
select name,sal from emp order by sal;
--对emp表中所有员工的奖金进行降序(从高到低)排序,显示员工姓名、奖金。
select name,bonus from emp order by bonus desc;
6、分页查询
查询公式:limit (页码-1)*每页显示记录数, 每页显示记录数
在mysql中,通过limit进行分页查询
-- 每页显示3条,查询第1页数据
select * from emp limit 0,3;
-- 每页显示3条,查询第2页数据
select * from emp limit 3,3;
-- 每页显示3条,查询第3页数据
select * from emp limit 6,3;
-- 每页显示3条,查询第4页数据
select * from emp limit 9,3;
-- 先根据薪资降序(从高到低)排序
select name,sal from emp order by sal desc;
-- 在排序的基础上,分页查询,每页显示3条,只查询第1页
select name,sal from emp order by sal desc limit 0,3;
5-多表查询
1、笛卡尔积查询
- 所谓笛卡尔积查询就是指,查询两张表,其中一张表有m条记录,另一张表有n条记录,查询的结果是m*n条。
- 虽然笛卡尔积查询中包含大量错误数据,但我们可以通过where子句将错误数据剔除,保留下来的就是正确数据。
-- 查询部门和部门对应的员工信息,员工所属的部门编号,等于部门的编号
select * from dept,emp
where emp.dept_id=dept.id;
2、左外连接
可以将左边表中的所有记录都查询出来,右边表只显示和左边相对应的数据,如果左边表中某些记录在右边没有对应的数据,右边显示为null即可。
--查询【所有部门】及部门对应的员工,如果某个部门下没有员工,员工显示为null
select * from dept left join emp
on emp.dept_id=dept.id;
3、右外连接
可以将右边表中的所有记录都查询出来,左边表只显示和右边相对应的数据,如果右边表中某些记录在左边没有对应的数据,可以显示为null。
--查询【所有员工】及员工所属的部门,如果某个员工没有所属部门,部门显示为null即可
select * from dept right join emp
on emp.dept_id=dept.id;
4、全外连接
- 如果想将两张表中的所有数据都查询出来(左外+右外并去除重复记录),可以使用全外连接查询,
- 但是mysql又不支持全外连接查询。
- 可以使用union将左外连接查询的结果和右外连接查询的结果合并在一起,并去除重复的记录。
select * from dept left join emp on emp.dept_id=dept.id
union
select * from dept right join emp on emp.dept_id=dept.id;
5、内连接
待补充
6、自连接
待补充
6-mysql查询语句的书写/执行顺序
其中,with 后的rollup为分组统计,cube在mysql中不支持,rollup是其特殊情况
mysql数据库优化
mysql性能优化:
核心就是,避免全表扫描,加快检索速度,方法如下:
-
1、为搜索字段建索引
- 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
-
2、当只要 n 行数据时使用 LIMIT n
-
3、避免 SELECT * 做全字段查询
-
4、避免在索引字段上使用计算
-
5、使用预编译查询
-
6、调整where字句中的连接顺序
-
7、尽量将多条sql语句压缩到一句sql中
-
8、使用表的别名
-
9、考虑临时表暂存中间结果
-
10用varchar代替char
-
11、where子句中条件的限制:
- 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null - 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
- 应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20 - in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3 - 应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where num/2=100
应改为:
select id from t where num=100*2 - 应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)=‘abc’–name以abc开头的id
应改为:
select id from t where name like ‘abc%’ - 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
- 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
-
12、可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0 -
13、为每张表设置一个ID(最好是INT型,推荐使用UNSIGNED无符号的INT型,并设置上自动增加的AUTO_INCREMENT标志)
-
14、用union all 替换union
union和union all都是合并多表,但union会去重+排序,union不会,因此可以确认如果合并后没有重复记录,可以用union all
数据连接池的设计—JDBC
注册数据库驱动
获取连接 --
连接url
区时
ssl
用户名和密码
字符集
……