mysql数据库的基本操作(主键、自增、唯一键、索引、范式、蠕虫复制、主键冲突、5大子句)

录:
1.列属性--主键
2.列属性--自增
3.列属性--唯一键
4.索引
5.关系
6.范式
7.数据高级操作--主键冲突
8.蠕虫复制
9.更新数据时limit限制更新多少条记录
10.删除操作
11.查询的高级操作
12.字段别名
13.查询--where子句
14.group by子句
15.having子句
16.order by子句
17.limit子句

1.列属性--主键    <--返回目录
    * 主键:primary key,一张表只能有一个字段可以使用对应的键,用来唯一的约束该字段里面的数据,
        不能重复;一张表只能有一个主键;
    * SQL增加主键
        - 方法一:
            create table tb_stu(
                sid varchar(32) primary key comment '学号:itcast+0000',
                name varchar(20) not null comment '姓名'
            )charset utf8;
        - 方法二:
            create table tb_stu(
                sid varchar(32) comment '学号:itcast+0000',
                number varchar(50) comment '身份证号',
                name varchar(20) not null comment '姓名',
                primary key(sid,number)  -- 复合主键
            )charset utf8;
        - 方法三:当表已经创建好,追加主键
            alter table tb_stu add primary key(字段列表);
    
    * 主键约束特点:非空,唯一,被引用
        
    * 删除主键:alter table tb_stu drop primary key;
    
    * 【业务主键和逻辑主键】
       在实际开发中,一般不会将业务字段设置为主键,通常使用没有业务含义的逻辑主键。
        create table tb_stu(
            id int primary key auto_increment comment '逻辑主键',
            name varchar(20)
        )charset utf8;
        
2.列属性--自增 auto_increment       <--返回目录
    * auto_increment:当对应的字段不给值,或者给默认值,或者给null值,触发自增。
        create table tb_stu(
            id int primary key auto_increment comment '逻辑主键',
            name varchar(20)
        )charset utf8;
        
        插入一条记录:insert into tb_stu values (null,'zs');
        然后查询创建语句:show create table tb_stu;
        结果:
            CREATE TABLE `tb_stu` (
              `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '逻辑主键',
              `name` varchar(20) DEFAULT NULL,
              PRIMARY KEY (`id`)
            ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
                    
                    
    * 某个字段能使用auto_increment,需要满足两个条件:
        1)该字段是一个索引,即表结构key栏有值(desc 表名查询表结构);
        2)该字段列类型是整型。
        
    * 一张表只能有一个自增字段            
        
    * 删除自增属性
        自增长是字段的一个属性,可以通过modify来进行修改(保证字段没有auto_increment即可)
        alter table tb_stu 字段名 列类型;
    
    * 修改当前字段自增长的值 alter table tb_stu auto_increment=4; 新值必须更大
        
    * 为什么自增起始值为1,步长为1?
        查看自增变量 show variables like 'auto_increment%';
        
3.列属性--唯一键      <--返回目录
    * 唯一键unique key:唯一键默认允许数据为null,而且可以多个数据位null
    * 一张表可以有多个唯一键
    * 创建唯一键:
        - 方法一:
            create table tb_stu(
                number int unique [key] comment '学号:唯一,允许为空'
            )charset utf8;
            
            注意:唯一键的字段key显示为UNI;
            当指定唯一键的字段同时指定not null,并且该表没有主键,desc表结构时该字段的key显示为PRI
            
        - 方法二:
            create table tb_stu(
                number int comment '学号',
                unique [key|index] [别名](number)
            )charset utf8;
        
        - 创建表后新增唯一键
            alter table 表名 add unique key(字段列表);
        
    * 删除唯一键
        alter table 表名 drop index 唯一键的索引名(默认与字段名相同);
        
4.索引    <--返回目录
    * 几乎所有的索引都是建立在字段上的
    * 索引:系统根据某种算法,将已有的数据(未来可能更新的数据),单独建立一个文件,文件能够实现快速的匹配数据,并且
        能够快速找到对应表中的记录。
    
    * 索引的意义:
        1)提升查询数据的效率
        2)约束数据的有效性(唯一性等)  对数据进行约束,比如数据唯一性
        
    * 增加索引的前提条件:索引本身会产生索引文件,有时候可能比数据文件还大,会消耗磁盘空间
    
    * 如果某个字段需要作为查询的条件经常使用,那么可以使用索引
      如果某个字段需要进行数据的有效性约束,比如主键,唯一键,可以使用索引
      
    * mysql中提供的索引:
        主键索引 primary key
        唯一索引 unique key
        全文索引 fulltext index    myISAM引擎才可用,innodb不可用
        普通索引 index
    
5.关系    <--返回目录
    * 一对一
    * 多对一
    * 多对多
    
6.范式    <--返回目录
    * 范式:Normal Format [ˈfɔ:mæt],是离散数学的知识,是为了解决一种数据的存储与优化的问题
      保存数据的存储之后,凡是能够通过关系寻找出来的数据,坚决不再重复存储,终极目标是为了
      减少数据的冗余
    
    * 范式:是一种分层的规范,分为6层,每一层都比上一层更加严格,若要满足下一层范式,前提是满足上一层范式
    * 6层范式:1NF,2NF...6NF;1NF是最底层,要求最低,6NF最高层,要求最严格
    * 一般mysql只要满足前【3层范式】;范式在数据的设计中有指导意义,但不是强制规范
    
    * 1NF:第一范式。在数据表存储数据的时候,如果表中设计的字段存储的数据,在取出来使用之前
        还需要额外的处理(拆分),那么所表的设计不满足第一范式;第一范式要求字段的数据具有原子性,不可再分
    
    * 2NF:第二范式。在数据表设计的过程中,如果有复合主键,且表中有字段并不是由整个主键来确定,而是
        依赖主键中的某个字段(主键的部分);存在字段依赖主键的的部分的问题,称之为【部分依赖】。
        第二范式就是要解决表设计不允许出现部分依赖。
        举例: 学生表:复合主键 姓名 班级 ,性别学号等学生信息依赖姓名,而与班级无关,这就是部分依赖。
    
    * 3NF:第三范式。前提是先满足第二范式。理论上讲,一张表中所有的字段都应该直接依赖主键(逻辑主键,代表的是业务主键),
        如果表设计中存在一个字段,并不直接依赖主键,而是通过某个非主键字段依赖,最终实现依赖主键,把这种不是直接依赖主键
        而是依赖非主键字段的依赖关系称之为【传递依赖】。第三范式就是要解决传递依赖的问题。
    
7.数据高级操作--主键冲突    <--返回目录
    * 数据操作:增删改查
    * 新增数据
        - 基本语法 insert into tb_stu(字段1,字段2...)values(值1,值2...);
        - 主键冲突,进行更新和替换
            insert into 表名(字段列表,包含主键)values(值列表) on duplicate key update 字段=新值;
            
        例子:主键冲突--更新
            create table tb_stu (
                id varchar(32) primary key,
                name varchar(30),
                age int
            )charset utf8;
            insert into tb_stu values('0001','张三',10);
            insert into tb_stu values('0001','张三1',20) on duplicate key update name='张三11',age=30;
            结果:2 row(s) affected,这条记录更新为 '0001' '张三11'  30
    
        例子:主键冲突--替换
            drop table tb_stu;
            create table tb_stu (
                id varchar(32) primary key,
                name varchar(30),
                age int
            )charset utf8;
            insert into tb_stu values('0001','张三',10);
            replace into tb_stu values('0001','张三1',20);  -- 结果:2 row(s) affected
            如果没有主键冲突,replace语句直接插入,结果时候1 row(s) affected
                
8.蠕虫复制    <--返回目录
    * 通过复制表创建新表
        create table tb_stu like [数据库名.]tb_stu1;    -- 同一数据库时,可以省略数据库名
        
    * 蠕虫复制:先查询数据,然后将查出的数据新增一遍
        insert into 表名(字段列表) select 字段列表/* from 表名;
        
    * 蠕虫复制的意义:
        1)从已有的表拷贝数据到新表;
        2)可以让表中的数据膨胀到一定的数量级,测试表的压力以及效率
            insert into tb_stu select * from tb_stu;
            
9.更新数据时limit限制更新多少条记录    <--返回目录
    create table tb_stu (
        id int primary key auto_increment,
        name varchar(30),
        age int
    )charset utf8;
    insert into tb_stu values(null,'张三1',10),(null,'张三2',20),(null,'张三3',30);
    update tb_stu set age = 50 where name like '张%' limit 3;
        
10.删除操作    <--返回目录
    * delete from tb_stu where age = 10 limit 2;  -- 限制删除2条记录
    * truncate 表名; -- 先删除表,在重新创建表。如果有字段自增,会重置。
        注意:执行该语句后,表中记录清空。
        
11.查询的高级操作    <--返回目录
    * 查询完整语法
        select [select选项] 字段列表/* from 数据源 [where条件子句] [group by子句]
            [having子句] [order by子句] [limit子句];
            
    * select选项 all  或 distinct
        - all:不写默认就是all
        - distinct:去除重复的记录
        
12.字段别名    <--返回目录
    select name [as] '姓名', age [as] '年龄' from tb_stu;
    select * from (select * from tb_stu) as s;  -- 子查询的表别名必须要有
    
13.查询--where子句    <--返回目录
    update stu set age = floor(rand()*20+20);
    select * from stu where id = 1 || id = 2;==>select * from stu where id in (1,2);
    
14.group by子句    <--返回目录
    * 分组的意思:为了统计数据;按组统计:按分组字段进行数据统计
    * SQL提供了一系列统计函数
        count(*/字段名):统计分组后的记录数,每一组有多少记录
        max(字段名):统计每组中该字段的最大值
        min(字段名):统计每组中该字段的最小值
        avg(字段名):统计每组中该字段的平均值
        sum(字段名):统计每组中该字段的和
    * count(*/字段名):里面可以放*,也可以放字段名;统计某个字段时,null不统计。
    
    * 分组后会自动排序,根据分组字段排序,默认升序
    
    * 例子:
        -- 创建表
        create table tb_user(
            id int primary key auto_increment,
            username varchar(20),
            `password` varchar(20),
            gender varchar(10),
            state tinyint   -- 0:未激活,1:已激活
        )charset utf8;
        
        -- 插入数据
        insert into tb_user values(null,'张三','zhangsan','男',0),(null,'李四','lisi','女',1),
        (null,'王五','wangwu','女',0),(null,'赵六','zhaoliu','男',1),(null,'小明','xiaoming','女',0);
        
        -- 分组查询,对分组后查询的结果进行排序
        select gender, count(*) c from tb_user group by gender order by c;
        
        -- 多字段分组查询:
        select gender,state,count(*) from tb_user group by gender,state;
            
        -- group_concat(字段名):对分组的结果中的某个字段进行字符串连接
        select gender,state,count(*),group_concat(username) from tb_user group by gender,state;
        结果:
          gender    state    count(*)    group_concat(username)
            女    0    2    王五,小明
            女    1    1    李四
            男    0    1    张三
            男    1    1    赵六
                    
        -- 回溯统计
        select gender,state,count(*),group_concat(username) from tb_user group by gender,state with rollup;
        结果:
            gender    state    count(*)    group_concat(username)
            女    0    2    王五,小明
            女    1    1    李四
            女    (NULL)    3    王五,小明,李四
            男    0    1    张三
            男    1    1    赵六
            男    (NULL)    2    张三,赵六
            (NULL)    (NULL)    5    王五,小明,李四,张三,赵六        
            
15.having子句    <--返回目录
    * having子句:对查询结果,再次进行条件判断
    * 例子1:
        select gender, count(*) as total
        from tb_user
        group by gender
        having total>=2;
    * 例子2:
        select name as '姓名', number as '学号'
        from tb_stu
        having '姓名' like '张%';
        
    * 能用where的尽量用where,where直接对数据源的数据进行判断,效率更高;
        having是对结果集(查询的结果,保存内存中)进行判断
    
16.order by子句    <--返回目录
    * roder by:排序
        select * from tb_stu order by age [asc/desc];
        asc:默认,升序
        desc:降序
    
    * 多字段排序:
        select * from tb_stu order by age asc ,gender desc; -- 如果age相同,女的排前面
    
17.limit子句    <--返回目录
    * limit子句:是一种限制结果的语句,限制数量
    * limit有两种使用方式:
        1)方式1:limit 数据量;   //限制数据量
            select * from tb_stu limit 2;  -- 限制查询记录数据量为2
        2)方式2:limit 起始位置,数据量;  //用来实现数据的分页
            select * from tb_stu limit 0,2;
 
---

原文地址:https://www.cnblogs.com/xy-ouyang/p/13282041.html