精华内容
下载资源
问答
  • 2017-10-11 11:17:39

    这个需求应该也比较常见,在不同的条件下创建不同的bean,具体场景很多,能看到这篇的肯定懂我的意思。

    倘若不了解spring4.X新加入的@Conditional注解的话,要实现不同条件创建不同的bean还是比较麻烦的,可能需要硬编码一些东西做if判断。那么现在有个@Conditional注解后,事情就简单多了。用法很简单,直接上代码。

    新建一个springboot项目,添加一个Configuration标注的类,我们通过不同的条件表达式来创建bean。

    package com.tianyalei.condition;
    
    import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Conditional;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * Created by wuweifeng on 2017/10/11.
     */
    @Configuration
    public class Config {
    
        @Conditional(MyCondition.class)
        @Bean
        public String condition() {
            System.err.println("自定义的condition的match方法返回值为true时,才会进入该方法创建bean");
            return "";
        }
    
        /**
         * 该Abc class位于类路径上时
         */
        @ConditionalOnClass(Abc.class)
        @Bean
        public String abc() {
            System.err.println("ConditionalOnClass true");
            return "";
        }
    
    //    @ConditionalOnClass(Abc.class)
    //    @Bean
    //    public Abc newAbc() {
    //        System.err.println("ConditionalOnClass true");
    //        return new Abc();
    //    }
    
        /**
         * 存在Abc类的实例时
         */
        @ConditionalOnBean(Abc.class)
        @Bean
        public String bean() {
            System.err.println("ConditionalOnBean is exist");
            return "";
        }
    
        @ConditionalOnMissingBean(Abc.class)
        @Bean
        public String missBean() {
            System.err.println("ConditionalOnBean is missing");
            return "";
        }
    
        /**
         * 表达式为true时
         */
        @ConditionalOnExpression(value = "true")
        @Bean
        public String expresssion() {
            System.err.println("expresssion is true");
            return "";
        }
    
        /**
         * 配置文件属性是否为true
         */
        @ConditionalOnProperty(
                value = {"abc.property"},
                matchIfMissing = false)
        @Bean
        public String property() {
            System.err.println("property is true");
            return "";
        }
    }
    

    这里面有个空类Abc.class,你可以就创建个叫Abc的类,里面是空的就行。

    import org.springframework.context.annotation.Condition;
    import org.springframework.context.annotation.ConditionContext;
    import org.springframework.core.type.AnnotatedTypeMetadata;
    
    /**
     * Created by wuweifeng on 2017/10/11.
     */
    public class MyCondition implements Condition {
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
            //判断当前系统是Mac,Windows,Linux
            return conditionContext.getEnvironment().getProperty("os.name").contains("Mac");
        }
    }


    @Conditional(MyCondition.class)
    这句代码可以标注在类上面,表示该类下面的所有@Bean都会启用配置
    也可以标注在方法上面,只是对该方法启用配置


    除了自己自定义Condition之外,Spring还提供了很多Condition给我们用
    @ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)
    @ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)
    @ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean)
    @ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)
    @ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)
    @ConditionalOnNotWebApplication(不是web应用)

    以上是一些常用的注解,其实就是条件判断,如果为true了就创建Bean,为false就不创建,就这么简单。

    这些注解里的条件可以是多个,也可以赋默认值,也可以标注在类上,如果标注在类上,则对类里的所有@Bean方法都生效。

    其中@ConditionalOnProperty是指在application.yml里配置的属性是否为true,其他的几个都是对class的判断。

    我在配置里加上abc.property = true这个配置就可以测试上面的代码了。

    然后再来一个对类进行多个条件标注的例子:

    package com.tianyalei.condition;
    
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * Created by wuweifeng on 2017/10/11.
     */
    @Configuration
    @ConditionalOnProperty(
            value = {"abc.property"},
            matchIfMissing = false
    )
    @ConditionalOnClass(Abc.class)
    public class Multi {
        @Bean
        @ConditionalOnMissingBean({Abc.class})
        public String check() {
            System.err.println("multi check");
            return "check";
        }
    }
    
    OK,代码很简单,运行看看结果

    可能上面的那些你用的地方不常见,那我来举一个我正在使用的例子。我的应用是基于SpringCloud的,在线上部署时有eureka来做注册中心,而在本地环境下,我的应用是单机的,不需要eureka,但是代码里已经引入了eureka了,每次启动就会自动去连接eureka,然后控制台就开始报错。虽然不影响功能,但是看着一直不停的报错也是不顺眼。

    那么我就可以使用Condition注解来解决它。

    /**
     * @author wuweifeng wrote on 2017/11/25.
     * 根据部署环境动态决定是否启用eureka
     */
    @Component
    @ConditionalOnProperty(value = "open.eureka")
    @EnableDiscoveryClient
    public class JudgeEnableDiscoveryClient {
    }
    
    我把EnableDiscoveryClient这个注解单独放个类里,里面什么也不写,条件就是application.yml里配置的open.eureka
    如果我只想让线上的环境开启eureka,那么我就在application-prod.yml里配上open.eureka=true,其他的yml什么也不写就行了。这样本地启动时就相当于没有开启EnableDiscoveryClient。


    使用场景还是蛮多的,具体的看情况,但是需要记住有这么个注解,以便不时之需。





    更多相关内容
  • MySQL创建表和约束条件(四)

    千次阅读 多人点赞 2019-11-15 14:09:16
    古语有云: 万恶淫为首,百善孝为先。 我们后辈当自勉。 上一章简单介绍了 MySQL的数据类型(三),如果没有看过,请观看上一章 ...在创建表时,一定要在 database 里面进行创建, 既先使用 use 数据库名来选择...

    古语有云: 万恶淫为首,百善孝为先。 我们后辈当自勉。

    上一章简单介绍了 MySQL的数据类型(三),如果没有看过,请观看上一章

    一. 创建表

    上一章时,我们学习了 MySQL的数据类型, 就像Java 知道了 int,string 之后,就该学习类了, 现在,我们知道了数据类型,就该去学习表 Table了。

    在创建表时,一定要在 database 里面进行创建, 既先使用 use 数据库名来选择数据库, 再进行创建, 否则会提示 “No database selected” 的错误。

    创建表语句:

    		create table 表名(
    				列名1  数据类型  [列级别约束条件] [默认值],
    				列名2  数据类型  [列级别约束条件] [默认值],
    				......
    				列名n  数据类型  [列级别约束条件] [默认值],
    
    				[表级别约束条件]
    	
    		);
    

    其中 表名,列名1,列名2,列名n 就像Java 里面的变量一样,不能用关键字。 但与Java 不同的是, MySQL不区分大小写。 这一点,与HTML一样。

    一.一 查询该数据库下所有的表

    使用 show tables; 命令进行查询该数据库下的表。

    要先使用 use 数据 库名先选择数据库。 使用 yuejl数据库。

    有图片。

    查询所具有的表 show tables;

    有图片。

    这个表 t 是上一章在测试timestamp时创建的。

    一.二 创建一个简单的表 temp1

    创建一个简单的表, 里面只有一个字段 name, 类型是 varchar 类型, 长度是10.

    不要忘记 先 use 数据库名 来选择数据库。

    按照上面的创建表的语句进行创建:

     create table t2(
        name varchar(10)
       );
    

    有图片

    一.三 创建一个复杂的表 temp2

    创建一个复杂的表,与老蝴蝶常用的User.java 类一样,具有 id(int类型),name(varchar类型),sex(varchar类型),age(int类型),description(varchar类型) 五个字段。

    (创建时,要按照一定的层次进行书写,这样显的帅气。)

    create table t3(
         id int(11),
         name varchar(20),
        sex varchar(10),
         age int(3),
        description varchar(100)
       );
    

    有图片。

    一.四 展示所有的表

    用 show tables; 命令进行展示

    有图片。

    刚才的两个表 t2,t3 放置到这里面了。

    一.五 创建表时常见错误

    1 . 表名已经存在, 会报 表已经存在的错误
    有图片。

    2 . 列名最后一个 写添加了 , 号, 报错。

    有图片

    3 . 列与列之间,没有加 ,号报错

    有图片。

    要想 用sql语句创建表时,不报错,只有多练,多写。 前期学习者建议用sql去创建表,不建议使用数据库连接工具去创建表。

    二. 约束条件

    二.一 约束条件的由来

    我们在创建表的命令时, 用这么两个东西, 列级别约束条件和表级别约束条件。 约束条件是干什么用的呢? 用什么作用效果呢?

    数据库是存储,管理和操作数据的的仓库, 而表是真正存储数据的, 更准确的说,所有的数据都是放置在表里面的。 我们希望在存储数据之前,就希望能对数据进行一下验证, 就像 Web网站里面的前端验证和后端数据验证, 登录过滤器,权限过滤器一样, 使正确的数据才能够正常的插入,使错误的数据不能够正常插入,提示报错, 使表有个自我检查的功能。 数据库设计者们发现有这么几个常用的小验证,小约束:

    1 . 这个列上面的属性值 必须要存在。 这就是非空约束

    2 . 这个列上面的属性值必须要唯一,不能重复。 这就是唯一约束

    3 . 这个列或者这两个列可以唯一确定这一行,这一行能够通过这个列或者这两列与 其他的行区别开来。 这就是主键约束

    4 . 这个列上的值如果没有手动填充值,数据库表默认提供一下,如性别,没有填写,默认是男。 这就是默认值约束

    5 . 这个列的值是往上增加的,并且与它上一行的值有关系。 如 num次数, 它上一行的值是1, 它这一行的值是2, 它下一行的值是 3 ,下下一行的值是4。 希望这个1,2,3,4 是表自己递增的, 并不是手动插入的。 这就是自增约束。

    6 . 这个列上的值,一定来源于其他表中的值,并不是凭空出现的。发生在两个表之间。 如员工的部门属性的值,一定来源于部门表中的值。 这就是外键约束

    7 . 这个列上的值,只能是规定好的值,不能是其他以外的值。 如性别, 只能是男或者女。 手动添加其他值,包括 保密,未知,太监,人妖 之类的,都不能正确插入。 这叫做检查约束(MySQL数据库中不起作用)。

    其中,1,2,3,4,5,7 是发生在一个表内的约束, 而6是发生在两个表之间的约束。

    上面专业的说法,叫做 数据完整性。

    数据完整性分为三个部分:

    1 . 实体完整性

    2 . 域完整性

    3 . 引用完整性

    实体完整性这项规则要求每个数据表都必须有主键,而作为主键的所有字段,其属性必须是独一及非空值。

    限制字段中的数据必须乎合预设的数据类型。

    参照的完整性不允许关系中有不存在的实体引用。

    使用约束,可以很方便的保证插入数据的正确性,避免逻辑错误数据的出现,但不能保证业务错误数据的出现。 业务错误数据,需要通过业务流程控制来避免。

    二.二 约束条件的分类

    • 主键约束 Primary Key (简称 PK)
    • 非空约束 Not Null
    • 唯一约束 Unique
    • 外键约束 Foreign Key (简称 FK)
    • 默认约束 Default
    • 检查约束 Check(MySQL中不起作用)
    • 自增约束 AUTO_INCREMENT

    下面,老蝴蝶分别对其进行详细的讲解。

    三. 主键约束 Primary Key

    主键约束 分为两种, 一种是 单字段主键, 另外一种是多字段联合主键。

    三.一 单字段主键

    1 . 在创建字段时, 指定 列级别约束条件

     			列名  数据类型   Primary Key  [默认值]
    

    如:

    create table pk4(
         id int(11) primary key,
       	 name varchar(10)
        );
    

    有图片。

    2 . 在创建完所有列之后, 指定 表级别约束条件

    	[constraint 约束名] primary key (列名)
    

    其中, 约束名通常命名为: PK_表名。 常常省略 constraint 约束名, 直接用 primary key (列名)

     create table pk5(
        id int(11),
        name varchar(10),
        primary key (id)
       );
    

    有图片。

    三.二 多字段联合主键

    多字段联合主键只能使用 表级别约束条件

    	[constraint 约束名]  primary key (列名1,列名2)
    

    也常常省略 constraint 约束名。

    如 创建学生与课程 的成绩表。 其中,学生编号和课程编号是联合 主键。

     create table pk6(
        stuId int(11),  -- 学生编号
         courseId int(11), -- 课程编号
         score double(5,2),
        primary key (stuId,courseId)
      );
    

    在这里插入图片描述

    三.三 演示主键约束

    用 pk4 表做例子吧。 (关于数据的插入,后面章节会详细讲解)

    1 . 先插入一个编号为 1,名称为两个蝴蝶飞 的记录。

    insert into pk4(id,name) values(1,'两个蝴蝶飞');
    

    有图片。

    2 . 再插入一个编号为1,名称为老蝴蝶的记录。

    insert into pk4(id,name) values(1,'老蝴蝶');
    

    有图片。

    编号 id是重复的,不能重复性插入, 会报错。

    四. 非空约束 not null

    只能指定一个单字段为非空约束,没有联合字段做为非空约束。 可以让多个字段都为非空约束。

    	列名  数据类型  not null [默认值]
    

    四.一 创建非空约束

    活学活用,将前面的主键约束再练习一遍。

      create table n7(
        id int(11) primary key,
        name varchar(20) not null
       );
    


    注意,只有这一种写法。 没有 not null (name) 作为表级别约束条件的, 只能放在列级别约束。

    四.二 演示非空约束

    1 . name有值, 正常插入

    insert into n7(id,name) values(1,'两个蝴蝶飞');
    

    有图片。

    2 . name 没有值 或者插入值为 null

    insert into n7(id) values(2);
    

    有图片。

    insert into n7(id,name) values(2,null);
    

    有图片。

    五. 唯一约束 Unique

    可以为空,MySQL也允许其他的列也可以为null.这一点不像SQL Server 数据库。

    五.一 创建列约束条件的 唯一约束

    命令:

    	列名  数据类型  unique 
    

    创建语句:

    create table u8(
        id int(11) primary key,
        name varchar(20) unique
    );
    

    有图片。

    五.二 创建表约束条件的 唯一约束

    也可以创建表级别的唯一约束

    [constraint 唯一约束名] unique (列名)
    

    创建语句:

    	create table u9(
        	 id int(11) primary key,
       		 name varchar(20),
        	unique (name)
        );
    

    在这里插入图片描述

    五.二 演示唯一约束

    以 u8 表为例。

    1 .先插入一条数据, id为1, name为两个蝴蝶飞

    insert into u8(id,name) values(1,'两个蝴蝶飞');
    

    有图片。

    2 . 再创造一条数据, id为3, name仍然为两个蝴蝶飞。 name 重复了。

    insert into u8(id,name) values(3,'两个蝴蝶飞');
    

    在这里插入图片描述

    3 . 但可以插入一条空的值, 如name 的值插入为 null

    insert into u8(id,name) values(4,null);
    

    有图片。

    但 null的值,可以有多个。 再插入 id为5,名称仍然为null 的。

    insert into u8(id,name) values(5,null);
    

    有图片。

    查询一下: select * from u8;

    有图片。

    说明,唯一约束可以插入多个 null的值,并不是唯一的null值。

    六. 默认约束 default

    命令:

    	列名  数据类型  default 默认值
    

    默认约束是,如果不填入这个属性值,就用默认值代替,如果填入了,哪怕填入的值是空,也用填入的值。

    六.一 创建默认约束

    令 性别默认是 男.

    create table d10(
        id int(11) primary key,
         name varchar(20),
         sex varchar(10) default '男'
       );
    

    在这里插入图片描述

    六.二 演示默认约束

    1 . 插入一条正常的数据, 性别是男。

     insert into d10(id,name,sex) values(1,'两个蝴蝶飞','男');
    

    有图片。

    2 . 插入一条正常的数据,性别是女.

     insert into d10(id,name,sex) values(2,'精灵妹','女');
    

    有图片。

    3 . 插入一条数据,不指定性别。

     insert into d10(id,name) values(3,'老蝴蝶');
    

    有图片。

    4 . 插入一条数据,性别为null 值。

    insert into d10(id,name,sex) values(4,'岳泽霖',null);
    

    在这里插入图片描述

    5 . 查询刚才的数据 select * from d10;

    有图片。

    七 检查约束 check (MySQL数据库被分析,但是会被忽略)

    七.一 MySQL 创建列级别约束 (不起作用)

    命令:

    	列名  数据类型 check (sql表达式)
    

    可以放置值列表, 表示插入的值必须在值列表里面。 也可以放置sql表达式,表示插入的值必须符合sql表达式

    1 . 创建和演示 性别只能是男或者女

    create table d11(
         id int(11) primary key,
         name varchar(20),
         sex varchar(10) check(sex in ('男','女'))
       );
    

    有图片。

    插入性别是男 数据。

    insert into d11(id,name,sex) values(1,'两个蝴蝶飞','男');
    

    有图片

    插入性别是保密的数据

    insert into d11(id,name,sex) values(2,'老蝴蝶','保密');
    

    有图片。

    发现,竟然可以插入, 检查约束并没有起作用。

    去谷歌一下, 里面提到了 MySQL 检查约束不起作用的问题。

    CHECK
    The CHECK clause is parsed but ignored by all storage engines. See Section 1.8.2.3, “Foreign Key Differences”

    但MySQL 可以使用其他的方式来代替, 如enum 枚举类型,或者触发器。 但老蝴蝶这儿不讲解。

    为了系统的连贯性,另外检查约束 check 确实我也不太懂,所以决定用 Oracle 数据库来讲解。 Oracle 数据库支持 检查约束 Check.

    以下的内容,都是用Oracle 进行创建的。 plsql工具。

    七.二 Oracle 创建列级别约束 (起作用)

    1 . 创建和演示性别只能是男或者女

    创建表:

     create table t1(
           id int primary key,
           name varchar2(20),
           sex varchar(10) check(sex in ('男','女')) -- 也可以用  check(sex='男' or sex='女')
         );
    

    插入数据:

    	insert into t1(id,name,sex) values(1,'两个蝴蝶飞','男'); -- 正常插入
         insert into t1(id,name,sex) values(2,'老蝴蝶','保密'); -- 会提示错误
    

    有图片。

    检查约束好使。

    2 . 创建和演示 年龄必须大于18岁 小于60

    创建表:

    create table t2(
               id int primary key,
               name varchar2(20),
               age int check(age>=18 and age<=60)
          );
    

    插入数据:

    	 insert into t2(id,name,age) values(1,'两个蝴蝶飞',20); -- 正常插入
          
          insert into t2(id,name,age) values(2,'岳泽霖',16); -- 会提示错误
          
          insert into t2(id,name,age) values(3,'老蝴蝶',62); --会提示错误
    

    有图片。

    检查约束好使。

    七.三 Oracle 创建表级别约束 (起作用)

    与列级别约束 基本类似 。

    创建表:

     create table t3(
               id int primary key,
               name varchar2(20),
               sex varchar(10),
               check(sex in ('男','女')) -- 也可以用  check(sex='男' or sex='女')
           );
    

    插入数据:

     	  insert into t3(id,name,sex) values(1,'两个蝴蝶飞','男'); -- 正常插入
          insert into t3(id,name,sex) values(2,'老蝴蝶','保密'); -- 会提示错误
    

    年龄的那个类似:

    创建表:

    create table t4(
               id int primary key,
               name varchar2(20),
               age int,
               check(age>=18 and age<=60)
          );
    

    插入数据:

    	 insert into t4(id,name,age) values(1,'两个蝴蝶飞',20); -- 正常插入
          
          insert into t4(id,name,age) values(2,'岳泽霖',16); -- 会提示错误
          
          insert into t4(id,name,age) values(3,'老蝴蝶',62); --会提示错误
    

    八. 自增约束 AUTO_INCREMENT

    自增约束,只能用于整数类型,默认开始值是1,每次增加1,用于数据库生成不重复的主键。(但在高并发环境下,这种方式生成的主键不一定正确)

    	列名  数据类型  AUTO_INCREMENT
    

    八.一 创建自增约束

     create table a12(
         id int(11) primary key auto_increment,
         name varchar(20)
       );
    

    有图片

    八.二 演示自增约束

    1 . 插入第一个数据,不插入id 的值

    insert into a12(name) values('两个蝴蝶飞');
    

    有图片。

    2 . 插入第二个数据,不插入id的值

    insert into a12(name) values('老蝴蝶');
    

    有图片

    3 . 查询数据

    有图片。

    九. 外键约束 Foreign Key

    外键约束不像上面的那些约束,是发生在一个表之间的, 外键约束 Foreign Key 是发生在两个表之间的, 这两个表,一个叫主表(父表), 一个叫从表(子表)。 其中,在子表里面定义外键约束, 引用主表中的主键。 外键可以是一列也可以是多列, 但一般都是一列。 一个表里面可以给多个列都定义外键。 就像 员工的课程成绩表一样, 员工编号是员工表的外键, 课程编号是课程表的外键。 外键是参数完整性, 里面的值可以为null值, 但如果不为null值, 则必须是主表主键的某个值。 注意,子表的外键必须引用的是主表的主键,主表的 unqiue 属性都不行,必须是主键。

    九.一 创建外键约束 Foreign Key

    命令:

    	[constraint 外键约束名] foreign key (列名)  references 主表名(主键列名)
    

    是表级别的约束条件。

    建议是用户自己手动添加外键约束名, constraint 外键约束名 不省略。

    常见的部门和员工表。 即员工表里面的部门编号一定是部门表的主键。

    1 . 创建部门表 dept

    create table dept(
        id int(11) primary key,
        name varchar(20)
        );
    

    有图片。

    2 .创建员工表 user

    create table user(
        id int(11) primary key,
         name varchar(20),
         description varchar(100),
         deptId int(11),
         constraint fk_user_deptId foreign key(deptId) references dept(id)
        );
    

    有图片。

    创建外键成功。

    九.二 外键约束演示

    1 . 先往部门表里面插入两条数据

    insert into dept(id,name) values(1,'信息部'),(2,'开发部');
    

    有图片。

    2 .往user 表里面插入 部门编号为 1的数据, 是正确的数据

     insert into user(id,name,description,deptId) values(1,'两个蝴蝶飞','一个快乐的程序员',1);
    

    有图片。

    3 . 往user 表里面插入部门编号为3的数据。 没有这个部门,是错误的数据。

     insert into user(id,name,description,deptId) values(2,'老蝴蝶','一个快乐的程序员',3);
    

    有图片。

    报外键约束的错误。 子表中插入父表中主键没有的属性值会报错。

    4 . 删除父表中的数据, 即删除父表中 部门编号为1的那条数据

    delete from dept where id=1;
    

    有图片。

    因为父表中的数据在子表中被引用了,所以是无法直接删除的, 可以先将子表中引用的那条数据删除,或者将deptId 更新成null, 再删除父表中的数据才可以。

    update user set deptId=null where id=1;
    
    delete from dept where id=1;
    

    有图片。

    十. 查看表结构

    十.一 describe 表名/desc 表名 查看

    describe user;
    

    有图片。

    也可以用简写的形式 : desc 表名

    desc user;
    

    有图片。

    侧重点是各个列的信息。

    其中:

    1. filed      指的是列名
    2. type     指的是列名的数据类型
    3. null     表示该列是否可以存储null值
    4. key     是否已经编制索引。 PRI 表示主键,UNI 表示 unique 索引的一部分, MUL 表示可允许出现多次
    5. Default      是否有默认值
    6. extra:     该列的附加信息, 如AUTO_INCREMENT

    十.一 show create table 表名 查看

    show create table user\G	
    

    有图片。

    会将创建 table 时的sql 语句打印出来, 还包括引擎和编码格式。

    侧重点是sql 创建语句。

    加\G 不加 \G 都可以, 加\G 可以使显示结果更加直观。



    谢谢!!!
    展开全文
  • 几乎所有的小伙伴都可以随口说几句关于创建索引的优缺点,也知道什么时候创建索引能够提高我们的查询性能,什么时候索引会更新,但是你有没有注意到,即使你设置了索引,有些时候索引他是不会生效的!这不仅考察了...

    几乎所有的小伙伴都可以随口说几句关于创建索引的优缺点,也知道什么时候创建索引能够提高我们的查询性能,什么时候索引会更新,但是你有没有注意到,即使你设置了索引,有些时候索引他是不会生效的!这不仅考察了大家对索引的了解程度,还要让大家在使用的时候能够正确的使用。以下介绍了一些可能会造成索引失效的特殊情况,希望大家在平时开发和面试的时候能够注意到!

    一、如何判断数据库索引是否生效

    首先在接着探讨之前,我们先说一下,如何判断数据库的索引是否生效!相信大家应该猜到了,就是explain!explain显示了MySQL如何使用索引来处理select语句以及连接表。他可以帮助选择更好的索引和写出更优化的查询语句。

    例如我们有一张表user,为name列创建索引name_index,如下所示:
    这里写图片描述
    使用explain分析语句如下:
    这里写图片描述
    可以看到,使用explain显示了很多列,各个关键字的含义如下:

    • table:顾名思义,显示这一行的数据是关于哪张表的;

    • type:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为:const、eq_reg、ref、range、indexhe和ALL;

    • possible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从where语句中选择一个合适的语句;

    • key: 实际使用的索引。如果为NULL,则没有使用索引。很少的情况下,MySQL会选择优化不足的索引。这种情况下,可以在Select语句中使用USE INDEX(indexname)来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MySQL忽略索引;

    • key_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好;

    • ref:显示索引的哪一列被使用了,如果可能的话,是一个常数;

    • rows:MySQL认为必须检查的用来返回请求数据的行数;

    • Extra:关于MySQL如何解析查询的额外信息。

    具体的各个列所能表示的值以及含义可以参考MySQL官方文档介绍,地址:https://dev.mysql.com/doc/refman/5.7/en/explain-output.html

    二、哪些场景会造成索引生效

    1、应尽量避免在 where 子句中使用 != 或 <> 操作符

    否则引擎将放弃使用索引而进行全表扫描;

    这里写图片描述

    2、尽量避免在 where 子句中使用 or 来连接条件

    否则将导致引擎放弃使用索引而进行全表扫描,即使其中有条件带索引也不会使用,这也是为什么尽量少用 or 的原因;

    这里写图片描述

    3、对于多列索引,不是使用的第一部分,则不会使用索引;

    这句话某种程度上有问题,详细请参考:本文《第三节:最左前缀原则》

    4、如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不会使用索引;

    这里写图片描述

    5、like的模糊查询以 % 开头,索引失效;

    这里写图片描述
    但是非前导模糊查询则可以:

    select * from user where name like xuliu%';
    

    6、应尽量避免在 where 子句中对字段进行表达式操作

    这将导致引擎放弃使用索引而进行全表扫描;

    如:

    select id from t where num/2 = 100 
    

    应改为:

    select id from t where num = 100*2;
    

    7、应尽量避免在 where 子句中对字段进行函数操作

    这将导致引擎放弃使用索引而进行全表扫描;

    例如:

    select id from t where substring(name,1,3) = 'abc' – name;
    

    以abc开头的,应改成:

    select id from t where name like ‘abc%’ 
    

    例如:

    select id from t where datediff(day, createdate, '2005-11-30') = 0 – '2005-11-30';
    

    应改为:

    select id from t where createdate >= '2005-11-30' and createdate < '2005-12-1';
    

    8、不要在 where 子句中的 “=” 左边进行函数、算术运算或其他表达式运算

    否则系统将可能无法正确使用索引;

    9、如果MySQL估计使用全表扫描要比使用索引快,则不使用索引;

    10、不适合键值较少的列(重复数据较多的列)

    假如索引列TYPE有5个键值,如果有1万条数据,那么 WHERE TYPE = 1将访问表中的2000个数据块。再加上访问索引块,一共要访问大于200个的数据块。如果全表扫描,假设10条数据一个数据块,那么只需访问1000个数据块,既然全表扫描访问的数据块少一些,肯定就不会利用索引了。

    三、最左前缀原则

    最左前缀原则:顾名思义是最左优先,以最左边的为起点任何连续的索引都能匹配上。

    (1)如果第一个字段是范围查询需要单独建一个索引;

    (2)在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边;

    当创建(a,b,c)复合索引时,想要索引生效的话,只能使用 a和ab、ac和abc三种组合!

    实例:以下是常见的几个查询:

    mysql>SELECT `a`,`b`,`c` FROM A WHERE `a`='a1' ; //索引生效
    mysql>SELECT `a`,`b`,`c` FROM A WHERE `b`='b2' AND `c`='c2'; //索引失效
    mysql>SELECT `a`,`b`,`c` FROM A WHERE `a`='a3' AND `c`='c3'; //索引生效,实际上值使用了索引a
    

    扩展:想要索引最大化的使用需要至少建几个索引?

    答:需要建立复合索引:bc

    3.1、三个字段联合索引测试:

    在这里插入图片描述
    联合索引的顺序为:sex,age,name

    SELECT * FROM user where sex="3"; #使用索引
    SELECT * FROM user where age="4"; #未使用索引
    SELECT * FROM user where name="2"; #未使用索引
    SELECT * FROM user where sex="2" and age="3"; #使用索引
    SELECT * FROM user where sex="2" and age="3" and name="4"; #使用索引
    SELECT * FROM user where age="3" and name="4";  #未使用索引
    SELECT * FROM user where sex="2" and name="4";  #使用索引
    
    #这个在3.2最后边解释,为什么
    explain SELECT * FROM index_demo.user where age="2" and sex="3"; #使用索引
    

    值得注意的是,where sex=“2” and name=“4” 这个相当于只有sex使用到了索引的,

    在这里插入图片描述
    和where sex=“2” and age=“3” and name="4"的区别:

    在这里插入图片描述

    3.2、如果索引字段有两个

    如果索引有两个字段:sex,age

    在这里插入图片描述

    explain SELECT * FROM index_demo.user where sex="3"; #使用索引
    explain SELECT * FROM index_demo.user where age="4"; #未使用索引
    explain SELECT * FROM index_demo.user where sex="2" and age="3"; #使用索引
    explain SELECT * FROM index_demo.user where age="3" and sex="4";  #使用索引
    

    在这里插入图片描述
    在这里插入图片描述
    where sex=“2” and age=“3”;和where sex=“2” and age=“3”;

    这两个都是用了索引的,这是mysql查询优化器,mysql查询优化器会判断纠正这条sql语句该以什么样的顺序执行效率最高,最后才生成真正的执行计划。所以,当然是我们能尽量的利用到索引时的查询顺序效率最高咯,所以mysql查询优化器会最终以这种顺序进行查询执行。

    然后回到刚才的3.1中三个索引的时候:sex,age,name

    explain SELECT * FROM index_demo.user where age="2" and sex="3"; #使用索引
    

    这条语句竟然使用索引了
    在这里插入图片描述
    可以看出他是使用索引了,因为对于三个索引的时候,只要是前两个,存在,不论顺序是什么都是会使用索引的,这里主要是mysql查询优化器起的作用了;


    参考文章:

    1、http://blog.csdn.net/qq_33774822/article/details/61197420

    在这里插入图片描述

    【视频福利】2T免费学习视频,搜索或扫描上述二维码关注微信公众号:Java后端技术(ID: JavaITWork)回复:1024,即可免费获取!内含SSM、Spring全家桶、微服务、MySQL、MyCat、集群、分布式、中间件、Linux、网络、多线程,Jenkins、Nexus、Docker、ELK等等免费学习视频,持续更新!

    展开全文
  • 一、创建DNS服务器: 1、打开“服务器管理器”,点击“添加角色和功能”: 2、点击下一步: 3、点击下一步: 4、点击下一步: 5、勾选“DNS服务器”: 6、点击下一步: 7、点击下一步: 8、...

    一、创建DNS服务器:

    1、打开“服务器管理器”,点击“添加角色和功能”:

     2、点击下一步:

    3、点击下一步:

    4、点击下一步:

     

     5、勾选“DNS服务器”:

    6、点击下一步:

    7、点击下一步:

    8、点击“安装”:

    9、安装过程中。。。

    10、安装完成:

    二、创建DNS正向查找区域:

    1、右键点击“正向查找区域”,选择“新建区域》...”:

    2、点击下一步:

    3、选择“主要区域”:

    4、输入域名称:

    5、点击下一步:

    6、点击下一步:

    7、点击完成:

    8、选择创建的区域,右键点击空白处,选择“新建主机(A)”,添加A记录:

    9、输入主机名和IP地址:

    10、A记录创建完成:

    11、打开命令提示符窗口,输入nslookup进入解析命令,输入 server 192.168.97.70 以本机解析如下:

    三、配置转发器

    1、右键点击主机名,选择“属性”:

    2、选择“转发器”选项卡,点击“编辑”:

    3、输入要转发的外网DNS地址,待验证成功,点击确定:

    4、添加如下:

    四、配置条件转发器

    1、右键点击“条件转发器”,选择“新建条件转发器...”:

    2、添加要转发的域名,并输入用来解析该域名的DNS服务器地址:

    3、添加成功:

    4、在另一个DNS服务器(192.168.97.72)上,在以上域名中添加A记录:web.zftest.com,

    5、在本地DNS服务器上用nslookup解析web.zftest.com,解析成功如下:

     

    展开全文
  • FLUENT创建周期性边界条件方法 -

    千次阅读 2020-12-23 21:17:38
    1. 指定计算域的Rotational Axis(Cell Zone Conditions中,设为Frame Motion),其中,rotation-axis origin设为0,0,0。... [yes]回车 然后FLUENT自动检测,如果没问题就报告periodic zone已经成功创建
  • Oracle如何创建条件索引

    千次阅读 2018-07-23 17:39:26
    首先讲述一个业务场景: 数据库商品表中有goods_id,goods_name,goods_price,status四个字段,goods_id是自增主键,status是状态,只有0,1两种可能,...首先创建表: -- Create table create table TB_GOODS ...
  • 我想创建一个新列,根据col1的index来选择col2的item, 例如: ``` index col1 col2 col3 1 [1,2] [apple, peer, oragne, banana] [apple,peer] 2 [2] [pancake, soda] [soda] ``` 请问应该如何操作?
  • 一、可以创建多个索引嘛? 可以创建多个索引的。...为此,到底在表中创建多少索引合适,就需要在这个更新速度与查询速度之间取得一个均衡点。 如对于一些数据仓库数据库系统,其主要用来进行查询。相...
  • 倘若不了解spring4.X新加入的@Conditional注解的话,要实现不同条件创建不同的bean还是比较麻烦的,可能需要硬编码一些东西做if判断。那么现在有个@Conditional注解后,事情就简单多了。用法很简单,直接上代码。 ...
  • 创建索引的条件和注意事项

    千次阅读 2016-09-21 12:16:14
    索引的理解和创建索引应该注意的条件
  • SQL Server 创建表及其约束条件

    万次阅读 多人点赞 2016-09-21 19:55:10
    创建数据库: CREATE DATABASE my_db; 2.创建表: CREATE TABLE Persons ( Id_P int, LastName varchar(255), FirstName varchar(255), Address varchar(255), City varchar(255) ) 数据...
  • 2.频繁作为查询条件的字段应该创建索引;3.查询中与其他表有关联的字段,例如外键关系;4.频繁更新的字段不适合创建索引,因为每次更新不单单是更新记录,还会更新索引,保存索引文件;5.where条件里用不到的字段,...
  • 2.频繁作为查询条件的字段应该创建索引; 3.查询中与其他表有关联的字段,例如外键关系; 4.频繁更新的字段不适合创建索引,因为每次更新不单单是更新记录,还会更新索引,保存索引文件; 5.where条件里用不到的...
  • PostgreSQL中创建条件的唯一索引

    千次阅读 2018-05-20 00:04:01
    下面例子印证了这种操作方式,得出的结论是,PG中的唯一索引是可以增加where条件过滤的:postgres=# create table t1 (id int); CREATE TABLE postgres=# create unique index idx_id_unq on t1(id) where id &...
  • Spring 创建条件化的bean(满足一定条件才会实例化该bean) 应用场景: 要求在特定的环境变量下创建该bean 希望某个bean被声明时候才会创建该bean 希望一个或者多个bean只有在应用的类路径下包含特定的数据库才创建 ...
  • 索引的介绍 索引在MySQL中也叫做“键”,它是一个特殊的文件,它保存着数据表里所有记录的位置信息,更通俗的来说,数据库索引好比是一本书前面的目录,能加快数据库的...主键列会自动创建索引 索引的创建: -- ...
  • 1.在非静态内部类条件下不能逐步创建对象,要先创建一个外部类对象,再创建内部类对象。 个人理解:因为类还没加载即还没分配内存,内部所有非静态成员都没分配内存,不可能直接创建一个非静态内部类对象。 2.在静态...
  • 只有当特定名称或者类型的Bean存在于BeanFactory时才创建某个Bean : @Configuration public class ConditionalOnBeanConfig { ... // 创建一个Bean,名称是 beanA,不需要满足什么前置条件, } ...
  • 主键自动创建索引频繁作为查询条件的字段应该创建索引查询中与其他表关联的字段,外键关系建立索引查询中排序字段,排序字段需要建立索引(大大提高排序的速度)频繁更新字段不适合创建索引where条件里用不到的字段...
  • 牛B程序员在“创建索引”时都会注意啥?

    万次阅读 多人点赞 2022-01-06 23:31:10
    当同事问我一些创建索引的经验时,作为一个久经沙场的老程序员,我建议尽量让每条SQL中的where、group by、order by条件都能最大化使用索引。并且...
  • @Conditional 可以根据条件创建不同的bean,   1 判断条件的类需要实现condition ,来设置判断的条件 2 自定义一个接口, 3 让不同的bean都实现这个接口,并返回不同的结果(是用于判断的条件) 4 在配置类中...
  • Java对象创建过程

    千次阅读 2022-03-28 17:54:13
    java对象创建过程、对象的组成、对象头、实例数据、对齐填充、对象创建方式、new关键字、Class类的newInstance方法、Constructor类的newInstance方法、Object类的clone方法、反序列化、无父类的对象创建、有父类的...
  • python创建数组

    千次阅读 2021-04-25 22:29:12
    NumPy模块提供了多种创建数组的方法,创建的数组类型也有多种多样,下面列举一下创建数组的方法: 1.使用array()函数创建数组 函数可基于序列型的对象(如列表、元组、集合等,还可以是一个已经创建好的数组) #...
  • WinForm 创建窗口句柄时出错

    千次阅读 2020-07-04 17:10:44
    问题的具体描述:根据条件设置移除和加入不同的控件,当前控件不满足条件时,将控件移除,然后加入新的控件。 代码如下: if (this.Panel.Controls.Contains(this.R_Parameter)) { this.Panel.Controls.Remove...
  • 数据库-创建数据库-创建数据表

    千次阅读 2022-03-20 17:22:53
    一.创建数据库
  • sql-哪些情况需要创建索引

    千次阅读 2018-08-21 23:16:01
    频繁作为查询条件的字段应该创建索引 查询中与其它表关联的字段,外键关联建立索引 频繁更新的字段不适合建索引(每次更新不单单是更新了记录还会更新索引) where条件中用不到的字段不建索引 单键/组合索引...
  • 结合使用注解@ConditionalOnMissingBean和@Bean,可以做到只有特定名称或者类型的Bean不存在于BeanFactory中时才创建某个Bean : @Configuration public class ConditionalOnMissingBeanConfig { @Bean ...
  • 结合使用注解@ConditionalOnMissingClass和@Bean,可以仅当某些类不存在于 classpath 上时候才创建某个Bean: @Configuration public class ConditionOnMissingClassConfig { @Bean @...
  • 我现在需要创建一个视图A,视图里面是三个视图BCD,根据一个页面传来的值判断不同的值查询不同的视图,这个值不少表中的字段。语法该怎么写?大神们帮帮忙啊!!
  • 1.频繁作为where条件语句查询字段 2.关联字段需要建立索引 3.排序字段可以建立索引 4.分组字段可以建立索引(因为分组前提是排序) 5.统计字段可以建立索引(如.count(),max()) 二、不适合建索引的情况: 1....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,726,539
精华内容 690,615
关键字:

创建公司需要什么条件