zoukankan      html  css  js  c++  java
  • mysql数据库的基本操作

    安装(基于centos)

    yum -y install mariadb mariadb-server   # centos7版本
    
    yum -y install mysql mysql-server #centos7以下版本

    启动

    service mysqld start  #开启 centos7以下版本
    chkconfig mysqld on   #设置开机自启
    OR
    systemctl start mariadb  #centos7
    systemctl enable mariadb

    设置密码

    1  mysqladmin -u root -p123 password '1234' #修改root用户密码
    
    2. 进入mysql库修改user表 
    mysql>use mysql; 
    mysql>update user set password=password('你的密码') where user='root'; 
    mysql>flush privileges; 

    登录

    mysql               #本地登录,默认用户root,空密码,用户为root@127.0.0.1
    -- mysql -uroot -p1234 #本地登录,指定用户名和密码,用户为root@127.0.0.1
    -- mysql -uroot P端口号 -h 192.168.31.95 -p密码 #远程登录,用户为root@192.168.31.95

    查看

    ps aux |grep mysqld #查看进程
    netstat -an |grep 3306 #查看端口

    mysql的常用命令

    -- 
    -- 启动mysql服务与停止mysql服务命令:
    -- 
    -- net start mysql
    -- net stop  mysql
    -- 
    -- 
    -- 登陆与退出命令:
    -- 
    --    mysql -h 服务器IP -P 端口号 -u  用户名 -p 密码 --prompt 命令提示符  --delimiter 指定分隔符
    --    mysql -h 127.0.0.1 -P 3306 -uroot -p123
    --    quit------exit----q;
    -- 
    -- 
    -- s;   ------my.ini文件:[mysql] default-character-set=gbk [mysqld] character-set-server=gbk
    -- 
    -- prompt 命令提示符(D:当前日期 d:当前数据库  u:当前用户)
    -- 
    -- T(开始日志) 	(结束日志)
    -- 
    -- show warnings;
    -- 
    -- help() ? h
    -- 
    -- G;
    -- 
    -- select now();
    -- select version();
    -- select user;
    -- 
    -- c 取消命令
    -- 
    -- delimiter 指定分隔符

    忘记密码

    方法一:启动mysql时,跳过授权表
    [root@controller ~]# service mysqld stop
    [root@controller ~]# mysqld_safe --skip-grant-table &
    [root@controller ~]# mysql
    mysql> select user,host,password from mysql.user;
    +----------+-----------------------+-------------------------------------------+
    | user     | host                  | password                                  |
    +----------+-----------------------+-------------------------------------------+
    | root     | localhost             | *A4B6157319038724E3560894F7F932C8886EBFCF |
    | root     | localhost.localdomain |                                           |
    | root     | 127.0.0.1             |                                           |
    | root     | ::1                   |                                           |
    |          | localhost             |                                           |
    |          | localhost.localdomain |                                           |
    | root     | %                     | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
    +----------+-----------------------+-------------------------------------------+
    mysql> update mysql.user set password=password("123") where user="root" and host="localhost";
    mysql> flush privileges;
    mysql> exit
    [root@controller ~]# service mysqld restart
    [root@controller ~]# mysql -uroot -p123

    sql及其规范

    <1> 在数据库系统中,SQL语句不区分大小写(建议用大写) 。但字符串常量区分大小写。建议命令大写,表名库名小写;
    
    <2> SQL语句可单行或多行书写,以“;”结尾。关键词不能跨多行或简写。
    
    <3> 用空格和缩进来提高语句的可读性。子句通常位于独立行,便于编辑,提高可读性。
    
    1
    2
    SELECT * FROM tb_table
                WHERE NAME="YUAN";
    <4> 注释:单行注释:--
    
                   多行注释:/*......*/
    
    <5>sql语句可以折行操作

    库备份

    dbname参数表示数据库的名称;
    table表示备份那个数据库的表名
    backupname备份数据库名字
     
    第一种:备份一个数据库的那些表
    mysqldump -u username -p dbname table1 table2 ...-> BackupName.sql
     
    第二种:备份多个数据库
     
    mysqldump -u username -p --databases dbname2 dbname2 > Backup.sql
    加上了--databases选项,然后后面跟多个数据库
     
     
    第三种:备份所有库
     
    mysqldump -u username -p -all-databases > BackupName.sql
    第四种:就是将MySQL中的数据库文件直接复制出来。这是最简单,速度最快的方法。
     
    不过在此之前,要先将服务器停止,这样才可以保证在复制期间数据库的数据不会发生变化。
    如果在复制数据库的过程中还有数据写入,就会造成数据不一致。这种情况在开发环境可以,
    但是在生产环境中很难允许备份服务器。
     
      注意:这种方法不适用于InnoDB存储引擎的表,而对于MyISAM存储引擎的表很方便。
    同时,还原时MySQL的版本最好相同。
       
    第五种:第三方client软件备份

    还原库

    mysql -u root -p  dbname< BackupName.sql
    dbname  是可选项 ,是用于某些表还原到那些库才需要用到dbname
    直接还原库不用加上dbname,也就是数据库名

    SQL语句

    库操作

    库名的命令规则:首字符是字母,其余部分可以是字母、数字、下划线、@、$

    不能是关键字,如create database create

    最长128位
    不能是纯数字

     1 查询有所有库
     2 show databases;
     3  
     4 mysql> show databases;
     5 +--------------------+
     6 | Database           |
     7 +--------------------+
     8 | information_schema |      #虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数(用户表信息,列信息,权限信息,字符信息),存放于内存中
     9 | mysql              |               #授权库,存放mysql所有的授权信息
    10 | performance_schema |   #存放mysql服务的性能参数
    11 | test               |                  #测试库
    12 +--------------------+
    13 5 rows in set (0.00 sec)
    14  
    15 创建库
    16 create database   dbname
    17 
    18 查看某一个数据库
    19 show create database  dbname
    20  
    21 mysql> create database xixi;     #创建
    22 Query OK, 1 row affected (0.00 sec)
    23  
    24 mysql> show create database xixi;        #查看
    25 +----------+------------------------------------------------------------------+
    26 | Database | Create Database                                                  |
    27 +----------+------------------------------------------------------------------+
    28 | xixi     | CREATE DATABASE `xixi` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ |
    29 +----------+------------------------------------------------------------------+
    30 1 row in set (0.00 sec)
    31 
    32 
    33 
    34 使用数据库 
    35 use  库名;
    36 看看当前use了哪个库
    37 select database()
    38 
    39 mysql> use xixi;
    40 Database changed
    41 mysql> select database();
    42 +------------+
    43 | database() |
    44 +------------+
    45 | xixi       |
    46 +------------+
    47 1 row in set (0.00 sec)
    48 
    49 
    50 
    51 修改:alter
    52  
    53 删除库
    54 drop database  数据库名;
    55  
    56 mysql> drop database xixi;           #删除库
    57 Query OK, 0 rows affected (0.01 sec)
    58  
    59 mysql> show databases;
    60 +--------------------+
    61 | Database           |
    62 +--------------------+
    63 | information_schema |
    64 | mysql              |
    65 | performance_schema |
    66 | test               |
    67 +--------------------+
    68 4 rows in set (0.00 sec)

    mysql数据库类型

    数值类型

    下面的表显示了需要的每个整数类型的存储和范围。

    日期 /时间类型

     

    字符串类型

    字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型。

    CHAR和VARCHAR类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。

    BINARY和VARBINARY类类似于CHAR和

    ,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。

    BLOB是一个二进制大对象,可以容纳可变数量的数据。有4种BLOB类型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它们只是可容纳值的最大长度不同。

    有4种TEXT类型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。这些对应4种BLOB类型,有相同的最大长度和存储需求。

    上面这些的数据类型都存放在数据表里面的,现在介绍数据表操作

    数据表操作

    1 我们需要进入某一个库里才能创建表
    2 一张表必须属于一个库
    3 表分成:字段+记录

    创建表

    语法

    create table 表名 (
                                字段名1  类型 (宽度) 约束条件,
                                字段名2  类型(宽度)  约束条件,
                                字段名3  类型(宽度)  约束条件,
                                .......
                                );
                                 
    注   :
    同一张表中,字段名不能相同
    字段名和类型必须有宽度和约束条件为可选项
     
    ```
    ```
    mysql> create table host (
        -> id int(10),
        -> hostname char(20),
        -> port int(5)
        -> );
    Query OK, 0 rows affected (0.11 sec)

    查看表

     1 查看某个库有多少表
     2 show  tables;
     3 查看某个新建表信息
     4 show  create table 表名;
     5 查看表结构
     6 desc   表名;
     7  
     8 查看表记录
     9 查看表的所有字段内容*
    10 select *  from  表名;
    11 mysql> select * from host;
    12 Empty set (0.00 sec)
    13  
    14 5.查看表内容
    15 查看表的某些字段的内容
    16 select  id  from host;              #查看host表的id字段的内容
    17 select  id,port   from   host;      #查看host表的id字段和port字典的内容
    18  
    19 
    20 
    21 
    22 mysql> show tables;
    23 +----------------+
    24 | Tables_in_xixi |
    25 +----------------+
    26 | host           |
    27 +----------------+
    28 1 row in set (0.00 sec)
    29  
    30 mysql> show create table host;
    31 +-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
    32 | Table | Create Table                                                                                                                                                |
    33 +-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
    34 | host  | CREATE TABLE `host` (
    35   `id` int(10) DEFAULT NULL,
    36   `hostname` char(20) DEFAULT NULL,
    37   `port` int(5) DEFAULT NULL
    38 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
    39 +-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
    40 1 row in set (0.00 sec)
    41  
    42 mysql>
    43 mysql> desc host;
    44 +----------+----------+------+-----+---------+-------+
    45 | Field    | Type     | Null | Key | Default | Extra |
    46 +----------+----------+------+-----+---------+-------+
    47 | id       | int(10)  | YES  |     | NULL    |       |
    48 | hostname | char(20) | YES  |     | NULL    |       |
    49 | port     | int(5)   | YES  |     | NULL    |       |
    50 +----------+----------+------+-----+---------+-------+
    51 3 rows in set (0.01 sec)
    52 field 代表字段名
    53 type代表该字段类型,
    54 Null 该字段是否可以为空
    55 default     该字段的默认设置
    56 extra        额外的设置
    57 
    58 mysql> select * from xixi.host;
    59 Empty set (0.00 sec)    #empty这里表示一张空表
    60  
    61 mysql> select id,port from xixi.host;
    62 Empty set (0.00 sec)
    create table employee(
                id int primary key auto_increment ,
                name varchar(20),
                gender bit default 1,   -- gender char(1)  default 1   -----    或者 TINYINT(1) 
                birthday date,
                entry_date date,
                job varchar(20),
                salary double(4,2) unsigned,
                resume text    -- 注意,这里作为最后一个字段不加逗号
              );
    
    
        /* 约束:
           primary key (非空且唯一)  :能够唯一区分出当前记录的字段称为主键!
           unique
           not null
           auto_increment 主键字段必须是数字类型。
           外键约束 foreign key  */

    修改表结构(字段)

    修改一列类型
          alter table tab_name modify 列名 类型 [完整性约束条件][first|after 字段名];
          alter table users2 modify age tinyint default 20;
          alter table users2 modify age int  after id;
       
    修改列名
          alter table tab_name change [column] 列名 新列名 类型 [完整性约束条件][first|after 字段名];
          alter table users2 change age Age int default 28 first;
    
    删除一列
          alter table tab_name drop [column] 列名;
          -- 思考:删除多列呢?删一个填一个呢?
          alter table users2 
                add salary float(6,2) unsigned not null after name,
                drop addr;    
    
    修改表名
          rename table 表名 to 新表名;
    修该表所用的字符集    
          alter table student character set utf8;
    
    删除表
        drop table tab_name;
    
    添加主键,删除主键
        alter table tab_name add primary key(字段名称,...) 
        alter table users drop primary key;
    
    eg:
        mysql> create table test5(num int auto_increment);
        ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key
        create table test(num int primary key auto_increment);
        -- 思考,如何删除主键?
        alter table test modify id int;   -- auto_increment没了,但这样写主键依然存在,所以还要加上下面这句
        alter table test drop primary key;-- 仅仅用这句也无法直接删除主键
    
    -- 唯一索引
        alter table tab_name add unique [index|key] [索引名称](字段名称,...) 
    
        alter table users add unique(name)-- 索引值默认为字段名show create table users;
        alter table users add unique key user_name(name);-- 索引值为user_name
    
        -- 添加联合索引
        alter table users add unique index name_age(name,age);#show create table users;
    
        -- 删除唯一索引
        alter table tab_name drop {index|key} index_name

    表记录增,删,改

    -- 1.增加一条记录insert
    
          /*insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......);*/
    
    
          create table employee_new(
                     id int primary key auto_increment,
                     name varchar(20) not null unique,
                     birthday varchar(20),
                     salary float(7,2)
                                 );
    
           insert into employee_new (id,name,birthday,salary) values
                         (1,'yuan','1990-09-09',9000);
    
           insert into employee_new values
           (2,'alex','1989-08-08',3000);
    
           insert into employee_new (name,salary) values
           ('xialv',1000);
    
          -- 插入多条数据
           insert into employee_new values
           (4,'alvin1','1993-04-20',3000),
           (5,'alvin2','1995-05-12',5000);
    
          -- set插入: insert [into] tab_name set 字段名=值
    
          insert into employee_new set id=12,name="alvin3";
    
    
    -- 2.修改表记录  update tab_name set field1=value1,field2=value2,......[where 语句]
    
        /*      UPDATE语法可以用新值更新原有表行中的各列。
                SET子句指示要修改哪些列和要给予哪些值。
                WHERE子句指定应更新哪些行。如没有WHERE子句,则更新所有的行。*/
    
    
        update employee_new set birthday="1989-10-24" WHERE id=1;
    
        --- 将yuan的薪水在原有基础上增加1000元。
        update employee_new set salary=salary+4000 where name='yuan';
    
    -- 3.删除表纪录
    
         delete from tab_name [where ....]
    
            /*    如果不跟where语句则删除整张表中的数据
                delete只能用来删除一行记录
                delete语句只能删除表中的内容,不能删除表本身,想要删除表,用drop
                TRUNCATE TABLE也可以删除表中的所有数据,词语句首先摧毁表,再新建表。此种方式删除的数据不能在
                事务中恢复。*/
    
                    -- 删除表中名称为’alex’的记录。
                    delete from employee_new where name='alex';
                    -- 删除表中所有记录。
                    delete from employee_new;-- 注意auto_increment没有被重置:alter table employee auto_increment=1;
                    -- 使用truncate删除表中记录。
                    truncate table emp_new;

    表记录之查

    CREATE TABLE ExamResult(
    
       id INT PRIMARY KEY  auto_increment,
       name VARCHAR (20),
       JS DOUBLE ,
       Django DOUBLE ,
       Database DOUBLE
    );
    
    
    INSERT INTO ExamResult VALUES  (1,"yuan",98,98,98),
                                   (2,"xialv",35,98,67),
                                   (3,"alex",59,59,62),
                                   (4,"wusir",88,89,82),
                                   (5,"alvin",88,98,67),
                                   (6,"yuan",86,100,55);
    
    
    -- (1)select [distinct] *|field1,field2,......   from tab_name
                -- 其中from指定从哪张表筛选,*表示查找所有列,也可以指定一个列
                -- 表明确指定要查找的列,distinct用来剔除重复行。
    
                        -- 查询表中所有学生的信息。
                        select * from ExamResult;
                        -- 查询表中所有学生的姓名和对应的英语成绩。
                        select name,JS from ExamResult;
                        -- 过滤表中重复数据。
                        select distinct JS ,name from ExamResult;
    
    
    
    -- (2)select 也可以使用表达式,并且可以使用: 字段 as 别名或者:字段 别名
    
                    -- 在所有学生分数上加10分特长分显示。
                    select name,JS+10,Django+10,Database+10 from ExamResult;
                    -- 统计每个学生的总分。
                    select name,JS+Django+Database from ExamResult;
                    -- 使用别名表示学生总分。
                    select name as 姓名,JS+Django+Database as 总成绩 from ExamResult;
                    select name,JS+Django+Database 总成绩 from ExamResult;
                    select name JS from ExamResult; //what will happen?---->记得加逗号
    
    -- (3)使用where子句,进行过滤查询。
    
                -- 查询姓名为XXX的学生成绩
                select * from ExamResult where name='yuan';
                -- 查询英语成绩大于90分的同学
                select id,name,JS from ExamResult where JS>90;
                -- 查询总分大于200分的所有同学
                select name,JS+Django+Database as 总成绩 from
                            ExamResult where JS+Django+Database>200 ;
                -- where字句中可以使用:
                         -- 比较运算符:
                            > < >= <= <> !=
                            between 80 and 100 值在10到20之间
                            in(80,90,100) 值是10或20或30
                            like 'yuan%'
                            /*
                            pattern可以是%或者_,
                            如果是%则表示任意多字符,此例如唐僧,唐国强
                            如果是_则表示一个字符唐_,只有唐僧符合。
                            */
    
                        -- 逻辑运算符
                            在多个条件直接可以使用逻辑运算符 and or not
                -- 练习
                    -- 查询JS分数在 70-100之间的同学。
                    select name ,JS from ExamResult where JS between 80 and 100;
                    -- 查询Django分数为75,76,77的同学。
                    select name ,Django from ExamResult where Django in (75,98,77);
                    -- 查询所有姓王的学生成绩。
                    select * from ExamResult where name like '王%';
                    -- 查询JS分>90,Django分>90的同学。
                    select id,name from ExamResult where JS>90 and Django >90;
                    -- 查找缺考数学的学生的姓名
                    select name from ExamResult where Database is null;
    
    
    -- (4)Order by 指定排序的列,排序的列即可是表中的列名,也可以是select 语句后指定的别名。
    
                  -- select *|field1,field2... from tab_name order by field [Asc|Desc]
    
                  -- Asc 升序、Desc 降序,其中asc为默认值 ORDER BY 子句应位于SELECT语句的结尾。
                  -- 练习:
                  -- 对JS成绩排序后输出。
                  select * from ExamResult order by JS;
                  -- 对总分排序按从高到低的顺序输出
                  select name ,(ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0))
                       总成绩 from ExamResult order by 总成绩 desc;
                  -- 对姓李的学生成绩排序输出
                  select name ,(ifnull(JS,0)+ifnull(Django,0)+ifnull(Dababase,0))
                       总成绩 from ExamResult where name like 'a%'
                                             order by 总成绩 desc;
    
    
    -- (5)group by 分组查询:
    
                -- 注意,按分组条件分组后每一组只会显示第一条记录
    
                -- group by字句,其后可以接多个列名,也可以跟having子句,对group by 的结果进行筛选。
                          -- 按位置字段筛选
                             select * from ExamResult group by 2;
    
                          -- 练习:对成绩表按名字分组后,显示每一类名字的JS的分数总和
                              select NAME ,SUM(JS)from ExamResult group by name;
                          -- 练习:对成绩表按名字分组后,显示每一类名字的Django的分数总和>150的
                          --      类名字和django总分
                             --INSERT INTO ExamResult VALUES  (12,"alex",90,90,90);
    
                              select name,sum(Django) from ExamResult group by name
                                                      having sum(Django)>150;
    
                       /*
                       having 和 where两者都可以对查询结果进行进一步的过滤,差别有:
                         <1>where语句只能用在分组之前的筛选,having可以用在分组之后的筛选;
                         <2>使用where语句的地方都可以用having进行替换
                         <3>having中可以用聚合函数,where中就不行。
                       */
                        -- 练习:对成绩表按名字分组后,显示除了yuan这一组以外的每一类名字的Django
                        -- 的分数总和>150的类名字和django总分
    
    
                            select name,sum(Django) from ExamResult
                                                      WHERE name!="yuan"
                                                      group by name
                                                      having sum(Django)>130;
    
    
                -- GROUP_CONCAT() 函数
                SELECT id,GROUP_CONCAT(name),GROUP_CONCAT(JS) from ExamResult GROUP BY id;
    
    -- (6)聚合函数: 先不要管聚合函数要干嘛,先把要求的内容查出来再包上聚合函数即可。
                     --   (一般和分组查询配合使用)
    
            --<1> 统计表中所有记录
    
                -- COUNT(列名):统计行的个数
                        -- 统计一个班级共有多少学生?先查出所有的学生,再用count包上
                         select count(*) from ExamResult;
                        -- 统计JS成绩大于70的学生有多少个?
                         select count(JS) from ExamResult where JS>70;
                        -- 统计总分大于280的人数有多少?
                         select count(name) from ExamResult
                               where (ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0))>280;
                        -- 注意:count(*)统计所有行;     count(字段)不统计null值.
    
                -- SUM(列名):统计满足条件的行的内容和
                        -- 统计一个班级JS总成绩?先查出所有的JS成绩,再用sum包上
                            select JS as JS总成绩 from ExamResult;
                            select sum(JS) as JS总成绩 from ExamResult;
                        -- 统计一个班级各科分别的总成绩
                            select sum(JS) as JS总成绩,
                                   sum(Django) as Django总成绩,
                                   sum(Database) as Database总成绩 from ExamResult;
    
                        -- 统计一个班级各科的成绩总和
                            select sum(ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0))
                                                        as 总成绩 from ExamResult;
                        -- 统计一个班级JS成绩平均分
                            select sum(JS)/count(*) from ExamResult ;
                        -- 注意:sum仅对数值起作用,否则会报错。
    
                -- AVG(列名):
                                -- 求一个班级JS平均分?先查出所有的JS分,然后用avg包上。
                                    select avg(ifnull(JS,0)) from ExamResult;
                                -- 求一个班级总分平均分
                                    select avg((ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0)))
                                                             from ExamResult ;
                    -- Max、Min
                                -- 求班级最高分和最低分(数值范围在统计中特别有用)
                                select Max((ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0)))
                                最高分 from ExamResult;
                                select Min((ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0)))
                                最低分 from ExamResult;
    
                    -- 注意:null 和所有的数计算都是null,所以需要用ifnull将null转换为0!
                    --      -----ifnull(JS,0)
    
    
                    -- with rollup的使用
    
                --<2> 统计分组后的组记录
    
    
    -- (7) 重点:Select from where group by having order by
                    -- Mysql在执行sql语句时的执行顺序:from  where  select group by  having order by
                    -- 分析:
                    select JS as JS成绩 from ExamResult where JS成绩 >70; ---- 不成功
                    select JS as JS成绩 from ExamResult having JS成绩 >90; --- 成功
                    select JS as JS成绩 from ExamResult group by JS成绩 having JS成绩 >80; ----成功
                    select JS as JS成绩 from ExamResult order by JS成绩;----成功
                    select * from ExamResult as 成绩 where 成绩.JS>85; ---- 成功
    
    --  (8) limit
                    SELECT * from ExamResult limit 1;
                    SELECT * from ExamResult limit 1,5;

    外键约束

    创建外键

     1 ---  每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任
     2 
     3 ----主表
     4 
     5 CREATE TABLE ClassCharger(
     6 
     7        id TINYINT PRIMARY KEY auto_increment,
     8        name VARCHAR (20),
     9        age INT ,
    10        is_marriged boolean  -- show create table ClassCharger: tinyint(1)
    11 
    12 );
    13 
    14 INSERT INTO ClassCharger (name,age,is_marriged) VALUES ("冰冰",12,0),
    15                                                        ("丹丹",14,0),
    16                                                        ("歪歪",22,0),
    17                                                        ("姗姗",20,0),
    18                                                        ("小雨",21,0);
    19 
    20 
    21 ----子表
    22 
    23 CREATE TABLE Student(
    24 
    25        id INT PRIMARY KEY auto_increment,
    26        name VARCHAR (20),
    27        charger_id TINYINT,     --切记:作为外键一定要和关联主键的数据类型保持一致
    28        -- [ADD CONSTRAINT charger_fk_stu]FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
    29 
    30 ) ENGINE=INNODB;
    31 
    32 INSERT INTO Student(name,charger_id) VALUES ("alvin1",2),
    33                                             ("alvin2",4),
    34                                             ("alvin3",1),
    35                                             ("alvin4",3),
    36                                             ("alvin5",1),
    37                                             ("alvin6",3),
    38                                             ("alvin7",2);
    39 
    40 
    41 DELETE FROM ClassCharger WHERE name="冰冰";
    42 INSERT student (name,charger_id) VALUES ("yuan",1);
    43 -- 删除居然成功,可是 alvin3显示还是有班主任id=1的冰冰的;
    44 
    45 -----------增加外键和删除外键---------
    46 
    47 ALTER TABLE student  ADD CONSTRAINT abc
    48                      FOREIGN KEY(charger_id)
    49                      REFERENCES  classcharger(id);
    50 
    51 
    52 ALTER TABLE student DROP FOREIGN KEY abc;

    innodb支持的on语句

     1 --外键约束对子表的含义:   如果在父表中找不到候选键,则不允许在子表上进行insert/update
     2 
     3 --外键约束对父表的含义:    在父表上进行update/delete以更新或删除在子表中有一条或多条对
     4                     -- 应匹配行的候选键时,父表的行为取决于:在定义子表的外键时指定的
     5                     -- on update/on delete子句
     6 
     7 
     8 -----------------innodb支持的四种方式---------------------------------------
     9 
    10 -----cascade方式 在父表上update/delete记录时,同步update/delete掉子表的匹配记录
    11 -----外键的级联删除:如果父表中的记录被删除,则子表中对应的记录自动被删除--------
    12 
    13      FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
    14                               ON DELETE CASCADE
    15 
    16 
    17 ------set null方式 在父表上update/delete记录时,将子表上匹配记录的列设为null
    18    -- 要注意子表的外键列不能为not null
    19 
    20      FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
    21                               ON DELETE SET NULL
    22 
    23 
    24 ------Restrict方式 :拒绝对父表进行删除更新操作(了解)
    25 
    26 ------No action方式 在mysql中同Restrict,如果子表中有匹配的记录,则不允许对父表对应候选键
    27    -- 进行update/delete操作(了解)

    多表查询

     1 -- 准备两张表
     2 -- company.employee
     3 -- company.department
     4 
     5       create table employee(
     6       emp_id int auto_increment primary key not null,
     7       emp_name varchar(50),
     8       age int,
     9       dept_id int
    10       );
    11 
    12       insert into employee(emp_name,age,dept_id) values
    13         ('A',19,200),
    14         ('B',26,201),
    15         ('C',30,201),
    16         ('D',24,202),
    17         ('E',20,200),
    18         ('F',38,204);
    19 
    20 
    21     create table department(
    22        dept_id int,
    23        dept_name varchar(100)
    24       );
    25 
    26     insert into department values
    27       (200,'人事部'),
    28       (201,'技术部'),
    29       (202,'销售部'),
    30       (203,'财政部');
    31 
    32 mysql> select * from employee;
    33 +--------+----------+------+---------+
    34 | emp_id | emp_name | age  | dept_id |
    35 +--------+----------+------+---------+
    36 |      1 | A        |   19 |     200 |
    37 |      2 | B        |   26 |     201 |
    38 |      3 | C        |   30 |     201 |
    39 |      4 | D        |   24 |     202 |
    40 |      5 | E        |   20 |     200 |
    41 |      6 | F        |   38 |     204 |
    42 +--------+----------+------+---------+
    43 rows in set (0.00 sec)
    44 
    45 mysql> select * from department;
    46 +---------+-----------+
    47 | dept_id | dept_name |
    48 +---------+-----------+
    49 |     200 | 人事部    |
    50 |     201 | 技术部    |
    51 |     202 | 销售部    |
    52 |     203 | 财政部    |
    53 +---------+-----------+
    54 rows in set (0.01 sec)

    多表查询之连接查询

    1.笛卡尔积查询

    mysql> SELECT * FROM employee,department;
    
    --        select employee.emp_id,employee.emp_name,employee.age,
    --        department.dept_name from employee,department;
    
    +--------+----------+------+---------+---------+-----------+
    | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
    +--------+----------+------+---------+---------+-----------+
    |      1 | A        |   19 |     200 |     200 | 人事部    |
    |      1 | A        |   19 |     200 |     201 | 技术部    |
    |      1 | A        |   19 |     200 |     202 | 销售部    |
    |      1 | A        |   19 |     200 |     203 | 财政部    |
    |      2 | B        |   26 |     201 |     200 | 人事部    |
    |      2 | B        |   26 |     201 |     201 | 技术部    |
    |      2 | B        |   26 |     201 |     202 | 销售部    |
    |      2 | B        |   26 |     201 |     203 | 财政部    |
    |      3 | C        |   30 |     201 |     200 | 人事部    |
    |      3 | C        |   30 |     201 |     201 | 技术部    |
    |      3 | C        |   30 |     201 |     202 | 销售部    |
    |      3 | C        |   30 |     201 |     203 | 财政部    |
    |      4 | D        |   24 |     202 |     200 | 人事部    |
    |      4 | D        |   24 |     202 |     201 | 技术部    |
    |      4 | D        |   24 |     202 |     202 | 销售部    |
    |      4 | D        |   24 |     202 |     203 | 财政部    |
    |      5 | E        |   20 |     200 |     200 | 人事部    |
    |      5 | E        |   20 |     200 |     201 | 技术部    |
    |      5 | E        |   20 |     200 |     202 | 销售部    |
    |      5 | E        |   20 |     200 |     203 | 财政部    |
    |      6 | F        |   38 |     204 |     200 | 人事部    |
    |      6 | F        |   38 |     204 |     201 | 技术部    |
    |      6 | F        |   38 |     204 |     202 | 销售部    |
    |      6 | F        |   38 |     204 |     203 | 财政部    |
    +--------+----------+------+---------+---------+-----------+

    2.内连接

     1 -- 查询两张表中都有的关联数据,相当于利用条件从笛卡尔积结果中筛选出了正确的结果。
     2 
     3   select * from employee,department where employee.dept_id = department.dept_id;
     4 --select * from employee inner join department on employee.dept_id = department.dept_id;
     5 
     6       +--------+----------+------+---------+---------+-----------+
     7       | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
     8       +--------+----------+------+---------+---------+-----------+
     9       |      1 | A        |   19 |     200 |     200 | 人事部    |
    10       |      2 | B        |   26 |     201 |     201 | 技术部    |
    11       |      3 | C        |   30 |     201 |     201 | 技术部    |
    12       |      4 | D        |   24 |     202 |     202 | 销售部    |
    13       |      5 | E        |   20 |     200 |     200 | 人事部    |
    14       +--------+----------+------+---------+---------+-----------+

    3.外链接

     1 --(1)左外连接:在内连接的基础上增加左边有右边没有的结果
     2 
     3  select * from employee left join department on employee.dept_id = department.dept_id;
     4 
     5      +--------+----------+------+---------+---------+-----------+
     6     | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
     7     +--------+----------+------+---------+---------+-----------+
     8     |      1 | A        |   19 |     200 |     200 | 人事部    |
     9     |      5 | E        |   20 |     200 |     200 | 人事部    |
    10     |      2 | B        |   26 |     201 |     201 | 技术部    |
    11     |      3 | C        |   30 |     201 |     201 | 技术部    |
    12     |      4 | D        |   24 |     202 |     202 | 销售部    |
    13     |      6 | F        |   38 |     204 |    NULL | NULL      |
    14     +--------+----------+------+---------+---------+-----------+
    15 
    16  --(2)右外连接:在内连接的基础上增加右边有左边没有的结果
    17 
    18  select * from employee RIGHT JOIN department on employee.dept_id = department.dept_id;
    19 
    20         +--------+----------+------+---------+---------+-----------+
    21         | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
    22         +--------+----------+------+---------+---------+-----------+
    23         |      1 | A        |   19 |     200 |     200 | 人事部    |
    24         |      2 | B        |   26 |     201 |     201 | 技术部    |
    25         |      3 | C        |   30 |     201 |     201 | 技术部    |
    26         |      4 | D        |   24 |     202 |     202 | 销售部    |
    27         |      5 | E        |   20 |     200 |     200 | 人事部    |
    28         |   NULL | NULL     | NULL |    NULL |     203 | 财政部    |
    29         +--------+----------+------+---------+---------+-----------+
    30 
    31  --(3)全外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果
    32 
    33     -- mysql不支持全外连接 full JOIN
    34     -- mysql可以使用此种方式间接实现全外连接
    35     
    36    select * from employee RIGHT JOIN department on employee.dept_id = department.dept_id
    37    UNION
    38    select * from employee LEFT JOIN department on employee.dept_id = department.dept_id;
    39 
    40         
    41 
    42         +--------+----------+------+---------+---------+-----------+
    43         | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
    44         +--------+----------+------+---------+---------+-----------+
    45         |      1 | A        |   19 |     200 |     200 | 人事部    |
    46         |      2 | B        |   26 |     201 |     201 | 技术部    |
    47         |      3 | C        |   30 |     201 |     201 | 技术部    |
    48         |      4 | D        |   24 |     202 |     202 | 销售部    |
    49         |      5 | E        |   20 |     200 |     200 | 人事部    |
    50         |   NULL | NULL     | NULL |    NULL |     203 | 财政部    |
    51         |      6 | F        |   38 |     204 |    NULL | NULL      |
    52         +--------+----------+------+---------+---------+-----------+
    53 
    54       -- 注意 union与union all的区别:union会去掉相同的纪录

    多表查询之复合条件链接查询

     1 -- 查询员工年龄大于等于25岁的部门
     2 
     3     SELECT DISTINCT department.dept_name
     4     FROM employee,department
     5     WHERE employee.dept_id = department.dept_id
     6     AND age>25;
     7 
     8 
     9 --以内连接的方式查询employee和department表,并且以age字段的升序方式显示
    10 
    11     select employee.emp_id,employee.emp_name,employee.age,department.dept_name
    12     from employee,department
    13     where employee.dept_id = department.dept_id
    14     order by age asc;

    多表查询之子查询

     1 -- 子查询是将一个查询语句嵌套在另一个查询语句中。
     2 -- 内层查询语句的查询结果,可以为外层查询语句提供查询条件。
     3 -- 子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
     4 -- 还可以包含比较运算符:= 、 !=、> 、< 5 
     6 
     7 -- 1. 带IN关键字的子查询
     8 
     9    ---查询employee表,但dept_id必须在department表中出现过
    10 
    11    select * from employee
    12             where dept_id IN
    13             (select dept_id from department);
    14 
    15 
    16 +--------+----------+------+---------+
    17 | emp_id | emp_name | age  | dept_id |
    18 +--------+----------+------+---------+
    19 |      1 | A        |   19 |     200 |
    20 |      2 | B        |   26 |     201 |
    21 |      3 | C        |   30 |     201 |
    22 |      4 | D        |   24 |     202 |
    23 |      5 | E        |   20 |     200 |
    24 +--------+----------+------+---------+
    25 rows in set (0.01 sec)
    26 
    27 
    28 
    29 -- 2. 带比较运算符的子查询
    30       --      =、!=、>、>=、<、<=、<>
    31 
    32      -- 查询员工年龄大于等于25岁的部门
    33      select dept_id,dept_name from department
    34            where dept_id IN
    35           (select DISTINCT dept_id from employee where age>=25);
    36 
    37 -- 3. 带EXISTS关键字的子查询
    38 
    39 -- EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。
    40 -- 而是返回一个真假值。Ture或False
    41 -- 当返回Ture时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询
    42 
    43      select * from employee
    44               WHERE EXISTS
    45               (SELECT dept_name from department where dept_id=203);
    46 
    47       --department表中存在dept_id=203,Ture
    48 
    49 
    50      select * from employee
    51                 WHERE EXISTS
    52               (SELECT dept_name from department where dept_id=205);
    53 
    54      -- Empty set (0.00 sec)
    55 
    56 
    57     ps:  create table t1(select * from t2);
  • 相关阅读:
    CS229 6.4 Neurons Networks Autoencoders and Sparsity
    CS229 6.3 Neurons Networks Gradient Checking
    【Leetcode】【Easy】Min Stack
    【Leetcode】【Easy】Merge Sorted Array
    【Leetcode】【Easy】ZigZag Conversion
    【Leetcode】【Easy】Valid Palindrome
    【Leetcode】【Easy】Reverse Integer
    【Leetcode】【Easy】Palindrome Number
    【Leetcode】【Easy】Length of Last Word
    【Leetcode】【Easy】Remove Nth Node From End of List
  • 原文地址:https://www.cnblogs.com/YingLai/p/6427617.html
Copyright © 2011-2022 走看看