zoukankan      html  css  js  c++  java
  • MySQL学习笔记——〇二

    接着上一章的来讲,对上一章的知识点做一些补充

    唯一索引

    唯一索引,不允许具有索引值相同的行,从而禁止重复的索引或键值。系统在创建该索引时检查是否有重复的键值,并在每次使用 INSERT 或 UPDATE 语句添加数据时进行检查。 

    唯一索引的效果和主键有些相似,但是最大的区别就是唯一索引是支持数据为空(NULL)的。但是在插入数据的时候也是不能有相同的。

    使用场景:

    表格里第一列ID为主键,第二列name,第三列是身份证号。正常的情况身份证号是不能重复的,但是如果没有统计身份证号这一列也是可以为空的。

    CREATE TABLE t11 (
        ID INT auto_increment PRIMARY KEY,
        NAME CHAR ( 5 ),
    cardNumber CHAR ( 18 ),
    UNIQUE uq1 ( cardNumber ));

    同样,唯一索引也是可以用多列作为联合唯一索引。比如说一个表,统计了学生选修的各科成绩,第一列为表的主键ID,第二列为课程id(对应课程表的id外键),第三列为学生istudent_d,第四列就是成绩

    CREATE TABLE `score` (
      `sid` int(11) NOT NULL AUTO_INCREMENT,
      `student_id` int(11) NOT NULL,
      `course_id` int(11) NOT NULL,
      `num` int(11) NOT NULL,
      PRIMARY KEY (`sid`),
      KEY `fk_score_student` (`student_id`),
      KEY `fk_score_course` (`course_id`),
      CONSTRAINT `fk_score_course` FOREIGN KEY (`course_id`) REFERENCES `course` (`cid`),
      CONSTRAINT `fk_score_student` FOREIGN KEY (`student_id`) REFERENCES `student` (`sid`)
    ) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8;

    使用唯一索引,可以提高数据检索时的效率

    外键的变种

     我们在前一章已经点到了外键的特点和,使用,普通的外键是个一对多的使用环境。现在我们在看一看几种外键的变种使用环境

    一对多

    一对多就是最常见的使用环境,

    上面的表就是最常见的一对多的使用场景(上面的红箭头应该反过来,一对多)

     看看怎么创建两个表

    CREATE TABLE Department( Did int PRIMARY KEY auto_increment,
    Dname varchar(32));
    
    CREATE TABLE Userinfo(Uid int PRIMARY KEY auto_increment,
        Name char(10),
        department_id int,
        CONSTRAINT fk_user_depart FOREIGN KEY (department_id) REFERENCES Department(Did));

    一对一

    还有一种情况是一对一,比方财务的报表,一个表是员工信息,另一个表是员工的工资账户,这里要求每个员工只能有一个账户,这两个表之间的外键就是个一对一的关系

    因为每个账户和员工都是一一对应的关系,这时候在设置外键的时候就把user_id设置成唯一索引,代码如下

    CREATE table Userinfo(Uid int PRIMARY KEY auto_increment,
    Name varchar(32));
    
    CREATE table Accountinfo(Aid int PRIMARY KEY auto_increment,
    account char(20),
    user_Id int,
    UNIQUE uq1(user_Id),
    CONSTRAINT fk_account_user FOREIGN KEY (user_Id) REFERENCES Userinfo(Uid));

    再举个例子,我们做一个用户的数据库,包含id,用户名,用户等级,然后某个等级以上的可以登录,保存登录密码,如下图

     因为不是所有的员工都有登录权限,所以这个表在存起来就比较浪费资源。我们比较常用的就是把密码提出来放在另外一张表上

     

    userid和id是一对一的关系,userid也是不能重复的。这个思路就能比较好管理和节省资源。代码就不放了,跟上面那个一对一的差不多。

    多对多

    还有一种情况是多对多,还是用个例子来说明,比方 有个婚恋网站的用户表,两个表分别记录了用户信息和约会的记录(userinfo其实可以根据用户性别分两个表)

     并且这种情形是可以在record里有重复的记录的(每一次约会都可以生成新的一次记录),创建方法

    create table userinfo(uid int auto_increment primary key,
    name char(10),
    gender ENUM('',''));
    
    create table record(id int auto_increment primary key,
    m_id int,
    f_id int,
    CONSTRAINT fk_account_user1 FOREIGN KEY (m_id) REFERENCES userinfo(uid),
    CONSTRAINT fk_account_user2 FOREIGN KEY (f_id) REFERENCES userinfo(uid)
    )

    还有一种情形,一个公司,有几台服务器,根据个人能力每个人用几台服务器,大概就是下面这个图的示意

     我们可以在拿到hostid以后的字符串获取到对应的主机名。但是还有一个需求,比方我们想查一下c1这台机子有几个人在用,上面的方法就比较不方便了。所以一般在这种两个表互相占对方多组数据的时候(多对多)我们就在创建一个表

     其实上面那个多对多的也可以分成这样的。但是这个user_info表有个特点,就是除了id作为表的主键外,user_id和host_id还可以作为联合唯一索引(因为一个user对一个主机的状态只能出现一次,再出现的时候就是数据异常了)。在实际使用过程中是否使用联合唯一,主要看业务逻辑。

    MySQL数据操作补充

    我们在前一章讲了MySQL的数据基本操作,这里做一些补充

    在添加数据的hi好可以用多个数据,同时用逗号分隔

    insert into t1(id,name) values(1,'aa'),(2,'bb'),(3,'cc')

    区间取值

    这个区间是包括m和n的闭区间

    select * from tb where id between(m,n);

    多条件并行取值in

    select * from tb where id in(1,3,5);
    取id为1,3,5 的值的数据

    通配符(like)

    通配符常用的是多字符%和单字符_,

    select * from tb where name like 'a%';
    select * from tb where name like 'a_';

    排序order by

    升序asc 和降序desc

    select * from tb order by id desc;

    限制limit

    显示那条数据

    select * from tb limit 10;显示前10条数据
    select * from tb limit m,n;显示从m开始取n条数据

    MySQL里不支持直接从后面去多少条数据,需要先倒序排列在取数

    select * from tb order by id desc limit 10 取后10个id的数据

    分组 group by

    可以根据相同的数据分组,比方下面的数据表

     我们想统计不同部门的员工数

    select count(Name) from Userinfo group by department_id

    这里的count是聚合函数,常用的max,min,sum,avg等等。

    分组后的筛选

    比方我们要找出部门员工大于2,这时候的筛选就不能用where了,好用having

    select Name from Userinfo group by department_id having count(id)>2

    总之:where后不能加聚合函数。

    连表操作

    连表操作是非常常用的操作。一般用来将多个表通过外键来联合显示内容(不一定非要是外键,不过一般都是用在外键的环境下)

    join连表

    还是那个一对多的外键

    我们需要在结论里直接显示出来每个人的工作部门,这时候就需要用连表了

    select * from userinfo left join department on department_id = Did

    这里用的是left join,当然还有right join 有比较大的区别的

     看一下上面的数据,用户表里是没有Did是5的,

    select * from userinfo left join department on department_id = Did

     用right join的是这样的

     所以,就是用left时,join左边的表会完全显示出来,而用right时,join右边的表的数据会完全显示出来(没有对应值的都是NULL)

    也就是说,A left join B 和 B right join A的效果是完全一致的。

    还有一种连表的方法是inner join 是自动去除空的数据。

    union连表

    和join连表左右连表的方式不同,union是把两个表(数据类型可以不同,但列数必须一致)竖着连在一起。列名是按照union前面select的数据的列名起的。

    union

    普通的union具有去重的功能,当两行数据完全一样的时候,进行union以后就会把相同的删除。下面的表格进行union

    select * from t1
    union
    select * from t2;

     但是如果对t1直接union t1,

    select * from t1
    union
    select * from t1;

    那么输出的表格和t1是一样的,因为他会去重。

    union all

    还有一种是不进行自动去重的用法,就是union all

    select * from t1
    union all
    select * from t2;

    输出就是把t1 直接拼接到 t1后面。

    笛卡尔积

     在数学中,笛卡尔乘积是指两个集合XY的笛卡尓积(Cartesian product),又称直积,表示为X × Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员,

    而在sql内,也有一种用法涉及到笛卡尔积,我们这里只先提一下概念,至于怎么用,后面会简单的提一下。

     上面的过程就是下面的代码运行结果

    select * from t1,t2

    至于具体的使用环境我们在后面的案例中会提到,这里就不再细讲了。

  • 相关阅读:
    远程执行文件包含
    MSSQL2008 部署及开启远程连接
    schtasks 命令使用
    提权
    一个简单的Hibernate工具类HibernateUtil
    StandardServiceRegistryBuilder
    hibernate配置文件
    Hibernate入门
    mysql5.7.14安装与配置
    路漫漫兮其修远长,吾将上下而求索
  • 原文地址:https://www.cnblogs.com/yinsedeyinse/p/12249729.html
Copyright © 2011-2022 走看看