mysql详细学习(二)

7.索引

通过索引(index)帮组我们高效获得数据的结构

:提取句子主干,可以得到索引的本质:索引是数据结构

7.1 索引的分类

一个表中主键索引只有一个,唯一索引可以不只一个

  • 主键索引(primary key)

    • 唯一的标识,不能重复,只有一个列是主键
  • 唯一索引(unique key)

    • 避免重复的列出现,可以重复,多个列可以标识唯一索引
  • 常规索引(key/index)

    • 默认的 index,key 关键字来设置
  • 全文索引:(fulltext)

    • 在特定的数据库引擎才有,
    • 快速定位数据

基础语法

--索引的使用:

--在创建表的时候给字段增加索引

--创建完毕时,增加索引
--显示所有的索引信息
show index from table1
--增加一个全文索引(索引名)列名
1. alert 数据库.table add fulltext index 索引名 (列名)
2. create index 索引名 on table (字段 )
explain 分析sql执行情况
explain select * from table1; ---非全文索引
explain select * from table1 where match (索引名) against ('要锁定的字符'
7.2 测试索引
delilmiter $$  --写函数必须写,标志
create function mock_data()
return int  
begin 
end


索引在大数据时,区别十分明显,特别快

7.3 索引原则
  • 索引不是越多越好
  • 小数据不需要索引
  • 索引一般加在查询的字段上
  • 不要对进程变动的字段加索引

索引的数据结构:

INNodb:Btree

8.权限管理和备份

8.1 用户管理

SQLyog可视化用户管理

SQL命令:

用户表:mysql.user

本质:对用户表增删改查

--创建用户
create user用户名 identitfied by 密码
--修改密码
--1.当前用户
set password = password('mima')
--2.指定用户
set password for 用户 = password('mima')
-- 重命名
rename user 原用户 to 新用户
--用户授权  
--all privileges:全部的权限 ,除了给别人授权;
--*.*:全部的库,表,
grant all privileges on *.* to 用户
--查看指定用户权限
show grants for 用户
--查看主机权限
show grants  for root@localhost
--撤销权限
revoke all privileges on *.*  from 用户

8.2 数据库备份

  • 保证重要的数据不丢失
  • 数据转移

备份方式:

  • 直接拷贝物理文件(data)

  • 在sqlyog可视化工具中手动导出

  • 命令行导出:mysqldump

  • mysqldump -h 主机 -u 用户名 -p 密码 数据库 表名 > 导出的位置              --导出一张表
    mysqldump -h 主机 -u 用户名 -p 密码 数据库 表名1,表2,表3 > 导出的位置    --导出多张表
    mysqldump -h 主机 -u 用户名 -p 密码 数据库  > 导出的位置              --导出数据库
    --导入
    --登陆的情况下,切换到数据库的位置
    --source 备份文件
    source 文件
    
    

9 规范数据库设计

当数据库比较复杂的时候,需要设计

差的数据库设计:

  • 数据冗余,浪费空间

    数据插入和删除麻烦,异常多

    程序性能差

优秀的数据库:

  • 节省内存
  • 保证数据库的完整性
  • 方便开发
设计:
  • 分析需求:分析业务和处理的数据库的需求
  • 概要设计:设计关系图,e_r图
步骤(博客网站):
  • 收集信息,分析需求

    • 用户表(用户登录,个人信息,写博客,创建分类)

    • 分类表(文章分类)

    • 评论表

    • 文章表(文章的信息)

    • 友链表(友链信息)

    • 自定义表

  • 标识实体(把需求落地字段)

  • 标识实体之间的关系:

    • 写博客: user-> blog
    • 创建分类:user->category
    • 关注:user ->user
    • 友链:links
    • 评论表 user-> user -blog

数据库的三大范式

第一范式(1NF):原子性,每一列不可分

第二范式:前提:满足第一范式,每张表只描述一件事

第三范式:前提是第二范式:,确保每个属性都和主键直接相关。

10 JDBC

应用程序 – JDBC----数据库驱动 --数据库

对于开发人员说,jdbc要学习

java.sql

javax.sql

  1. 安装JDBC,导入jar包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WJPeAcER-1592360936599)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200616204152174.png)]

  1. 先复制到自己建立的lib文件夹,然后在ADD as library

  2. 测试代码:

    //1 .加载驱动
    Class.forName("com.mysql.jdbc.Driver")
    //2.用户信息和URL
        jdbc:mysql://主机地址:3306/数据库名?参数1&参数2&参数3.
    String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charaterEncoding"
    String username = "root";
    String password = "123";
    //3 连接成功,connection:数据库对象
    //connection 数据库对象,可以有 事务提交,回滚,,,,
    Connection connection = DriverManager.getConnection(url,username,password);
    //4.执行sql对象,statement :执行sql的对象
    Statement   statement  = connection.createStatement();
    //5. SQL语句
    String sql  = "select * from users"
    //6 根据sql语句导入statement对象,执行,返回查询的结果集
    ResultSet resultset = statement.executeQuery(sql);//返回结果集
    // 7释放连接
    result.closes();
    statement.close();
    connection.close();
    
    //connection 数据库对象,可以在数据库级别执行 事务提交,回滚,,,,
    //statement:sQL对象
    statement.executeQuery()//查询,返回结果集
    statement.execute();//执行任何语句
    statement.executeUpdate();//更新,插入,删除,返回受影响行数
    
    // resultset 结果集
     resultset.getObject();//不知道列的类型执行,知道列的类型就执行具体的方法。
     resultset.getString();
     resultset.getInt();
    ...
    
    
    // resultset
    遍历: resultset.next():移动到下一个数据
         resultset.previous():移动到前一行
         resultset.absolute(row):移动指定行
    

statement对象

jdbc中:statement对象用于向数据库发送SQL语句,想完成数据库的增删改查,只需要这个对象向数据库发送查询语句即可。

// 增删改------executeUpdate
//executeUpdate完成数据插入
Statement st = connection.createStatement();
String sql = "insert into  user(...)values(....)";
int num = st,executeUpdate(sql);
if (num>0){
    system.out.ptint("插入成功")
}
————————————————————————————————————————————
//executeUpdate完成数据删除
Statement st = connection.createStatement();
String sql = "delete from user where id = 1";
int num = st,executeUpdate(sql);
if (num>0){
    system.out.ptint("删除成功")
}

______________________________________________
//executeUpdate数据修改   
Statement st = connection.createStatement();
String sql = "update user set name = "hhh" where name = "dd";
int num = st,executeUpdate(sql);
if (num>0){
    system.out.ptint("修改成功")
}    
    


//查询用executeQuery,返回数据集
Statement st = connection.createStatement();
String sql  = "select * from users"
ResultSet resultset = st.executeQuery(sql);//返回结果集

常规写法:

在java上src文件目录下创建properties配置文件

//第一步配置文件db.propeties
driver = com.mysql.jdbc.Driver
url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charaterEncoding"
username = "root";
password = "123";


//第二写工具类,加载配置文件,加载驱动
public class jdbcUtils{
    private static String driver = null; //提升作用域,下面用的static,这里也用
    private static String url = null;
    private static String usename = null;
    private static String password = null;
    static{
        try{
            IntpuStream in  = jdbcUtils.class.getClassLoader().getResourceAsStream("db.propeties");
            //利用反射读取jdbcUtils类所在目录的配置文件的信息
            Properties properties = new Properties();//创建配置对象流
            properties.load(in);//加载输入流
            driver = properties.getProperty("driver");
            url = properties.getProperty("driver");
            usename = properties.getProperty("driver");
            password = properties.getProperty("driver");
            class.forName("driver");//加载驱动
            
        }catch(Exception e){
            e.printStackTrace ();
            
        }
    }
    
    //获取连接
    public static Connection getConnection() throws SQLException{
        return  DriverManager.getConnection(url,username,password);
    }
    //释放资源
    public void  static release(Connection conne,Statement st,ResultSet rs ){
        if(rs!=null){
            rs.close();
            
        } if(st!=null){
            st.close();
            
        }
    }if(conn!=null)
    {
        conn.close();
    }
}
//第三部,java调用数据库
SQL 注入问题

sql存在漏洞,导致数据泄露 :SQL语句被拼接or,

PreparedStatement:防止SQL注入,效率高

是Statement 的子类

//第一步配置文件db.propeties
driver = com.mysql.jdbc.Driver
url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charaterEncoding"
username = "root";
password = "123";


//第二写工具类,加载配置文件,加载驱动
public class jdbcUtils{
    private static String driver = null; //提升作用域,下面用的static,这里也用
    private static String url = null;
    private static String usename = null;
    private static String password = null;
    static{
        try{
            IntpuStream in  = jdbcUtils.class.getClassLoader().getResourceAsStream("db.propeties");
            //利用反射读取jdbcUtils类所在目录的配置文件的信息
            Properties properties = new Properties();//创建配置对象流
            properties.load(in);//加载输入流
            driver = properties.getProperty("driver");
            url = properties.getProperty("driver");
            usename = properties.getProperty("driver");
            password = properties.getProperty("driver");
            class.forName("driver");//加载驱动
            
        }catch(Exception e){
            e.printStackTrace ();
            
        }
    }
    
    //获取连接
    public static Connection getConnection() throws SQLException{
        return  DriverManager.getConnection(url,username,password);
    }
    //释放资源
    public void  static release(Connection conne,Statement st,ResultSet rs ){
        if(rs!=null){
            rs.close();
            
        } if(st!=null){
            st.close();
            
        }
    }if(conn!=null)
    {
        conn.close();
    }
}
//第三步,java调用数据库插入
public class testInsert{
    public static void main(string [] args){
        Connection conn  = null;//扩大作用域
        PrepareStatement st = null;//创建PrepareStatement对象
        try{
            conn = jdbcUtils.getConnection();
            //区别
            //使用?占位符代替参数
            String sql  = "insert into user (id,name,password,birthday) values (?,?,?,?)"
                st = conn.prepareStatement(sql);//预编译SQL,先写,然后先不执行
            //手动给参数赋值
            st.setInt(1,4);
            st.setString(2,"手动");
             st.setString(3,"123");
            //注意:下面的参数需要的是数据库的date,先要在java程序中
            //获得new Date().getTime()时间戳。
             st.setDate(4,new java.sql.Date(new Date().getTime()));
            //执行
            int i = st.executeUpdate();
            if (i>0){
                System.out.print("执行成功")
            }
            
        }catch(Excetipn e){
            e.printStackTrae();
        }finally{
            jdbcUtils.release(conn,st.rs);
        }
    }
}
//第四步java调用数据库删除
public class testInsert{
    public static void main(string [] args){
        Connection conn  = null;//扩大作用域
        PrepareStatement st = null;//创建PrepareStatement对象
        try{
            conn = jdbcUtils.getConnection();
            //区别
            //使用?占位符代替参数
            String sql  = "delete from user where id =?"
                st = conn.prepareStatement(sql);//预编译SQL,先写,然后先不执行
            //手动给参数赋值
            st.setInt(1,4);
           
            int i = st.executeUpdate();
            if (i>0){
                System.out.print("执行成功")
            }
            
        }catch(Excetipn e){
            e.printStackTrae();
        }finally{
            jdbcUtils.release(conn,st.rs);
        }
    }
}
//第⑤步java调用数据库更新
public class testInsert{
    public static void main(string [] args){
        Connection conn  = null;//扩大作用域
        PrepareStatement st = null;//创建PrepareStatement对象
        try{
            conn = jdbcUtils.getConnection();
            //区别
            //使用?占位符代替参数
            String sql  = "update user set name = ? where id = ?"
                st = conn.prepareStatement(sql);//预编译SQL,先写,然后先不执行
            //手动给参数赋值
            
            st.setString(2,"手动");
             st.setString(3,"123");
           
            
            //执行
           int i = st.executeUpdate();
            if (i>0){
                System.out.print("执行成功")
            }
            
        }catch(Excetipn e){
            e.printStackTrae();
        }finally{
            jdbcUtils.release(conn,st.rs);
        }
    }
}
//java查询
public class testInsert{
    public static void main(string [] args){
        Connection conn  = null;//扩大作用域
        PrepareStatement st = null;//创建PrepareStatement对象
        ResultSet rs = null;
        try{
            conn = jdbcUtils.getConnection();
            //区别
            //使用?占位符代替参数
            String sql  = "select * from user where id = ?"
                st = conn.prepareStatement(sql);//预编译SQL,先写,然后先不执行
            //手动给参数赋值
            st.setInt(1,4);
         
             rs = st.executeQuery();
            while (rs.next()){
                System.out.print(rs.getString("name"));
            }
            
        }catch(Excetipn e){
            e.printStackTrae();
        }finally{
            jdbcUtils.release(conn,st.rs);
        }
    }
}

prepareStatement防止注入的本质:把传递的参数当做字符

存在转义字符直接忽略

数据库连接池

数据库 - -连接 – 释放资源:十分浪费资源

池化技术:

准备预先的资源,过来就连接准备好的。

最小连接数

最大连接数

等待时间

编写连接池,实现一个接口DataSource

开源数据源实现

  • DBcp
  • C3p0
  • Druid:阿里

使用这些数据库连接池,就不要在项目开发中编写连接数据库的代码

DBCP

先导入对应jar包,然后利用对应的方法加载驱动,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值