HOME/Articles/

数据库基本概念

Article Outline

数据库基本概念

<!--more-->

数据库原理

如果要想把数据持久化,除了写到文件里,就是存到数据库里了。

数据库

  • 数据库提供结构化数据的持久化存储
  • 索引保证数据查询的速度
  • 事务的原子性保证数据不丢失

事务的概念:保证一些事件要么都不发生,要么都会发生,比如去ATM取钱,有1. ATM把钱给你 2.在你的账户上扣钱 2个事件,如果1结束了之后ATM断电了, 那么2就不会发生,显然是有问题的,事务就是为了保证1发生之后2肯定也会发生,要么就是1和2都不发生。

数据库中的类型

  • 整数类型:int/bigint
  • 字符串类型:varchar(100)/TEXT
  • 时间类型: timestamp

数据库中的表设计原则

  • 每个实体一张表(如 用户/商品)
    • 每个实体都有唯一主键ID
    • 按照业务需要去建立索引
  • 每个关系用一张表来联系

SQL语句

基本的SQL使用

sql多表查询

sql中有内置函数,当前时间即为now()

SELECT膜法

  • SELECT *
  • SELECT count(*) count(1)
  • select max/min/avg
  • select limit 分页
  • select order by 排序
  • select is null/not null
  • select where id in ()

group by后面的列,在前面select中也一定要带上,比如select ADDRESS, count(*) from USER group by ADDRESS;如果select后不跟ADDRESS就会报错

另外join也可以连续join添加多张表:

-- join操作可以连续join
select "ORDER".ID                              as ORDER_ID,
       USER.NAME                               as USER_NAME,
       GOODS.NAME                              as GOODS_NAME,
       "ORDER".GOODS_NUM * "ORDER".GOODS_PRICE as TOTAL_PRICE
from "ORDER"
       left join USER on USER.ID = "ORDER".USER_ID
       left join GOODS on "ORDER".GOODS_ID = GOODS.ID

JDBC

Java DataBase Connection,给一个连接字符串,就可以读取到数据库的信息

使用JDBC连接数据库

  • Java DataBase Connection
    • 连接串:即类似于 jdbc:h2:file://xxxx.db
    • 用户名
    • 密码
  • Statement
  • PrepareStatement: 防止SQL注入
  • ResultSet

SQL注入指的是在代码中没有验证传入的参数,导致了攻击者可以使用精心设计的参数拼成的sql可以通过代码的验证,如or 1=1这种,达到可以欺骗服务器执行恶意的sql语句

PrepareStatement 防止sql注入的原理是在执行时就已经预先编译好带占位符的sql语句了,有参数进来直接替换就好了,不会像Statement那样整个语句一起编译了。

来看一个简单使用JDBC的例子:

public class DatabaseReader {
    public static void main(String[] args) {
        File projectDir = new File(System.getProperty("basedir", System.getProperty("user.dir")));
        String jdbcUrl = "jdbc:h2:file:" + new File(projectDir, "Dee").getAbsolutePath();

        try(Connection connection = DriverManager.getConnection(jdbcUrl, "", "");
            PreparedStatement statement =
                    connection.prepareStatement("select * from USER")) {
            statement.setInt(1, 0);
            ResultSet resultSet = statement.executeQuery();
            while (resultSet.next()) {
                System.out.println(
                        resultSet.getInt(1)
                                + " "
                                + resultSet.getString(2)
                                + " "
                                + resultSet.getString(3));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }
}

使用Docker安装数据库

比起本地安装,使用Docker的好处有:

  • 百分百兼容
  • 百分百无残留
  • 百分百统一且方便

值得注意的是,Docker内的数据库文件是不持久话,所以要记得加-v参数,将内部数据库文件映射到外部本机上

关于存储字段的一些补充

  • 对于密码,绝不允许明文存储在数据库里
  • 对于钱的存储,类型应该使用BigDecimal,对应数据库的Decimal