MySQL (abajo)

9. Asuntos

9.1, principio ACID

  • Atomicidad: O todos tienen éxito o todos fracasan.
  • Coherencia: la integridad de los datos es coherente antes y después de la transacción.
  • Aislamiento: varios usuarios acceden a la misma base de datos, la base de datos abre una transacción separada para cada usuario, estas transacciones no se afectan entre sí.
  • Persistencia: una vez que la transacción se confirma de forma irreversible, se conserva en la base de datos.

9.2, transacción de ejecución de SQL

MySQL confirma automáticamente las transacciones de forma predeterminada.

--关闭事务自动提交,1则开启。
SET autocommit=0
--开启事务
START TRANSACTION
--提交
COMMIT
--回滚
ROLLBACK
--事务结束
SET autocommit=1

--创建保存点
SAVEPOINT 保存点名
--回滚保存点
ROLLBACK TO SAVEPOINT 保存点名
--删除保存点
RELEASE SAVEPOINT 保存点名
--一般不使用保存点

9.3, transacción JDBC

//这一段可以先看12、JDBC再回来看。
static void login(String username, String password) {
    
    
    Connection conn = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    try {
    
    
        conn = util.getConnection();
        //关闭数据库自动提交,开启事务
        conn.setAutoCommit(false);

        String sql1 = "UPDATE account set money = money-100 where name = 'a'";
        pstm = conn.prepareStatement(sql1);
        pstm.executeQuery();

        String sql2 = "UPDATE account set money = money-100 where name = 'a'";
        pstm = conn.prepareStatement(sql2);
        pstm.executeQuery();

        conn.commit();		//提交事务
    } catch (SQLException e) {
    
    
        try {
    
    
            conn.rollback();		//失败回滚
        } catch (SQLException ex) {
    
    
            ex.printStackTrace();
        }
    }finally {
    
    
        util.release(conn,pstm,rs);
    }
}

10. Índice

10.1 Clasificación del índice

  • Índice de clave principal (CLAVE PRIMARIA)

    Identificador único, la clave principal no se puede repetir.

  • Índice único (CLAVE ÚNICA)

    Para evitar columnas duplicadas, varias columnas pueden ser índices únicos.

    Puede haber varios índices únicos en una tabla, pero solo un índice de clave principal.

  • Índice regular (CLAVE / ÍNDICE)

    El índice predeterminado.

  • Índice de texto completo (FULLTEXT)

    Localice datos rápidamente, solo el motor MyISAM los tiene.

10.2 El uso de índices

--创建表时给字段增加索引。

--显示所有索引信息
SHOW INDEX FROM 表名
--增加一个全文索引
ALTER TABLE 数据库.ADD FULLTEXT INDEX 索引名(列名)
--分析sql语句执行情况
EXPLAIN sql语句

10.3, los principios de diseño del índice

  1. Seleccione un índice único
  2. Cree índices para campos que a menudo deben ordenarse, agruparse y combinarse
  3. Cree índices para los campos que se utilizan a menudo como condiciones de consulta.
  4. Limita el número de índices
  5. Intenta usar índices con menos datos
  6. Es mejor no utilizar índices para tablas con pequeñas cantidades de datos.
  7. Intenta usar prefijos para indexar
  8. Eliminar índices que ya no se usan o que se usan con poca frecuencia

11. Tres paradigmas de bases de datos

La primera forma normal (1NF): requiere que cada columna de la tabla de la base de datos sea un elemento de datos atómicos indivisible.

Segunda forma normal (2NF): sobre la base de 1NF, los atributos que no son de código deben ser completamente dependientes de los códigos candidatos (sobre la base de 1NF, se elimina la dependencia funcional parcial de los atributos no primarios en el código principal)

El segundo paradigma debe garantizar que cada columna de la tabla de la base de datos esté relacionada con la clave principal y no solo con una determinada parte de la clave principal (principalmente para la clave principal combinada).

Tercera forma normal (3NF): sobre la base de 2NF, cualquier atributo no primario no depende de otros atributos no primarios (eliminando la dependencia transitiva sobre la base de 2NF)

El tercer paradigma debe garantizar que cada columna de datos de la tabla de datos esté directamente relacionada con la clave principal, pero no indirectamente.

La diferencia entre el segundo y el tercer paradigma debería ser:

El segundo paradigma requiere que las tablas que están completamente relacionadas con la clave primaria y parcialmente relacionadas con la clave primaria se dividan en dos tablas, y las claves primarias de las dos tablas sean las mismas.

La tercera forma normal requiere que las tablas relacionadas con la clave primaria y las que no están relacionadas con la clave primaria se dividan en dos tablas, las claves primarias de las dos tablas son diferentes

12 、 JDBC

La interfaz del programa de aplicación que se utiliza para regular cómo el programa cliente accede a la base de datos y proporciona métodos como consultar y actualizar datos en la base de datos.

12.1 Uso de JDBC

public static final String URL = "jdbc:mysql://localhost:3306/DatabaseName?useUnicode=true&characterEncoding=utf8&useSSL=true";//支持中文编码,使用utf8编码,安全连接
public static final String USER = "root";
public static final String PASSWORD = "123456";

public static void main(String[] args) throws Exception {
    
    
    //1.加载驱动程序
    Class.forName("com.mysql.jdbc.Driver");
    //2. 获得数据库连接
    Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
    //3.创建SQL对象
    Statement stmt = conn.createStatement();
    //4.执行SQL,返回结果集
    String sql1 = "SELECT * FROM user";
    String sql1 = "INSERT INTO `user` VALUE ('a',123456)";
    //查询使用executeQuery
    ResultSet rs1 = stmt.executeQuery(sql1);
    //增删改使用Update
    ResultSet rs2 = stmt.executeUpdate(sql2);
    //如果有数据,rs.next()返回true
    while(rs1.next()){
    
    
        //不知道返回的是什么类型可以使用getObject
        System.out.println("用户名:"+rs1.getString("username")+" 密码:"+rs1.getInt("pwd"));
    }
    //释放连接
    rs1.close();
    rs2.close();
    stmt.close();
    conn.close();
}

12.2 Herramientas de embalaje

public class util {
    
    
    private static String dirver = null;
    private static String url = null;
    private static String username = null;
    private static String password = null;

    static {
    
    
        try {
    
    
            InputStream in = util.class.getClassLoader().getResourceAsStream("db.properties");
            Properties properties = new Properties();
            properties.load(in);
            dirver = properties.getProperty("dirver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");
            Class.forName(dirver);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    //获取连接
    public static Connection getConnection() throws SQLException {
    
    
        return DriverManager.getConnection(url, username, password);
    }

    //释放连接
    public static void release(Connection conn, Statement stmt, ResultSet rs) {
    
    
        try {
    
    
            if (rs != null)
                rs.close();
            if (stmt != null)
                stmt.close();
            if (conn != null)
                conn.close();
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }
}

Uso de herramientas

public static void main(String[] args) {
    
    
    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;
    try {
    
    
        conn = util.getConnection();
        stmt = conn.createStatement();
        String sql = "INSERT INTO `user` VALUE ('a',123456)";
        int i = stmt.executeUpdate(sql);
        if (i > 0) {
    
    
            System.out.println("插入成功!");
        }
    } catch (Exception e) {
    
    
        e.printStackTrace();
    } finally {
    
    
        util.release(conn, stmt, rs);
    }
}

12.3, inyección SQL

Existen lagunas en SQL y la validez de los datos de entrada del usuario no se juzga o el filtrado no es estricto. Se agregan declaraciones SQL adicionales al final de las declaraciones de consulta predefinidas en la aplicación para lograr operaciones ilegales y engañar al servidor de la base de datos. para realizar consultas arbitrarias no autorizadas para obtener la información de datos correspondiente

//这样将会输出所有的用户信息。

public static void login(String username, String password) {
    
    
    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;
    try {
    
    
        conn = util.getConnection();
        stmt = conn.createStatement();
        String sql = "SELECT * FROM users WHERE `username` = '" + username + "'AND `password` = '" + password + "'";
        rs = stmt.executeQuery(sql);
        while (rs.next()) {
    
    
            System.out.println("用户名:" + rs.getString("username") + " 密码:" + rs.getInt("pwd"));
        }
    } catch (Exception e) {
    
    
        e.printStackTrace();
    } finally {
    
    
        util.release(conn, stmt, rs);
    }
}

public static void main(String[] args) {
    
    
    login(" ' or '1=1", " ' or '1=1");
}

12.4, objeto PreparedStatement

Similar a Statement, pero es más eficaz para evitar la inyección de SQL.

public class DbDelete {
    
    
    public void delGoddess(){
    
    
        //获取连接
        Connection conn = DbUtil.getConnection();
        //sql, 每行加空格
        String sql = "delete from imooc_goddess where id=?";
        //预编译SQL,减少sql执行
        PreparedStatement ptmt = conn.prepareStatement(sql);

        //传参
        ptmt.setInt(1, id);

        //执行
        ptmt.execute();
    }
}
//增加和修改类似

PreparedStatement evita problemas de inyección de SQL, trata los parámetros pasados ​​como caracteres e ignora los caracteres de escape.

//这样会不会有任何输出
static void login(String username, String password) {
    
    
    Connection conn = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    try {
    
    
        conn = util.getConnection();
        String sql = "SELECT * FROM users WHERE `username`=? AND `password` =?";
        pstm = conn.prepareStatement(sql);
        pstm.setString(1, username);
        pstm.setString(2, password);
        rs = pstm.executeQuery();
        while (rs.next()) {
    
    
            System.out.println("用户名:" + rs.getString("username") + " 密码:" + rs.getInt("pwd"));
        }
    } catch (SQLException e) {
    
    
        e.printStackTrace();
    } finally {
    
    
        util.release(conn, stmt, rs);
    }
}

public static void main(String[] args) {
    
    
    login(" ' or '1=1", " ' or '1=1");
}

12.5, grupo de conexiones de base de datos

El usuario necesita obtener un enlace de la base de datos cada vez que se realiza una solicitud, y la creación de la conexión de la base de datos generalmente consume recursos relativamente grandes y lleva mucho tiempo crearla. Suponiendo que el sitio web tiene 100.000 visitas al día, el servidor de la base de datos necesita crear 100.000 conexiones, lo que desperdicia en gran medida los recursos de la base de datos y puede causar fácilmente un desbordamiento de la memoria y la expansión de la computadora del servidor de la base de datos.

El grupo de conexiones de base de datos es responsable de asignar, administrar y liberar conexiones de base de datos y permite que las aplicaciones reutilicen una conexión de base de datos existente en lugar de restablecer una.

La configuración del número mínimo de conexiones y el número máximo de conexiones del grupo de conexiones de la base de datos debe tener en cuenta los siguientes factores:

  1. El número mínimo de conexiones: es la conexión de la base de datos que el grupo de conexiones mantiene todo el tiempo, por lo que si la aplicación no usa gran parte de la conexión de la base de datos, se desperdiciarán muchos recursos de conexión de la base de datos.
  2. Número máximo de conexiones: el número máximo de conexiones que puede solicitar el grupo de conexiones. Si el número de solicitudes de conexión a la base de datos supera el número de veces, las solicitudes de conexión a la base de datos posteriores se agregarán a la cola de espera, lo que afectará las operaciones futuras de la base de datos.
  3. Si el número mínimo de conexiones es muy diferente del número máximo de conexiones, entonces la primera solicitud de conexión será rentable y las solicitudes de conexión posteriores que superen el número mínimo de conexiones equivalen a establecer una nueva conexión a la base de datos. Sin embargo, estas conexiones de base de datos que superen el número mínimo de conexiones no se liberarán inmediatamente después de su uso, sino que se colocarán en el grupo de conexiones para esperar la reutilización o el tiempo de espera del espacio.

Los grupos de conexiones de bases de datos más utilizados incluyen JDCP y C3P0.

Supongo que te gusta

Origin blog.csdn.net/xxmuq/article/details/113866707
Recomendado
Clasificación