【Java】MySql

文章目录

  • MySQL
    • 1、SQL通用语法、分类
    • 2、SQL数据类型和字段属性
      • 数据类型
      • 字段属性
    • 3、DDL(数据定义语言)
    • 4、DML(数据操作语言)
    • 5、DQL(数据查询语言)
      • 1、基础查询
      • 2、条件查询
      • 3、排序查询
      • 4、分组查询
      • 5、分页查询
      • 小结
    • 6、约束
    • 7、多表查询
    • 8、事务
    • 9、索引
    • 10、JDBC

MySQL

关系型数据库是由多张能相互连接的二维表组成的数据库。

如果不由二维表组成,则称这个数据库为非关系型数据库。

1、SQL通用语法、分类

SQL是一门结构化数据查询语言。具体的MySQL相当于“方言”。

SQL通用语法:

-- 这是注释

上边的注释一定要在–后面加上空格。这是语法规定,不然会报错。

/*这也是注释*/

此外,SQL语言要求一定要分号作为语句执行完毕的结尾。

SQL分类:

  • DDL 数据定义语言,用来定义数据库对象:数据库、表、列等
  • DML 数据操作语言,用来对数据库里的数据进行增删改
  • DQL 数据查询语言,用来对数据库里的数据进行查询
  • DCL 数据控制语言,用来定义数据库的访问权限和安全级别,以及创建用户

2、SQL数据类型和字段属性

数据类型

数值:

数据类型 含义 长度
tinyint 十分小的数据 1个字节
smallint 小数据 2个字节
mediumint 中等数据 3个字节
int 标准数据 4个字节
bigint 大数据 8个字节
float 浮点数 4个字节
double 浮点数 8个字节
decimal 字符串形式的浮点数 金融计算的时候float和double无法满足精度要求,需要转化成字符串

字符串:

数据类型 含义 长度
char 固定大小的字符串 0-255
varchar 可变大小的字符串 0-65535 常用来保存变量
tinytext 微型文本串 2^8-1
text 文本串 2^16-1 常用来保存大文本。写文章等等

时间日期:

Java有一个类java.utill.Date

数据类型 格式 含义
year YYYY 年份格式
date YYYY-MM-DD 日期格式
time HH:MM:SS 时间格式
datetime YYYY-MM-DD HH:MM:SS 最常用的,把上边的日期和时间串起来了。
timestamp 时间戳 1970.1.1到现在的毫秒数 非常重要

字段属性

unsigned

  • 无符号的整数
  • 声明该列不能使用负数

zerofill

比如:设置字段的数据类型属性为int(3)或者在长度里填上3。那么:5->005

int后面的括号表示一个宽度(上面例子是3),使用了zerofill后,当数据小于这个宽度时会自动填充0

auto_increment

自动在上一条记录的基础上+1

通常用来设计唯一的主键index

可以自己设计自增的起始值和步长

not null

如果设置字段属性为非空,那么记录里一定要填上一些数据,否则会报错。

default

字段设置默认值之后,如果不填入值,记录的值就会自动填入默认值。

3、DDL(数据定义语言)

  • 查询数据库
SHOW DATABASES;
  • 创建数据库
CREATE DATABASE 数据库名称;
-- 更好地创建数据库
CREATE DATABASE IF NOT EXISTS 数据库名称;
  • 删除数据库
DROP DATABASE 数据库名称;
-- 更好地删除数据库
DROP DATABASE IF EXISTS 数据库名称;
  • 使用数据库
-- 查看当前正在使用的数据库
SELECT DATABASE();
-- 使用数据库
USE 数据库名称;

上边是DDL定义数据库,接下来是DDL定义表

  • 查询表
-- 查询当前数据库下所有表
SHOW TABLES;
-- 查询表的结构(注意只是查询表结构而已。不是表的数据)
DESC 表名称;
  • 创建表(创建表头)
CREATE TABLE 表名(
	字段名1 数据类型,
    字段名2 数据类型,
    字段名3 数据类型,
    ……
    字段名n 数据类型
);

注意最后一行末尾不能加逗号。

  • 修改表(操作比较多。主要还是在操作表头)
添加字段
ALTER TABLE table_name ADD column_name data_type;
删除字段
ALTER TABLE table_name DROP COLUMN column_name;
修改字段名
ALTER TABLE table_name CHANGE old_column_name new_column_name data_type;
修改字段数据类型
ALTER TABLE table_name MODIFY COLUMN column_name new_data_type;
添加主键
ALTER TABLE table_name ADD PRIMARY KEY (column_name);
删除主键
ALTER TABLE table_name DROP PRIMARY KEY;
添加索引
ALTER TABLE table_name ADD INDEX index_name (column_name);
删除索引
ALTER TABLE table_name DROP INDEX index_name;
添加唯一约束
ALTER TABLE table_name ADD UNIQUE (column_name);
删除唯一约束
ALTER TABLE table_name DROP INDEX column_name;
  • 删除表
DROP TABLE 表名;
-- 更好地删除表
DROP TABLE IF EXISTS 表名;

4、DML(数据操作语言)

数据操作其实就是对表中的数据进行增删改。insert、update、delete。

  • 添加数据
-- 给指定的列添加数据(对应列就是对应的数据)
INSERT INTO 表名(字段1,字段2,……) VALUES(1,2,……);
-- 给所有的列添加数据
INSERT INTO 表名 VALUES(所有字段都必须要有对应的值!)

添加还是推荐使用第一种。因为可以直观看出哪个列对应哪个值。

  • 修改数据
update 表名 set 字段名 =where 主键 = 什么

貌似无论是添加还是修改,都必须涉及到表名。

注意,如果update没有加where条件,那么会将一整列的数据全部修改。

  • 删除数据
DELETE FROM 表名 where 主键 = 什么

将一整条数据删除。如果不加where条件,会将表中所有数据删除。

5、DQL(数据查询语言)

1、基础查询

-- 查询字段1和字段2
SELECT 字段1,字段2 FROM 表名;
-- 去重
SELECT DISTINCT 字段1,字段2 FROM 表名;
-- 别名
SELECT 字段1 AS 其他名字 FROM 表名;

可以用*来代替所有行,但是不推荐使用

2、条件查询

就是where。然后加上大于小于等于等等条件。

比较特殊的:

  • between and 范围查询,不仅可以查询数值,也可以查询日期

  • in() 就相当于括号里面的值两两之间都有一个or

  • is 查询null要用is

  • LIKE 模糊查询。通配符有两种:下划线_和百分号%。下划线单个任意字符,百分号多个任意字符

-- 查询名字字段第二个字是“化”的名字
SELECT name FROM stu where name LIKE "_化%";
-- 查询名字中包含“德”的名字
SELECT name FROM stu where name LIKE "%德%";

3、排序查询

SELECT 字段 FROM 表名 ORDER BY 字段名 排序方式,字段名 排序方式,……

排序方式有两种,升序和降序。当有多个字段进行排序时,规则为:若第一个字段相等,则对相等的第一个字段所在的记录进行第二个字段的排序。排序方式中,升序使用ASC,降序使用DESC。

4、分组查询

  • 聚合函数:在select语句里前方使用,使用聚合函数对对应的列进行处理,之后再将列进行显示。主要函数有:count() sum() average() min() max()

    • count()统计的值中不包含空,所以count()一般用在主键。也可以直接用星号。

    所有的null都不参与聚合函数计算

SELECT 字段名 FROM 表名 GROUP BY 字段名 HAVING 条件(对分组之后的每一组执行此条件)

分组查询只能查两种字段:一种是进行分组的字段,另一种是其他字段但是必须经过聚合函数处理!!!

聚合函数紧跟着GROUP BY之后执行。注意是紧跟着。后面还有些优先级更低的比如having。

执行顺序:where>gruop by、聚合函数>having

所以where是在分组之前对数据进行过滤,having是在分组之后对分组结果进行过滤。

5、分页查询

分页查询语法

select 字段列表 from 表名 limit 起始索引, 查询条数

起始索引从0开始。查询条数就是每一页显示多少条数据。但是“每一页”是需要在起始索引那里用数学表达式进行控制的。数学表达式为:起始索引=(第几页-1)*查询条数,“几”是从1开始的。

小结

子句优先级顺序:where>分组(group by)聚合(count()、max()、min()等)过滤(having)>排序(order by)>分页(limit)

6、约束

约束其实就是一些作用在列上的规则,用于限制加入表中的数据,约束的存在保证了数据的有效性,正确性和完整性。

  • 约束的分类:
    • 非空约束(NOT NULL)保证列中数据不能为空
    • 唯一约束(UNIQUE)保证列中数据唯一
    • 检查约束(CHECK)保证列中数据的值满足某一条件 但是MySQL中不支持检查约束
    • 默认约束(DEFAULT)未指定值则默认为某一值
    • 主键约束(PRIMARY KEY)保证列中数据唯一且不为空。该约束在一张表中只能有一个。
    • 外键约束(FOREIGN KEY)让两个表中的数据产生联系。

约束写在创建表中的每一个字段的数据类型后面。

唯一约束和主键约束的区别就是主键约束要求非空。

当约束是唯一约束或者主键约束时,可以在这两个约束后面写上auto_increment,这个单词的意思是自动加1。

根据需求,可以给表中字段适当添加约束。

外键约束

两个表之间可能存在关系 比如一个学生表,一个年级表 每一个学生都有一个年级,故这两个表是可以连接起来的。

外键是关系型数据库中的一种特殊属性,它用于建立表与表之间的引用关系。在一个表中,外键是引用另一个表的主键的列。换句话说,外键是指向另一个表的主键的列,使得两个表之间建立关联关系。这种关联关系可以用于保持数据的一致性和完整性,避免数据冗余。外键的作用包括:

  1. 保证数据的一致性和完整性:通过外键关联关系,可以确保数据的准确性和一致性。例如,当一个表中的外键与另一个表的主键关联时,可以确保两个表中的数据相互匹配。
  2. 实现表之间的关联:外键可以用于建立表与表之间的关联关系,使得可以通过一个表中的外键查询到另一个表中的数据。这种关联关系可以是一对一、一对多、多对一或多对多等形式。
  3. 提高查询效率:通过外键与索引的结合使用,可以提高查询效率。当查询条件中涉及到外键时,数据库可以利用索引快速定位到相关数据行,从而加快查询速度。

需要注意的是,外键的使用需要谨慎,不当的使用可能会对数据库性能产生负面影响。在设计和使用外键时,需要考虑数据库的表结构和查询需求,以及数据的一致性和完整性要求。

两个表有主从关系,创建外键需要在从表中创建。

语法:

在MySQL中创建外键通常涉及两个步骤:首先,创建主表和从表;然后,在从表中添加外键约束,该外键引用主表的主键。下面是一个简单的例子,

--- 创建主表
CREATE TABLE 主表 (  
    id INT PRIMARY KEY,  
    name VARCHAR(50)  
);
--- 创建从表,并添加外键约束
CREATE TABLE 从表 (  
    id INT PRIMARY KEY,  
    主表_id INT,  
    description VARCHAR(100),  
    FOREIGN KEY (主表_id) REFERENCES 主表(id)  
);


在这个例子中,主表 是主表,它有一个名为 id 的主键列。从表 是从表,它有一个名为 主表_id 的列,该列被定义为外键,并引用 主表 的 id 列。这样,在从表中插入或更新数据时,MySQL会检查 主表_id 列的值是否存在于 主表 的 id 列中,以确保数据的一致性和完整性。
创建外键时,需要确保以下几点:
1.主表和从表必须使用相同的存储引擎(例如InnoDB)。
2.主表的被引用列(在本例中为 主表.id)必须具有主键或唯一索引约束。
3.在创建外键约束之前,从表中的外键列(在本例中为 从表.主表_id)不能包含任何与主表中被引用列不匹配的值。

外键名字一般以fk(下划线)从表(下划线)主表来命名.

在创建主表和从表并在从表中指定外键时,必须先将主表先创建,之后才能创建从表, 必须先将主表的数据填入,之后才能填入从表的数据.

一旦外键约束建立,想要删除主表中外键指向的列中的数据, 就必须先将从表中的外键所在列的对应数据删干净才行.

7、多表查询

多表查询分为连接查询和子查询。

连接查询分为内查询和外查询(左外查询和右外查询)。

select 表名.字段名,表名.字段名 from 表1 inner join 表2 on 条件

select 表名.字段名,表名.字段名 from 表1 left join 表2 on 条件
select 表名.字段名,表名.字段名 from 表1 right join 表2 on 条件

内查询和外查询的区别:

  • 内查询取两个表的交集
  • 外查询除了取交集外,还要对应取左边或者右边的表的所有内容。

连接查询的条件用外键来进行连接是最方便的。

子查询其实就是嵌套查询。在where中再加一条查询,这条查询返回的结果经过判断继续给上一级的查询使用。

8、事务

事务的主要作用是确保数据库的一致性和完整性。通过将一系列操作捆绑在一起,事务确保这些操作要么全部成功,要么全部失败。这样可以避免数据的不一致性,并保护数据库免受破坏。

举个例子来说明事务的作用:假设有一个银行ATM取钱的场景。当用户从其账户中取款时,涉及多个数据库操作,如扣款、更新账户余额等。如果这些操作不在一个事务中执行,可能会出现扣款成功但账户余额未更新的情况,导致数据不一致。

通过将取款操作放在一个事务中,可以确保这些操作要么全部成功,要么全部失败。如果其中一个操作失败,事务将回滚到之前的状态,即不会执行后续的操作。这样可以确保数据的完整性和一致性,避免出现数据不一致的情况。

因此,事务在数据库操作中起着重要的作用,它可以确保一系列操作要么全部成功,要么全部失败,从而保护数据库免受破坏并保持数据的一致性。

常见的面试题:事务的四大特征

ACID

  1. 原子性(Atomicity):事务是一个完整的操作。
  2. 一致性(Consistency):当事务完成时,数据必须处于一致状态。
  3. 隔离性(Isolation):对数据进行修改的所有并发事务是彼此隔离的。
  4. 持久性(Durability):事务完成后,它对于系统的影响是永久性的。

在MySQL中,事务是默认自动提交的。换而言之,会把每一句sql语句视为一个事务然后直接提交。

可以设置为手动提交(默认自动提交是1):

set @@aotocommit=0;

MySQL中如何进行事务回滚?

-- 开启一个事务
START TRANSACTION;  
  
-- 执行一些SQL语句  
INSERT INTO table_name (column1, column2) VALUES ('value1', 'value2');  
UPDATE table_name SET column1 = 'new_value' WHERE condition;  
  
-- 如果发生错误,回滚事务  
BEGIN TRY  
    -- 执行一些SQL语句  
    INSERT INTO table_name (column1, column2) VALUES ('value3', 'value4');  
    UPDATE table_name SET column1 = 'new_value2' WHERE condition2;  
COMMIT;  
END TRY  
  
BEGIN CATCH  
    ROLLBACK; -- 回滚事务  
END CATCH;

在上述示例中,如果在执行BEGIN TRY块中的SQL语句时发生错误,将进入BEGIN CATCH块中执行回滚操作。这将撤销所有未提交的更改。

9、索引

MySQL中的索引是一种特殊的数据结构,用于加速对数据库表中数据的检索操作。通过创建索引,MySQL可以在不需要扫描整个表的情况下快速找到与查询条件匹配的记录。

在MySQL中,主要有以下几种类型的索引:

  1. 普通索引:仅用于加速查询,是最基本的索引类型。没有任何限制,适用于大多数情况。
  2. 唯一索引:与普通索引类似,不同的是索引列的值必须唯一,但允许有空值。
  3. 主键索引:一种特殊的唯一索引,不允许有空值。每个表只能有一个主键索引。(在MySQL中,当创建一个主键时,系统会自动为主键字段创建一个唯一索引。因此,主键中默认包含了主键索引。)
  4. 全文索引:用于文本数据模糊查询的特殊索引,基于倒排索引实现。
  5. 组合索引:将几个列作为一条索引进行检索,遵循“最左前缀”原则。创建复合索引时应该将最常用(频率)作限制条件的列放在最左边,依次递减。

此外,MySQL支持多种索引类型,如B-Tree索引、哈希索引、空间索引等。其中,B-Tree索引是MySQL中最常见的索引类型,适用于大部分场景。它支持全值匹配、范围查询和前缀匹配。哈希索引则是一种基于哈希表实现的索引,支持全值匹配,但不支持范围查询和前缀匹配。空间索引则是一种用于地理空间数据查询的特殊索引,基于R树实现。

总的来说,MySQL中的索引是提高查询效率的重要手段。正确地使用和创建索引可以显著提高数据库操作的性能。

但是,索引是需要消耗内存资源的。所以数据比较少的时候可以不使用索引,数据多的时候才使用。而且,数据量小的时候查询速度用索引和不用索引差不多

索引的使用

#显示所有的索引信息
show index from `student`
#给已经创建好的表添加一个索引
alter `student` add 索引类型 索引名 (要添加索引的字段名)

#为users表中username创建一个索引
CREATE INDEX idx_name ON users (username);

索引使用原则

  • 索引不是越多越好
  • 不要对经常变动(频繁使用DML语言,增、删、改)的数据加索引,经常查询但是不经常更改的数据可以添加索引
  • 小数据量的表不需要加索引(加了并没有很大的性能提升)
  • 索引一般加在常用来查询的字段上

索引的底层是b+树。这个是面试经常问到的内容,所以可以去深入了解一下。

10、JDBC

虽然说是重点,但是写起来还是太麻烦了。后边有新的技术栈可以代替。mybatis

JDBC是指Java操作数据库的规范。这个规范由专业人员去设计。所以我只需要掌握JDBC接口的操作即可。

其实就是利用Java和数据库打交道。

首先,要想让程序和数据库之间产生联系,中间需要有一个数据库驱动来进行连接。所以去导一个包mysql-connector-java

就是在项目下边创建一个文件夹命名为lib。把包加进去,右键把lib添加到库里边就可以了。

JDBC程序:

package com.xu.jdbcdemo;

import java.sql.*;

public class JDBCDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //提供用户信息和主机地址,连接数据库。connection就是连接数据库的对象
        String url="jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
        String username="root";
        String password="123456";
        Connection connection=DriverManager.getConnection(url,username,password);
        //执行数据库的对象
        Statement statement=connection.createStatement();
        //用执行数据库的对象来执行sql语句。打印一下
        ResultSet resultSet=statement.executeQuery("SELECT * FROM users");
        while(resultSet.next()){
            System.out.println("id="+resultSet.getObject("id"));
            System.out.println("name="+resultSet.getObject("name"));
            System.out.println("password="+resultSet.getObject("password"));
            System.out.println("email="+resultSet.getObject("email"));
            System.out.println("birth="+resultSet.getObject("birthday"));
        }

        //关闭连接
        resultSet.close();
        statement.close();
        connection.close();
    }
}

步骤总结:

  • 加载驱动
  • 利用驱动管理获得连接数据库的对象
  • 利用连接数据库对象获得执行sql语句的对象
  • 利用执行sql语句的对象去执行sql语句
  • 关闭所有的连接

之后可以把这些步骤全部封装起来,传入sql语句就可以完成上边的全部步骤

connection对象中有一些方法是关于事务处理的。

statement中还有其他的方法,其中有一个是execute(),可以执行任何sql语句,不过效率会慢一些,因为要去判断属于哪一个语句。

resultSet是记录的结果集。这个对象中也有其他的方法。getObject()是在不知道字段类型的情况下使用的,如果知道了字段的类型,可以使用getInt,getDouble等等。然后next方法是移动到下一个记录。如果没有下一个记录就返回false

你可能感兴趣的:(Java,java,mysql,oracle)