zoukankan      html  css  js  c++  java
  • mysql foreignkey

    1.foreign key

    当数据足够大的时候,字段会出现大量重复,

    解决:额外定义一个大量冗余的字段表,(有id) 一张是关联表(从表),一张是被关联表(主表)

    进行关联的时候 ,先创建被关联表, 现在被关联表添加,再是关联表

    constraint fk_dep(随便写) foreign key(dep_id) references dep(id) 

    在创建关联表 但是再修改出现问题是先删除这个部门的员工才能删除这个部门
    问题代码:
     1 #1.创建表时先创建被关联表,再创建关联表
     2 # 先创建被关联表(dep表)
     3 create table dep(
     4     id int primary key,
     5     name varchar(20) not null,
     6     descripe varchar(20) not null
     7 );
     8 
     9 #再创建关联表(emp表)
    10 create table emp(
    11     id int primary key,
    12     name varchar(20) not null,
    13     age int not null,
    14     dep_id int,
    15     constraint fk_dep foreign key(dep_id) references dep(id) 
    16 );
    17 
    18 #2.插入记录时,先往被关联表中插入记录,再往关联表中插入记录
    19 
    20 insert into dep values
    21 (1,'IT','IT技术有限部门'),
    22 (2,'销售部','销售部门'),
    23 (3,'财务部','花钱太多部门');
    24 
    25 insert into emp values
    26 (1,'zhangsan',18,1),
    27 (2,'lisi',19,1),
    28 (3,'egon',20,2),
    29 (4,'yuanhao',40,3),
    30 (5,'alex',18,2);
    31 
    32 3.删除表
    33 #按道理来说,删除了部门表中的某个部门,员工表的有关联的记录相继删除。
    34 mysql> delete from dep where id=3;
    35 ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`db5`.`emp`, CONSTRAINT `fk_name` FOREIGN KEY (`dep_id`) REFERENCES `dep` (`id`))
    36 
    37 #但是先删除员工表的记录之后,再删除当前部门就没有任何问题
    38 
    39 mysql> delete from emp where dep =3;
    40 Query OK, 1 row affected (0.00 sec)
    41 
    42 mysql> select * from emp;
    43 +----+----------+-----+--------+
    44 | id | name     | age | dep_id |
    45 +----+----------+-----+--------+
    46 |  1 | zhangsan |  18 |      1 |
    47 |  2 | lisi     |  18 |      1 |
    48 |  3 | egon     |  20 |      2 |
    49 |  5 | alex     |  18 |      2 |
    50 +----+----------+-----+--------+
    51 rows in set (0.00 sec)
    52 
    53 mysql> delete from dep where id=3;
    54 Query OK, 1 row affected (0.00 sec)
    55 
    56 mysql> select * from dep;
    57 +----+-----------+----------------------+
    58 | id | name      | descripe             |
    59 +----+-----------+----------------------+
    60 |  1 | IT        | IT技术有限部门       |
    61 |  2 | 销售部    | 销售部门             |
    62 +----+-----------+----------------------+
    63 rows in set (0.00 sec)
    删除员工才能删除部门
    解决办法:
    关联表升级:
        on delete cascade #同步删除
        on update cascade #同步更新
    就可以同步删除了
    1 create table emp(
    2     id int primary key,
    3     name varchar(20) not null,
    4     age int not null,
    5     dep_id int,
    6     constraint fk_dep foreign key(dep_id) references dep(id) 
    7     on delete cascade #同步删除
    8     on update cascade #同步更新
    9 );
    修改的emp

    后面的同步删除,更新

     1 #再去删被关联表(dep)的记录,关联表(emp)中的记录也跟着删除
     2 mysql> delete from dep where id=3;
     3 Query OK, 1 row affected (0.00 sec)
     4 
     5 mysql> select * from dep;
     6 +----+-----------+----------------------+
     7 | id | name      | descripe             |
     8 +----+-----------+----------------------+
     9 |  1 | IT        | IT技术有限部门       |
    10 |  2 | 销售部    | 销售部门             |
    11 +----+-----------+----------------------+
    12 rows in set (0.00 sec)
    13 
    14 mysql> select * from emp;
    15 +----+----------+-----+--------+
    16 | id | name     | age | dep_id |
    17 +----+----------+-----+--------+
    18 |  1 | zhangsan |  18 |      1 |
    19 |  2 | lisi     |  19 |      1 |
    20 |  3 | egon     |  20 |      2 |
    21 |  5 | alex     |  18 |      2 |
    22 +----+----------+-----+--------+
    23 rows in set (0.00 sec)
    24 
    25 #再去更改被关联表(dep)的记录,关联表(emp)中的记录也跟着更改
    26 
    27 mysql> update dep set id=222 where id=2;
    28 Query OK, 1 row affected (0.02 sec)
    29 Rows matched: 1  Changed: 1  Warnings: 0
    30 
    31 # 赶紧去查看一下两张表是否都被删除了,是否都被更改了
    32 mysql> select * from dep;
    33 +-----+-----------+----------------------+
    34 | id  | name      | descripe             |
    35 +-----+-----------+----------------------+
    36 |   1 | IT        | IT技术有限部门       |
    37 | 222 | 销售部    | 销售部门             |
    38 +-----+-----------+----------------------+
    39 rows in set (0.00 sec)
    40 
    41 mysql> select * from emp;
    42 +----+----------+-----+--------+
    43 | id | name     | age | dep_id |
    44 +----+----------+-----+--------+
    45 |  1 | zhangsan |  18 |      1 |
    46 |  2 | lisi     |  19 |      1 |
    47 |  3 | egon     |  20 |    222 |
    48 |  5 | alex     |  18 |    222 |
    49 +----+----------+-----+--------+
    50 rows in set (0.00 sec)
    同步删除,更新

    2.

    外键的变种 三种关系

    因为有foreign key 的约束 ,使表有了三种关系

    多对一  书 出版商 (一个出版商可以出版多种书  而一本书只能由一个出版商出,因为版权)

    先创建出版商,在创建书 (含有

     constraint fk_book_press foreign key(press_id) references press(id)
        on delete cascade
        on update cascade
    );

    )

     1 create table press(
     2     id int primary key auto_increment,
     3     name varchar(20)
     4 );
     5 
     6 create table book(
     7     id int primary key auto_increment,
     8     name varchar(20),
     9     press_id int not null,
    10          constraint fk_book_press foreign key(press_id) references press(id)
    11     on delete cascade
    12     on update cascade
    13 );
    14 
    15 # 先往被关联表中插入记录
    16 insert into press(name) values
    17 ('北京工业地雷出版社'),
    18 ('人民音乐不好听出版社'),
    19 ('知识产权没有用出版社')
    20 ;
    21 
    22 # 再往关联表中插入记录
    23 insert into book(name,press_id) values
    24 ('九阳神功',1),
    25 ('九阴真经',2),
    26 ('九阴白骨爪',2),
    27 ('独孤九剑',3),
    28 ('降龙十巴掌',2),
    29 ('葵花宝典',3)
    30 ;
    31 
    32 查询结果:
    33 mysql> select * from book;
    34 +----+-----------------+----------+
    35 | id | name            | press_id |
    36 +----+-----------------+----------+
    37 |  1 | 九阳神功        |        1 |
    38 |  2 | 九阴真经        |        2 |
    39 |  3 | 九阴白骨爪      |        2 |
    40 |  4 | 独孤九剑        |        3 |
    41 |  5 | 降龙十巴掌      |        2 |
    42 |  6 | 葵花宝典        |        3 |
    43 +----+-----------------+----------+
    44 rows in set (0.00 sec)
    45 
    46 mysql> select * from press;
    47 +----+--------------------------------+
    48 | id | name                           |
    49 +----+--------------------------------+
    50 |  1 | 北京工业地雷出版社             |
    51 |  2 | 人民音乐不好听出版社           |
    52 |  3 | 知识产权没有用出版社           |
    53 +----+--------------------------------+
    54 rows in set (0.00 sec)
    55 
    56 书和出版社(多对一)
    多对一

    多对多 书 作者  (作者可以写多本书,书也可由多个作者)

    这样是无法创建foreign ke关系的,可以创建第三张表存放

    1.创建书 和 作者 2.创建出一个表明关系的表  3.放入作者和作者的作品.4.在公共表放上数据(

    insert into author2book(author_id,book_id) values

    )

     1 # 创建被关联表author表,之前的book表在讲多对一的关系已创建
     2 create table author(
     3     id int primary key auto_increment,
     4     name varchar(20)
     5 );
     6 #这张表就存放了author表和book表的关系,即查询二者的关系查这表就可以了
     7 create table author2book(
     8     id int not null unique auto_increment,
     9     author_id int not null,
    10     book_id int not null,
    11     constraint fk_author foreign key(author_id) references author(id)
    12     on delete cascade
    13     on update cascade,
    14     constraint fk_book foreign key(book_id) references book(id)
    15     on delete cascade
    16     on update cascade,
    17     primary key(author_id,book_id)
    18 );
    19 #插入四个作者,id依次排开
    20 insert into author(name) values('egon'),('alex'),('wusir'),('yuanhao');
    21 
    22 # 每个作者的代表作
    23 egon: 九阳神功、九阴真经、九阴白骨爪、独孤九剑、降龙十巴掌、葵花宝典
    24 alex: 九阳神功、葵花宝典
    25 wusir:独孤九剑、降龙十巴掌、葵花宝典
    26 yuanhao:九阳神功
    27 
    28 # 在author2book表中插入相应的数据
    29 
    30 insert into author2book(author_id,book_id) values
    31 (1,1),
    32 (1,2),
    33 (1,3),
    34 (1,4),
    35 (1,5),
    36 (1,6),
    37 (2,1),
    38 (2,6),
    39 (3,4),
    40 (3,5),
    41 (3,6),
    42 (4,1)
    43 ;
    44 # 现在就可以查author2book对应的作者和书的关系了
    45 mysql> select * from author2book;
    46 +----+-----------+---------+
    47 | id | author_id | book_id |
    48 +----+-----------+---------+
    49 |  1 |         1 |       1 |
    50 |  2 |         1 |       2 |
    51 |  3 |         1 |       3 |
    52 |  4 |         1 |       4 |
    53 |  5 |         1 |       5 |
    54 |  6 |         1 |       6 |
    55 |  7 |         2 |       1 |
    56 |  8 |         2 |       6 |
    57 |  9 |         3 |       4 |
    58 | 10 |         3 |       5 |
    59 | 11 |         3 |       6 |
    60 | 12 |         4 |       1 |
    61 +----+-----------+---------+
    62 rows in set (0.00 sec)
    63 
    64 作者与书籍关系(多对多)
    多对多

    一对一

    在其中从表的仿造主表加上unique

     1 #例如: 一个用户只能注册一个博客
     2 
     3 #两张表: 用户表 (user)和 博客表(blog)
     4 # 创建用户表
     5 create table user(
     6     id int primary key auto_increment,
     7     name varchar(20)
     8 );
     9 # 创建博客表
    10 create table blog(
    11     id int primary key auto_increment,
    12     url varchar(100),
    13     user_id int unique,
    14     constraint fk_user foreign key(user_id) references user(id)
    15     on delete cascade
    16     on update cascade
    17 );
    18 #插入用户表中的记录
    19 insert into user(name) values
    20 ('alex'),
    21 ('wusir'),
    22 ('egon'),
    23 ('xiaoma')
    24 ;
    25 # 插入博客表的记录
    26 insert into blog(url,user_id) values
    27 ('http://www.cnblog/alex',1),
    28 ('http://www.cnblog/wusir',2),
    29 ('http://www.cnblog/egon',3),
    30 ('http://www.cnblog/xiaoma',4)
    31 ;
    32 # 查询wusir的博客地址
    33 select url from blog where user_id=2;
    34 
    35 用户和博客(一对一)
    一对一


    二.

    单表查询

    语法 select 字段1,字段2 ...(*) from 表名

    where 条件

    group by

    (1)where 约束 

    where子句中可以使用

    1.比较运算符>,<,>=,<=,<>,!=

    2.between 80  and 100;(前面是)需要查找的条件

    3. in (80,90,100);值再()中间

    4.like"jin%" %表示查找多个含有jin的字符

    like"ale_" _表示查找一个含有ale关键字的字符

    5.逻辑运算符: 可以再多个条件下使用逻辑运算符 and or  not

      1 #1 :单条件查询
      2 mysql> select id,emp_name from employee where id > 5;
      3 +----+------------+
      4 | id | emp_name   |
      5 +----+------------+
      6 |  6 | jingliyang |
      7 |  7 | jinxin     |
      8 |  8 | xiaomage   |
      9 |  9 | 歪歪       |
     10 | 10 | 丫丫       |
     11 | 11 | 丁丁       |
     12 | 12 | 星星       |
     13 | 13 | 格格       |
     14 | 14 | 张野       |
     15 | 15 | 程咬金     |
     16 | 16 | 程咬银     |
     17 | 17 | 程咬铜     |
     18 | 18 | 程咬铁     |
     19 
     20 #2 多条件查询
     21 mysql> select emp_name from employee where post='teacher' and salary>10000;
     22 +----------+
     23 | emp_name |
     24 +----------+
     25 | alex         |
     26 | jinxin     |
     27 +----------+
     28 
     29 #3.关键字BETWEEN AND
     30  SELECT name,salary FROM employee 
     31         WHERE salary BETWEEN 10000 AND 20000;
     32 
     33  SELECT name,salary FROM employee 
     34         WHERE salary NOT BETWEEN 10000 AND 20000;
     35 
     36 #注意''是空字符串,不是null
     37  SELECT name,post_comment FROM employee WHERE post_comment='';
     38  ps:
     39         执行
     40         update employee set post_comment='' where id=2;
     41         再用上条查看,就会有结果了
     42 #5:关键字IN集合查询
     43 mysql>  SELECT name,salary FROM employee WHERE salary=3000 OR salary=3500 OR salary=4000 OR salary=9000 ;
     44 +------------+---------+
     45 | name       | salary  |
     46 +------------+---------+
     47 | yuanhao    | 3500.00 |
     48 | jingliyang | 9000.00 |
     49 +------------+---------+
     50 rows in set (0.00 sec)
     51 
     52 mysql>  SELECT name,salary FROM employee  WHERE salary IN (3000,3500,4000,9000) ;
     53 +------------+---------+
     54 | name       | salary  |
     55 +------------+---------+
     56 | yuanhao    | 3500.00 |
     57 | jingliyang | 9000.00 |
     58 +------------+---------+
     59 mysql>  SELECT name,salary FROM employee  WHERE salary NOT IN (3000,3500,4000,9000) ;
     60 +-----------+------------+
     61 | name      | salary     |
     62 +-----------+------------+
     63 | egon      |    7300.33 |
     64 | alex      | 1000000.31 |
     65 | wupeiqi   |    8300.00 |
     66 | liwenzhou |    2100.00 |
     67 | jinxin    |   30000.00 |
     68 | xiaomage  |   10000.00 |
     69 | 歪歪      |    3000.13 |
     70 | 丫丫      |    2000.35 |
     71 | 丁丁      |    1000.37 |
     72 | 星星      |    3000.29 |
     73 | 格格      |    4000.33 |
     74 | 张野      |   10000.13 |
     75 | 程咬金    |   20000.00 |
     76 | 程咬银    |   19000.00 |
     77 | 程咬铜    |   18000.00 |
     78 | 程咬铁    |   17000.00 |
     79 +-----------+------------+
     80 rows in set (0.00 sec)
     81 
     82 #6:关键字LIKE模糊查询
     83 通配符’% 84 mysql> SELECT * FROM employee WHERE name LIKE 'jin%';
     85 +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+
     86 | id | name       | sex    | age | hire_date  | post    | post_comment | salary   | office | depart_id |
     87 +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+
     88 |  6 | jingliyang | female |  18 | 2011-02-11 | teacher | NULL         |  9000.00 |    401 |         1 |
     89 |  7 | jinxin     | male   |  18 | 1900-03-01 | teacher | NULL         | 30000.00 |    401 |         1 |
     90 +----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+
     91 rows in set (0.00 sec)
     92 
     93 
     94 通配符'_'
     95 
     96 mysql> SELECT  age FROM employee WHERE name LIKE 'ale_';
     97 +-----+
     98 | age |
     99 +-----+
    100 |  78 |
    101 +-----+
    102 row in set (0.00 sec)
    103 
    104 练习:
    105 1. 查看岗位是teacher的员工姓名、年龄
    106 2. 查看岗位是teacher且年龄大于30岁的员工姓名、年龄
    107 3. 查看岗位是teacher且薪资在9000-1000范围内的员工姓名、年龄、薪资
    108 4. 查看岗位描述不为NULL的员工信息
    109 5. 查看岗位是teacher且薪资是10000或9000或30000的员工姓名、年龄、薪资
    110 6. 查看岗位是teacher且薪资不是10000或9000或30000的员工姓名、年龄、薪资
    111 7. 查看岗位是teacher且名字是jin开头的员工姓名、年薪
    112 
    113 #对应的sql语句
    114 select name,age from employee where post = 'teacher';
    115 select name,age from employee where post='teacher' and age > 30; 
    116 select name,age,salary from employee where post='teacher' and salary between 9000 and 10000;
    117 select * from employee where post_comment is not null;
    118 select name,age,salary from employee where post='teacher' and salary in (10000,9000,30000);
    119 select name,age,salary from employee where post='teacher' and salary not in (10000,9000,30000);
    120 select name,salary*12 from employee where post='teacher' and name like 'jin%';
    121 
    122 where约束
    where 详解以及练习

    (2)group by 分组查询

    #1、首先明确一点:分组发生在where之后,即分组是基于where之后得到的记录而进行的
    
    #2、分组指的是:将所有记录按照某个相同字段进行归类,比如针对员工信息表的职位分组,或者按照性别进行分组等
    
    #3、为何要分组呢?
        取每个部门的最高工资
        取每个部门的员工数
        取男人数和女人数
    
    小窍门:‘每’这个字后面的字段,就是我们分组的依据
    
    #4、大前提:
        可以按照任意字段分组,但是分组完毕后,比如group by post,只能查看post字段,如果想查看组内信息,需要借助于聚合函数

    在分组前需要进行
    mysql> set global sql_mode='ONLY_FULL_GROUP_BY';
    也可以将
    ONLY_FULL_GROUP_BY 放置配置文件上

    聚合函数辅助分组

     1 mysql> select * from emp group by post;# 报错
     2 ERROR 1054 (42S22): Unknown column 'post' in 'group statement'
     3 
     4 
     5 
     6 mysql>  select post from employee group by post;
     7 +-----------------------------------------+
     8 | post                                    |
     9 +-----------------------------------------+
    10 | operation                               |
    11 | sale                                    |
    12 | teacher                                 |
    13 | 老男孩驻沙河办事处外交大使              |
    14 +-----------------------------------------+
    15 rows in set (0.00 sec)
    分组



















  • 相关阅读:
    Go数据类型之复合数据类型--数组
    linux系统编程面试题
    各种距离 欧式距离、曼哈顿距离、切比雪夫距离、闵可夫斯基距离、标准欧氏距离、马氏距离、余弦距离、汉明距离、杰拉德距离、相关距离、信息熵
    欧氏距离和曼哈顿距离
    SpringCloud-Zuul源码分析和路由改造
    TiDB注意事项
    Littleproxy的使用
    HBase 架构与工作原理5
    HBase 架构与工作原理2
    HBase 架构与工作原理3
  • 原文地址:https://www.cnblogs.com/zhangqing979797/p/9795211.html
Copyright © 2011-2022 走看看