# 为什么用数据库?
  1. 数据可以存在哪里?
    浏览器上,内存(变量-数组,临时存储),硬盘,网盘,手抄,光盘
  2. 数据永久化?
    硬盘,网盘,光盘---以文件的形式
    word , excel , ppt , xml  //数据量小的时候
    数据库实现数据永久化(还是一种文件)  //数据量大的时候
  数据库的作用
  1. 可以存储大量的数据,可以对其进行访问,检索(管理数据)
  2. 保证数据的完整性(稳定性 + 正确性)
  3. 安全与共享
  4. 可以对数据进行重新分析,产生新的数据(数据分析,数据挖掘)
# 什么是数据库
    存储的数据的"仓库"
# 数据库发展历程
  1. 层次模型
  2. 网状模型
  3. 关系模型
    以表格为单位,进行数据存储
   
    表:一类实体对象的集合
        行:实体,记录
        列:属性,字段
    关系:
        1   ——   N      一对多
        N   ——   1      多对一
        N   ——   N      多对多
  
  4. 对象模型(mongoDB)
# 关系型数据库
    sql server, oracle, mysql, db2, access等
    数据库管理系统(DataBase Manage System: DBMS)
# SQL(Structured Query Language): 结构化查询语言
    SQL 语句:
    四部分:
        DDL(Data Define Language): 数据定义语言
        DQL(Data Query Language): 数据查询语言
        DML(Data Manage Language): 数据管理语言(添、删、改数据)
        DCL(Data Control Language): 数据控制语言(设置权限、用户管理)
        职位:DBA(database Administor)
    DDL 数据定义语言
    1. 创建数据库
    语法:
        create database 数据库名;
        命名规则︰
            1.第一个字符必须是下列字符之一:
                a-z和A-Z,
                下划线(_)、at符号(@)或者数字符号(#)。
            2.后续字符可以是
                at符号(@)、美元符号($)、数字符号或下划线,字母。
            3.标识符不能是所用RDBMS的保留字。
                不允许嵌入空格或其它特殊字符
        使用数据库
           use 数据库名
        删除数据库
           drop database 数据库名
    2.创建表
        create table表名(列名 列的数据类型(列的约束), ... );
       
        数据类型有哪些
            数字            大小
                int         4字节
                float       单浮点,4字节
                double      双精度,8字节
                decimal     总位数,小数点后的位数,17字节
                    注:总位数必须大于小数点后的位数
  
            字符串
                char : 固定字符,固定字符长度
               
                varchar : 可变字符,随内容长度变化
                text : 长文本(不用指定长度)
                nchar
                nvarchar
                ntext
                n: 只Unicode编码,可显示中文
           
            日期
                date
                datetime
                timestamp 时间戳 timestamp
                ...
  
       列的规则:实现数据的完整性
        完整性 = 可靠性 + 正确性
        1. 实体完整性   主键约束,唯一约束,标识列
            -- 保证行的有效性
       
            主键约束:primary key,表中主键列不能重复且不为空
            唯一约束:unique key,设置唯一约束不能重复,可为空
            列标识:自增列没有重复值
        2. 域完整性
            -- 保证列的有效性
                非空约束Not Null
                默认约束:Default
                check约束
        3. 引用完整性
             -- 引用数据的完整性
           
        4. 外键
            外键:外键是指从表的某列与主表的某列存在依附关系,此关系是设计这两张表时根据业务而建立的,但是此关系并没有强制性依赖。
            外键约束:是指在外键关联主键上强制加上一个约束,如果违反该约束,则不允许该条数据的修改
        语法:
            constraint foreign key(列名) references 主表(主表列名)
        5. 自定义完整性
            存储过程
       
        删除表
        drop table 表名
            --有外键关系时不能删除
        复制表
        create table new select * from old  // 复制旧表的结构与数据,不复制约束
        create table new select * from old where 1=0 // 复制旧表的结构,不复制数据与约束
  
        修改表
        -添加列
            alert table 表名 add phone char(11) unique
        -修改列
            alert table 表名 change phone mobile char(11) unique
        -删除列
            alert table 表名 drop column mobile
  
    DML: 数据操作语言(添加、修改、删除)
    添加
    语法:
        insert into 表名(表中各列名) values (对应列的值)
        // 字符给值要加单引号,自增列用null,默认值用default
        // 表名后加括号,可选其中部分列赋值,不加括号需要给每个字段值
        INSERT INTO student (stuNo, stuName, state,classId) VALUES ('007', 'zhangsan' , 1,1);
    多行添加
        insert into 表名(表中各列名) values (对应列的值),(对应列的值),(对应列的值)...;
        INSERT INTO student (stuNo, stuName, state,classId) VALUES ('007', 'zhangsan' , 1,1),
        ('008', 'lisi' , 1,1),
        ('009', 'wangwu' , 1,1),
        ('010', 'zhaoliu' , 1,1)
        ;
  
    更新:
        update 表名 set 列名=值 where 条件(如:列名1=值 and 列名2=值);
   
    删除:
        delete from 表名 where 条件
        truncate table 表名     //用于删除所有表数据
        区别:
        delete 可以有条件,删除数据后能恢复(有日志文件),效率低,自增列不会重置;
        truncate 只能删除整个数据,删除后数据不能恢复,效率高,可以重置自增列;
    DQL: 数据查询语言
    # MYSQL 查询?
    从表中查找需要的数据
    # 查询原理
        表中全部遍历,根据条件查询相应的数据,投影需要的数据。
   
    语法:
        查询全部
        select * from 表名
        查询部分字段
        select 字段1,字段2,... from 表名
        查询并重命名列
        SELECT stuNo AS No,stuName AS NAME,... FROM 表名
        查询表的部分操作方法
        (1)concat(str1,str2...)  //拼接字符串
        例:
            SELECT CONCAT(stuName,' hahah') FROM student
        (2)distinct //去重
            SELECT DISTINCT classld, age FROM student
            // 判断满足classId 和 age 都存在重复时进行去重操作
        (3)limit  //返回指定的行数
        limit 开始行数,返回的数量--开始的行数从0开始
        例:
            SELECT * FROM student LIMIT 0,2
        (4)排序 order by
        order by 列名 asc(升序,默认)/desc(降序)
        例:
            SELECT * FROM student ORDER BY age DESC
            SELECT * FROM student ORDER BY age DESC id ASC
            // 先按年龄降序排列,有相同值的再按id升序排列
        (5)模糊查询 like
        通配符:
            %: 0个或多个    任意字符
            _: 1个          任意字符
        (6)范围 between 开始值 and 结束值
        注:开始值小于或者等于结束值;但是如果大于了也不报错,只是没有数据
            SELECT*FROM student WHERE age >=20 AND age <=17
            SELECT* FROM student WHERE age BETWEEN 20 AND 17
        (7)聚合函数,特点:返回单行单列,不统计为Null的值
        求和 sum(列名)
        求平均 avg()
        求最大 max()
        求最小 min()
        数量 count(列名)
        (8)group by 分组统一
        例:
            select classID from student group by classID
            select count(1),classID from student group by classID
            // 与count()合用可获取各分组的数量
        执行顺序
        from - where - select - group by - having - order by - limit
        (9)join 连接
        --内连接,显示两表共有的部分记录
        select 查询的内容 from 表1 join 表2 on 连接条件
        例:
            SELECT student.*,class.className FROM student JOIN class ON student.classId = class.classId
       
        --外连接
            -left join
            -right join
        例:
            select * from A left join B on A.aid = B.bid;
            // 显示A表全部记录的情况下,将符合条件的B表中的记录连接到右边,如未在B表中找到记录则字段显示null;
            select * from A right join B on A.aid = B.bid;
            // 显示B表全部记录的情况下,将符合条件的A表中的记录连接到右边,如未在A表中找到记录则字段显示null;
       
    条件查询时使用的符号,关系运算符: >,< ,>=,<=,= ,!= ,>,要求,只为单个值
    条件范围:
        查询id =1 和id = 4 的学生信息-- in/not // in可以是多个值
       
        // in中的值,是或者关系
        SELECT * FROM student WHERE id IN (1,4)
       
        SELECT * FROM student WHERE id NOT IN(1,4)
    子查询
        ·select中的子查询
        例:
        select *,(select className from class where classId = student.classId) as className from student
        // 主查询一行记录,子查询需要遍历一遍,性能低,慎用
        ·from中的子查询(返回多行多列)
        例:
            SELECT * FROM
            (SELECT * FROM student WHERE sex ='女’) AS temp
            WHERE age = 17
        ·where中的子查询
        select * from student where classId = (select classId from class where className = "web");
# 三大范式
    1NF:保证原子性(行不重复,列不再分)
    2NF:满足1NF,且所有非主键列,完全依赖主键列
    3NF:满足2NF,且每列与主键有直接关系,没有间接关系