mysql基础

数据库是什么:
    一个存储和管理数据的仓库

DB,DBMS.RDBMS:
    DB:database
    DBMS:Database management system
    RDBMS:关系型数据库管理系统

目前来说常见的数据库;
    1.关系型数据库:
        关系型数据库使用二维表格来存储数据:
        MySQL:开源免费的数据库,互联网公司用的最多
        Oracle:速度快,功能完善,安全性高
        ProgressSQL
        ...
    2.NoSQL(非关系型数据库):
        Redis:用键值对来保存数据.用处:消息队列,session共享,缓存
        MongoDB:用json来保存非结构化数据
        Neo4j:图数据库,用节点和关系边来保存数据
        HBase:以文件的形式来保存数据

SQL语句:
    用来操作和管理数据库的
    DCL
    DML
    DDL
    DQL

关系型数据库结构:
    一个RDBMS可以管理多个数据库 一个数据库里面可以有多张表 一张表由行和列组成 行:记录->java中实际存在的对象 列:字段->java类

    java类:
    public class User{
        int id;
        String username;
        String password;
        String role;

        public User(xxx){

        }
    }
    User user = new User(1,"zhangsan","123456","admin")
    orm:对象关系映射 -> user.id = 2 java里的语句 直接修改数据表中的值

    表示:
    id  username    password    role
    --------------------------------
    1   zhangsan    123456      admin
    2   lisi        password    user

    在windows下面 ,mysql默认不区分大小写,但是在linux下面会区别
    一般来说:在sql里面全部都用小写字母,单词和单词之间用_进行链接

    insert语句,update语句,delete语句和select语句


    MySQL中常用的一些数据类型:
        binary:二进制数据,即 保存一些二进制文件 如果想要在mysql里面保存文件的话,必须选择binary
            ps:一般来说不会直接在数据库里面保存文件,会保存一个文件的文件名,然后通过文件名组织成绝对路径或者相对路径的形式来保存文件
        text/longtext:保存一些长文本内容,一篇文章
        char/varchar:定长/变长字符串
        date/time/datetime/timestamp:yyyy-MM-dd/HH:mm:ss/yyyy-MM-dd HH:mm:ss/yyyy-MM-dd HH:mm:ss(格式虽然一样,但是保存在硬盘里的数据不一样)
            ps:1.jdbc里面 有一个包叫做 java.sql.Date -> 这个类对应的就是sql里面的datetime数据类型,但是转换有点麻烦
               2.datetime这个数据类型在硬盘里面保存的实际上是两个int类型的数据:1988-09-11 11:54:32 -> 19880911 115432 因为是int数据所以可以比较大小
        tinyint:因为sql中没有布尔类型,所以如果想要保存布尔值的话,一般选择tinyint,1为true 0为false
    
    如果真正想要更改字段的顺序的话,需要点击navicat的设计表,然后上移下移(改变DDL里面定义字段的顺序)


    
    insert语句:
        用来向一张表里面插入一条记录:
            1.insert into 表名 values (字段1的值,字段2的值...) -> 这个方法是通过字段的顺序来向每一个字段插入一个值,如果字段的数量不匹配会报错

            2.insert into 表名 (字段1,字段2,字段3...) values (值1,值2,值3...),(值1,值2,值3...)

    update语句:
        修改一些字段的值
            update 表名 set 字段名 = 字段值,...

    delete语句:
        删除
            delete from 表名 where xxx

    select语句:
        查找
            select 字段1,字段2,字段3... from 表名

        select语句的执行结果:
            一个表

        举例:
            id  role    username    password
            ---------------------------------
            1    admin    zhangsan    123456
            2    lisi    1    user
            3    lisi    1    user

            public class User{
                int id;
                String role;
                String username;
                String password;
            }

            User user1 = new User(1    admin    zhangsan    123456)
            User user2 = new User( 2    lisi    1    user)
            User user3 = new User(3    lisi    1    user)

            List<User> users = new ArrayList<>();
            users.add(user1)
            users.add(user2)
            users.add(user3)

            所以users这个List就可以代表这张表了
            HashMap<String,String> hashmap1 = new HashMap<>()
            hashmap1.put()
            xxx
            这张表也可以用List(hashmap)来表示
        



    ps:
        1.insert语句,update语句,delete语句执行后都会返回一个affected rows 表示影响的行数
        2.如果想要自动递增(即让数据库存储引擎自动生成一个值),直接插入一个null
        3.`` 用来标记表名和字段名,虽然说不写也行,但是写上会让sql语句的可读性增加
        4.一般情况下,delete和update语句都会搭配条件语句 where来使用 如果没有指定某一行或者某一列的话,会修改/删除所有记录
        5.primay key 主键有唯一性
        6.* 叫做通配符 用来表示所有的字段

where:
    条件查询:根据一些条件来筛选结果集中的某些行或者某些列
    where子句放在from子句的后面(对from关键字执行的结果进行筛选)
    select * from emp where emp.sal > 2000
        1.执行from emp 找出emp表中的所有数据
        2.执行where语句,对from生成的临时表做筛选
        3.执行select语句,从最后的临时表里面选取哪些字段进行返回

        between...and...运算符:
            可以和 >= and <=相互替换
            第一个数从做往右取 第二个数从右往左取

        AND/OR:
            select * from emp WHERE emp.JOB = 'manager' OR emp.JOB = 'salesman'
            这条sql语句执行流程:
                1.from emp 找出emp表中的所有数据
                2.where语句 拿出这种临时表里面的每一条记录 如果这条记录 emp.JOB = 'manager' OR emp.JOB = 'salesman' 两个条件为true的话,
                就放到临时表中
                3.select语句,从where语句的临时表里面把字段拿出来

            select * from emp WHERE emp.JOB = 'manager' or 1=1
                会造成sql注入,把数据库里面的每一条数据都查出来:
                    1 = 1永远为true 所以or的执行结果就肯定为true

            想想一个场景 ,输入一个用户名和密码:
                1.根据用户名把密码查出来
                2.密码做比较
                3.登陆成功

            现在用户输入的是:
                zhangsan
                select * from user where user.username = "zhangsan"
                zhangsan""" or 1=1"
                select * from user where user.username = "zhangsan""" or 1=1""
ps:
    1.尽量避免使用*通配符,如果使用*通配符,会导致sql不走索引而全表查找,导致性能太低
    2.MySQL中的null是一个特殊的数据类型,表示一个空值,null和所有类型的数据运算的结果都是null,null不能用=做比较,如果要判断一个字段是否为null的话,只能用is null
    3.尽量避免写太长和太多运算的sql语句,把需要执行的逻辑放到后端来做,提升查找的速度!
    4.SQL里面有一个关键字叫as可以给表和字段起别名,虽然可以不写,但是建议写上,提升sql语句的可读性
    5. 5.5版本的隐式转换规则:如果把一个字符串转化成int类型的数据,从第一个字符开始验证,直接遇到一个非数字字符为止
        "100a100" -> 100
    分组查询:
    对数据进行分组,分组的依据是什么?根据某个字段进行分组,字段值相同的为一组

    id username departmentNo
    1   张三    1
    2   李四    2
    3   王五    1

    分组查询:
        使用group by子句可以指定根据某个字段来进行分组

        ps:
            1.如果我只对某个字段进行分组,但是没有使用分组函数来进行进一步的处理的话
            比如说:
                select * from emp GROUP BY emp.JOB
            返回的结果:
                只会显示每一组的第一条记录
            2.group by语句绝大部分情况下都需要搭配分组函数来使用,不然的话就没什么意义了
            3.因为分组这个过程比较抽象,所以使用group by语句的时候一定要找到一个合适的场景
            4.在sql的规范中,having子句必须要搭配group by一起使用

    分组查询涉及到两个子句:
        1.group by
        2.having -> 对分组后的数据进行限制,能不能在having里面使用分组函数呢?
            having和where有什么不同点:
                1.相同点:都是对结果集进行一些条件限制
                2.不同点:
                    一个是对from后面的结果集进行限制,一个是对分组后的数据集进行限制

        GROUP_CONCAT(expr): 这个函数可以把每个组里面的某些字段的值给拼接到一起

        分组查询可以按照多个字段来进行分组,怎么玩的?
            部门:
                开发部:java开发工程师
                运维部:java开发工程师
                测试部:
            如果按照多个字段进行分组:每一个字段都相同的数据为一组
                
        



   
posted @ 2022-05-14 08:55  java小寇  阅读(51)  评论(0)    收藏  举报