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

    一.初始mysql语句

    操作文件夹

      增

    create  database db1 charset utf8

      查

    #查看当前创建的数据库
    show create database db1;
    #查看所有的数据库
    show databases;

      改

    alter  database db1 charset gbk;

      删

    drop database db1;

    操作文件(表)

    use db1 ; 切换文件夹
    select database; 查看当前所在文件夹

      增

    create table t1(id int,name char);

      查

    #查看当前的这张t1表
    show create table t1;
    #查看所有的表
    show tables;
    #查看表的详细信息
    desc t1;

      改

    #modify是修改的意思
    alter table t1 modify name char(6);
    #改变name为大写的NAME
    alter table t1 change name NAME char(7);

      删 

    #删除表
    drop table t1;

    操作文件内容(记录)

      增

    #插入一条数据,规定id,name数据leillei
    insert t1(id,name) alues(1,"mjj01"),(2,"mjj02");

      查

    select id from db1.t1;
    select id,name from db1.t1;
    select * from db1.t1;

      改

    update db1.t1 set name="zhang"
    update db1.t1 set name="alex" where id=2;

      删

    delete from t1;
    delete from t1 where id=2;

    二.库的操作

    1.系统数据库

    information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息、列信息、权限信息、字符信息等
    performance_schema: MySQL 5.5开始新增一个数据库:主要用于收集数据库服务器性能参数,记录处理查询请求时发生的各种事件、锁等现象
    mysql: 授权库,主要存储系统用户的权限信息
    test: MySQL数据库系统自动创建的测试数据库

    2.创建数据库

      求救语法

    help create database;

      创建数据库语法

    create database 数据库名 charset utf8;

      数据库命名规范

    复制代码
    可以由字母、数字、下划线、@、#、$
    区分大小写
    唯一性
    不能使用关键字如 create select
    不能单独使用数字
    最长128位
    # 基本上跟python或者js的命名规则一样

    3.数据库相关操作

    #查看数据库
    show databases;
    #查看当前库
    show create database db1;
    #查看所有的库
    select database();
    #选择数据库
    use 数据库名
    #删除数据库
    drop database 数据库名
    #修改数据库
    alter database db1 charset utf8;

    三.表的操作

    1.mysql支持的存储引擎 

      mysql 5.5版本之后默认为innodb存储引擎
      另外还有mysiam、memory、blackhone
      #memory,在重启mysql或者重启机器后,表内数据清空
      #blackhole,往表内插入任何数据,都相当于丢入黑洞,表内永远不存记录

    InnoDB 存储引擎

      支持事务,其设计目标主要面向联机事务处理(OLTP)的应用。其特点是行锁设计、支持外键,并支持类似 Oracle 的非锁定读,即默认读取操作不会产生锁。 从 MySQL 5.5.8 版本开始是默认的存储引擎。

    MyISAM 存储引擎

      不支持事务、表锁设计、支持全文索引,主要面向一些 OLAP 数 据库应用,在 MySQL 5.5.8 版本之前是默认的存储引擎(除 Windows 版本外)。数据库系统 与文件系统一个很大的不同在于对事务的支持,MyISAM 存储引擎是不支持事务的。 

    Memory 存储引擎

      正如其名,Memory 存储引擎中的数据都存放在内存中,数据库重 启或发生崩溃,表中的数据都将消失。它非常适合于存储 OLTP 数据库应用中临时数据的临时表,也可以作为 OLAP 数据库应用中数据仓库的维度表。Memory 存储引擎默认使用哈希 索引,而不是通常熟悉的 B+ 树索引。

    BLACKHOLE

      黑洞存储引擎,可以应用于主备复制中的分发主库。

    指定表类型/存储引擎

    create table t1(id int) engine=innodb;  # 默认不写就是innodb

    创建四张表,分别使用innodb,myisam,memory,blackhole存储引擎,进行插入数据测试 

    create table t1(id int)engine=innodb;
    create table t2(id int)engine=myisam;
    create table t3(id int)engine=memory;
    create table t4(id int)engine=blackhole;
    #.frm是存储数据表的框架结构
    
    # .ibd是mysql数据文件 
    
    #.MYD是MyISAM表的数据文件的扩展名
    
    #.MYI是MyISAM表的索引的扩展名
    
    #发现后两种存储引擎只有表结构,无数据
    
    #memory,在重启mysql或者重启机器后,表内数据清空
    #blackhole,往表内插入任何数据,都相当于丢入黑洞,表内永远不存记录

    2.创建表

    create table 表名(
    字段名1 类型[(宽度) 约束条件],
    字段名2 类型[(宽度) 约束条件],
    字段名3 类型[(宽度) 约束条件]
    );
    
    #注意:
    1. 在同一张表中,字段名是不能相同
    2. 宽度和约束条件可选
    3. 字段名和类型是必须的

      创建数据库

    create database db2 charset utf8;

      使用数据库

    use db2;

      创建a1表

    create table a1(
        id  int,
        name  varchar(50),
        age int(3)
    );

      插入表的记录

    insert into a1 values
    (1,"mjj",18),
    (2,"wusir",28);

      查询表的数据和结构

        查询a1表中的存储数据   select * from a1;

    mysql> select * from a1;
    +------+-------+------+
    | id | name | age |
    +------+-------+------+
    | 1 | mjj   | 18  |
    | 2 | wusir | 28  |
    +------+-------+------+
    2 rows in set (0.02 sec)
    
    mysql>

        查看a1表的结构    desc a1;

    mysql> desc a1;
    +-------+-------------+------+-----+---------+-------+
    | Field     | Type           | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | id        | int(11)        | YES  |      | NULL    |       |
    | name      | varchar(50)    | YES  |      | NULL    |       |
    | age       | int(3)         | YES  |      | NULL    |       |
    +-------+-------------+------+-----+---------+-------+
    3 rows in set (0.16 sec)

        查看表的详细结构    show create table a1G;

    mysql> show create table a1G;
    *************************** 1. row ***************************
           Table: a1
    Create Table: CREATE TABLE `a1` (
      `id` int(11) DEFAULT NULL,
      `name` varchar(50) DEFAULT NULL,
      `age` int(3) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)

      复制表  

        创建一个新的数据库db3

    create database db3 charset utf8;

      使用db3

     mysql>use db3;
    Database changed

      复制db2.a1的表结构和记录

    # 这就是复制表的操作(既复制了表结构,又复制了记录)
    mysql> create table b1 select * from db2.a1;
    Query OK, 2 rows affected (0.03 sec)

      查看db3.b1中的数据和表结构

    mysql>select * from db3.b1;
    +------+-------+------+
    | id   | name  | age  |
    +------+-------+------+
    |    1 | mjj   |   18 |
    |    2 | wusir |   28 |
    +------+-------+------+
    2 rows in set (0.00 sec)

      只要表结构,不要记录

    #在db2数据库下新创建一个b2表,给一个where条件,条件要求不成立,条件为false,只拷贝表结构
    mysql> create table b2 select * from db2.a1 where 1>5;
    Query OK, 0 rows affected (0.05 sec)
    Records: 0  Duplicates: 0  Warnings: 0

      查看表结构

    # 查看表结构
    mysql> desc b2;
    +-------+-------------+------+-----+---------+-------+
    | Field | Type        | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | id    | int(11)     | YES  |     | NULL    |       |
    | name  | varchar(50) | YES  |     | NULL    |       |
    | age   | int(3)      | YES  |     | NULL    |       |
    +-------+-------------+------+-----+---------+-------+
    3 rows in set (0.02 sec)
    
    #查看表结构中的数据,发现是空数据
    mysql> select * from b2;
    Empty set (0.00 sec)

      使用like(只拷贝表结构,不拷贝记录)

    mysql> create table b3 like db2.a1;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> desc b3;
    +-------+-------------+------+-----+---------+-------+
    | Field | Type        | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | id    | int(11)     | YES  |     | NULL    |       |
    | name  | varchar(50) | YES  |     | NULL    |       |
    | age   | int(3)      | YES  |     | NULL    |       |
    +-------+-------------+------+-----+---------+-------+
    3 rows in set (0.02 sec)
    
    mysql> select * from db3.b3;
    Empty set (0.00 sec)

      删除表

    drop table 表名;

    四.数据类型

    mysql常用数据类型:

    #1. 数字:
        整型:tinyint  int  bigint
        小数:
            float :在位数比较短的情况下不精准
            double :在位数比较长的情况下不精准
                0.000001230123123123
                存成:0.000001230000
    
            decimal:(如果用小数,则用推荐使用decimal)
                精准
                内部原理是以字符串形式去存
    
    #2. 字符串:
        char(10):简单粗暴,浪费空间,存取速度快
                root存成root000000
        varchar:精准,节省空间,存取速度慢
    
        sql优化:创建表时,定长的类型往前放,变长的往后放
                        比如性别           比如地址或描述信息
    
        >255个字符,超了就把文件路径存放到数据库中。
                比如图片,视频等找一个文件服务器,数据库中只存路径或url。
    
    
    #3. 时间类型:
        最常用:datetime
    
    
    #4. 枚举类型与集合类型
       enum 和set

    一、数值类型

    整数类型:TINYINT SMALLINT MEDIUMINT INT BIGINT

    作用:存储年龄,等级,id,各种号码等

    ========================================
            tinyint[(m)] [unsigned] [zerofill]
    
                小整数,数据类型用于保存一些范围的整数数值范围:
                有符号:
                    -128 ~ 127
                无符号:
    ~ 255
    
                PS: MySQL中无布尔值,使用tinyint(1)构造。
    
    
    
    ========================================
            int[(m)][unsigned][zerofill]
    
                整数,数据类型用于保存一些范围的整数数值范围:
                有符号:
                        -2147483648 ~ 2147483647
                无符号:
    ~ 4294967295
    
    
    
    ========================================
            bigint[(m)][unsigned][zerofill]
                大整数,数据类型用于保存一些范围的整数数值范围:
                有符号:
                        -9223372036854775808 ~ 9223372036854775807
                无符号:
     ~  18446744073709551615

    验证1:有符号和无符号tinyint

    ============有符号tinyint==============
    # 创建数据库db4
    create database db4 charset utf8;
    
    # 切换到当前db4数据库
    mysql> use db4;
    
    # 创建t1 规定x字段为tinyint数据类型(默认是有符号的)
    mysql> create table t1(x tinyint);
    
    # 验证,插入-1这个数
    mysql>   insert into t1 values(-1);
    
    # 查询 表记录,查询成功(证明默认是有符号类型)
    mysql> select * from t1;
    +------+
    | x    |
    +------+
    | -1 |
    +------+
    
    #执行如下操作,会发现报错。因为有符号范围在(-128,127)
    mysql>   insert into t1 values(-129),(128);
    ERROR 1264 (22003): Out of range value for column 'x' at row 1
    
    
    ============无符号tinyint==============
    # 创建表时定义记录的字符为无符号类型(0,255) ,使用unsigned
    mysql> create table t2(x tinyint unsigned);
    
    # 报错,超出范围
    mysql>   insert into t2 values(-129);
    ERROR 1264 (22003): Out of range value for column 'x' at row 1
    
    # 插入成功
    mysql>   insert into t2 values(255);
    Query OK, 1 row affected (0.00 sec)

    验证2:int类型后面的存储是显示宽度,而不是存储宽度

    mysql> create table t3(id int(1) unsigned);
    
    #插入255555记录也是可以的
    mysql> insert into t3 values(255555);
    
    mysql> select * from t3;
    +--------+
    | id     |
    +--------+
    | 255555 |
    +--------+
    ps:以上操作还不能够验证,再来一张表验证用zerofill 用0填充
    
    # zerofill 用0填充
    mysql> create table t4(id int(5) unsigned zerofill);
    
    
    mysql> insert into t4 value(1);
    Query OK, 1 row affected (0.00 sec)
    
    #插入的记录是1,但是显示的宽度是00001
    mysql> select * from t4;
    +-------+
    | id    |
    +-------+
    | 00001 |
    +-------+
    1 row in set (0.00 sec)

    注意:为该类型指定宽度时,仅仅只是指定查询结果的显示宽度,与存储范围无关,存储范围如下

    其实我们完全没必要为整数类型指定显示宽度,使用默认的就可以了

    默认的显示宽度,都是在最大值的基础上加1

    int的存储宽度是4个Bytes,即32个bit,即2**32

    无符号最大值为:4294967296-1

    有符号最大值:2147483648-1

    有符号和无符号的最大数字需要的显示宽度均为10,而针对有符号的最小值则需要11位才能显示完全,所以int类型默认的显示宽度为11是非常合理的

    最后:整形类型,其实没有必要指定显示宽度,使用默认的就ok

    二、浮点型

    定点数类型: DEC等同于DECIMAL

    浮点类型:FLOAT DOUBLE

    作用:存储薪资、身高、体重、体质参数等

    语法:

    -------------------------FLOAT-------------------
    FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
    #参数解释:单精度浮点数(非准确小数值),M是全长,D是小数点后个数。M最大值为255,D最大值为30
    
    #有符号:
               -3.402823466E+38 to -1.175494351E-38,
               1.175494351E-38 to 3.402823466E+38
    
    #无符号:
               1.175494351E-38 to 3.402823466E+38
    #精确度: 
               **** 随着小数的增多,精度变得不准确 ****
    
    
     -------------------------DOUBLE-----------------------
    DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
    
    #参数解释: 双精度浮点数(非准确小数值),M是全长,D是小数点后个数。M最大值为255,D最大值为30
    
    #有符号:
               -1.7976931348623157E+308 to -2.2250738585072014E-308
               2.2250738585072014E-308 to 1.7976931348623157E+308
    
    #无符号:
               2.2250738585072014E-308 to 1.7976931348623157E+308
    
    #精确度:
               ****随着小数的增多,精度比float要高,但也会变得不准确 ****
    
    ======================================
    --------------------DECIMAL------------------------
    decimal[(m[,d])] [unsigned] [zerofill]
    
    #参数解释:准确的小数值,M是整数部分总个数(负号不算),D是小数点后个数。 M最大值为65,D最大值为30。
    
    
    #精确度:
               **** 随着小数的增多,精度始终准确 ****
               对于精确数值计算时需要用此类型
               decaimal能够存储精确值的原因在于其内部按照字符串存储。

    验证三种类型建表:

    #1验证FLOAT类型建表:
    mysql> create table t5(x float(256,31));
    ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.
    mysql> create table t5(x float(256,30));
    ERROR 1439 (42000): Display width out of range for column 'x' (max = 255)
    mysql> create table t5(x float(255,30)); #建表成功
    Query OK, 0 rows affected (0.03 sec)
    
    #2验证DOUBLE类型建表:
    mysql> create table t6(x double(255,30)); #建表成功
    Query OK, 0 rows affected (0.03 sec)
    
    #3验证deimal类型建表:
    mysql> create table t7(x decimal(66,31));
    ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.
    mysql> create table t7(x decimal(66,30));
    ERROR 1426 (42000): Too big precision 66 specified for column 'x'. Maximum is 65.
    mysql> create table t7(x decimal(65,30)); #建表成功
    Query OK, 0 rows affected (0.00 sec)

    验证三种类型的精度:

    # 分别对三张表插入相应的记录
    mysql> insert into t5 values(1.1111111111111111111111111111111);#小数点后31个1
    Query OK, 1 row affected (0.01 sec)
    
    mysql> insert into t6 values(1.1111111111111111111111111111111);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> insert into t7 values(1.1111111111111111111111111111111);
    Query OK, 1 row affected, 1 warning (0.00 sec)
    
    # 查询结果
    mysql> select * from t5; #随着小数的增多,精度开始不准确
    +----------------------------------+
    | x                                |
    +----------------------------------+
    | 1.111111164093017600000000000000 |
    +----------------------------------+
    1 row in set (0.00 sec)
    
    mysql> select * from t6; #精度比float要准确点,但随着小数的增多,同样变得不准确
    +----------------------------------+
    | x                                |
    +----------------------------------+
    | 1.111111111111111200000000000000 |
    +----------------------------------+
    1 row in set (0.00 sec)
    
    mysql> select * from t7; #精度始终准确,d为30,于是只留了30位小数
    +----------------------------------+
    | x                                |
    +----------------------------------+
    | 1.111111111111111111111111111111 |
    +----------------------------------+
    1 row in set (0.00 sec)

    三、日期类型

    DATE TIME DATETIME TIMESTAMP YEAR
    作用:存储用户注册时间,文章发布时间,员工入职时间,出生时间,过期时间等

    语法:
            YEAR
                YYYY(1901/2155)
    
            DATE
                YYYY-MM-DD(1000-01-01/9999-12-31)
    
            TIME
                HH:MM:SS('-838:59:59'/'838:59:59')
    
            DATETIME
    
                YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59    Y)
    
            TIMESTAMP
    
                YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某时)

    验证:

    1、year

    mysql> create table t8(born_year year);#无论year指定何种宽度,最后都默认是year(4)
    Query OK, 0 rows affected (0.03 sec)
    #插入失败,超出范围(1901/2155) mysql> insert into t8 values -> (1900), -> (1901), -> (2155), -> (2156); ERROR 1264 (22003): Out of range value for column 'born_year' at row 1

    mysql> select * from t8; Empty set (0.01 sec) mysql> insert into t8 values -> (1905), -> (2018); Query OK, 2 rows affected (0.00 sec) #插入记录成功 Records: 2 Duplicates: 0 Warnings: 0
    mysql> select * from t8; +-----------+ | born_year | +-----------+ | 1905 | | 2018 | +-----------+ 2 rows in set (0.00 sec)

    2、date、year、datetime

    #创建t9表
    mysql> create table t9(d date,t time,dt datetime);
    Query OK, 0 rows affected (0.06 sec)
    
    #查看表的结构
    mysql> desc t9;
    +-------+----------+------+-----+---------+-------+
    | Field | Type     | Null | Key | Default | Extra |
    +-------+----------+------+-----+---------+-------+
    | d     | date     | YES  |     | NULL    |       |
    | t     | time     | YES  |     | NULL    |       |
    | dt    | datetime | YES  |     | NULL    |       |
    +-------+----------+------+-----+---------+-------+
    3 rows in set (0.14 sec)
    
    
    # 调用mysql自带的now()函数,获取当前类型指定的时间 如下结构
    mysql> insert into t9 values(now(),now(),now());
    Query OK, 1 row affected, 1 warning (0.01 sec)
    
    mysql> select * from t9;
    +------------+----------+---------------------+
    | d          | t        | dt                  |
    +------------+----------+---------------------+
    | 2018-06-09 | 09:35:20 | 2018-06-09 09:35:20 |
    +------------+----------+---------------------+
    1 row in set (0.00 sec)

    datetime与timestamp的区别

    在实际应用的很多场景中,MySQL的这两种日期类型都能够满足我们的需要,存储精度都为秒,但在某些情况下,会展现出他们各自的优劣。
    下面就来总结一下两种日期类型的区别。
    
    1.DATETIME的日期范围是1001——9999年,TIMESTAMP的时间范围是1970——2038年。
    
    2.DATETIME存储时间与时区无关,TIMESTAMP存储时间与时区有关,显示的值也依赖于时区。在mysql服务器,
    操作系统以及客户端连接都有时区的设置。
    
    3.DATETIME使用8字节的存储空间,TIMESTAMP的存储空间为4字节。因此,TIMESTAMP比DATETIME的空间利用率更高。
    
    4.DATETIME的默认值为null;TIMESTAMP的字段默认不为空(not null),默认值为当前时间(CURRENT_TIMESTAMP),
    如果不做特殊处理,并且update语句中没有指定该列的更新值,则默认更新为当前时间。

    小结:

    #1. 单独插入时间时,需要以字符串的形式,按照对应的格式插入
    #2. 插入年份时,尽量使用4位值
    #3. 插入两位年份时,<=69,以20开头,比如50,  结果2050      
                    >=70,以19开头,比如71,结果1971
     create table t12(y year);
     insert into t12 values  (50),(71);
     select * from t12;
    +------+
    | y    |
    +------+
    | 2050 |
    | 1971 |
    +------+

    练习:

    创建一张学生表(student),要求有id,姓名,出生年份,出生的年月日,进班的时间,以及来老男孩学习的现在具体时间。

    mysql> create table student(
        -> id int,
        -> name varchar(20),
        -> born_year year,
        -> birth date,
        -> class_time time,
        -> reg_time datetime
        -> );
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> insert into student values
        ->   (1,'alex',"1995","1995-11-11","11:11:11","2017-11-11 11:11:11"),
        ->   (2,'egon',"1997","1997-12-12","12:12:12","2017-12-12 12:12:12"),
        ->   (3,'wsb',"1998","1998-01-01","13:13:13","2017-01-01 13:13:13");
    Query OK, 3 rows affected (0.00 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql>   select * from student;
    +------+------+-----------+------------+------------+---------------------+
    | id   | name | born_year | birth      | class_time | reg_time            |
    +------+------+-----------+------------+------------+---------------------+
    |    1 | alex |      1995 | 1995-11-11 | 11:11:11   | 2017-11-11 11:11:11 |
    |    2 | egon |      1997 | 1997-12-12 | 12:12:12   | 2017-12-12 12:12:12 |
    |    3 | wsb  |      1998 | 1998-01-01 | 13:13:13   | 2017-01-01 13:13:13 |
    +------+------+-----------+------------+------------+---------------------+
    3 rows in set (0.00 sec)
    View Code

    四.字符类型

    #官网:https://dev.mysql.com/doc/refman/5.7/en/char.html
    #注意:char和varchar括号内的参数指的都是字符的长度
    
    #char类型:定长,简单粗暴,浪费空间,存取速度快
        字符长度范围:0-255(一个中文是一个字符,是utf8编码的3个字节)
        存储:
            存储char类型的值时,会往右填充空格来满足长度
            例如:指定长度为10,存>10个字符则报错,存<10个字符则用空格填充直到凑够10个字符存储
    
        检索:
            在检索或者说查询时,查出的结果会自动删除尾部的空格,除非我们打开pad_char_to_full_length SQL模式(设置SQL模式:SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
          查询sql的默认模式:select @@sql_mode;)
    
    #varchar类型:变长,精准,节省空间,存取速度慢
        字符长度范围:0-65535(如果大于21845会提示用其他类型 。mysql行最大限制为65535字节,字符编码为utf-8:https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html)
        存储:
            varchar类型存储数据的真实内容,不会用空格填充,如果'ab  ',尾部的空格也会被存起来
            强调:varchar类型会在真实数据前加1-2Bytes的前缀,该前缀用来表示真实数据的bytes字节数(1-2Bytes最大表示65535个数字,正好符合mysql对row的最大字节限制,即已经足够使用)
            如果真实的数据<255bytes则需要1Bytes的前缀(1Bytes=8bit 2**8最大表示的数字为255)
            如果真实的数据>255bytes则需要2Bytes的前缀(2Bytes=16bit 2**16最大表示的数字为65535)
    
        检索:
            尾部有空格会保存下来,在检索或者说查询时,也会正常显示包含空格在内的内容

    两个函数

    length():查看字节数
    char_length():查看字符数

    1.char填充空格来满足固定长度,但是在查询时却会很不要脸地删除尾部的空格(装作自己好像没有浪费过空间一样),然后修改sql_mode让其现出原形。

    # 创建t1表,分别指明字段x为char类型,字段y为varchar类型
    mysql> create table t1(x char(5),y varchar(4));
    Query OK, 0 rows affected (0.16 sec)
    
    # char存放的是5个字符,而varchar存4个字符
    mysql>  insert into t1 values('你瞅啥 ','你瞅啥 ');
    Query OK, 1 row affected (0.01 sec)
    
    # 在检索时char很不要脸地将自己浪费的2个字符给删掉了,装的好像自己没浪费过空间一样,而varchar很老实,存了多少,就显示多少
    mysql> select x,char_length(x),y,char_length(y) from t1;
    +-----------+----------------+------------+----------------+
    | x         | char_length(x) | y          | char_length(y) |
    +-----------+----------------+------------+----------------+
    | 你瞅啥    |              3 | 你瞅啥     |              4 |
    +-----------+----------------+------------+----------------+
    1 row in set (0.02 sec)
    
     #略施小计,让char现原形
     mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
    Query OK, 0 rows affected (0.00 sec)
    
    #查看当前mysql的mode模式
    mysql> select @@sql_mode;
    +-------------------------+
    | @@sql_mode              |
    +-------------------------+
    | PAD_CHAR_TO_FULL_LENGTH |
    +-------------------------+
    1 row in set (0.00 sec)
    
    #原形毕露了吧。。。。
    mysql> select x,char_length(x) y,char_length(y) from t1;
    +-------------+------+----------------+
    | x           | y    | char_length(y) |
    +-------------+------+----------------+
    | 你瞅啥      |    5 |              4 |
    +-------------+------+----------------+
    1 row in set (0.00 sec)
    
    # 查看字节数
    #char类型:3个中文字符+2个空格=11Bytes
    #varchar类型:3个中文字符+1个空格=10Bytes
    mysql> select x,length(x),y,length(y) from t1;
    +-------------+-----------+------------+-----------+
    | x           | length(x) | y          | length(y) |
    +-------------+-----------+------------+-----------+
    | 你瞅啥      |        11 | 你瞅啥     |        10 |
    +-------------+-----------+------------+-----------+
    1 row in set (0.02 sec)

    总结:

    常用字符串系列:char与varchar
    注:虽然varchar使用起来较为灵活,但是从整个系统的性能角度来说,char数据类型的处理速度更快,有时甚至可以超出varchar处理速度的50%。因此,用户在设计数据库时应当综合考虑各方面的因素,以求达到最佳的平衡

    其他字符串系列(效率:char>varchar>text)
    TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT
    BLOB 系列 TINYBLOB BLOB MEDIUMBLOB LONGBLOB
    BINARY系列 BINARY VARBINARY

    text:text数据类型用于保存变长的大字符串,可以组多到65535 (2**16 − 1)个字符。
    mediumtext:A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.
    longtext:A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.

    五.枚举类型和集合类型

    字段的值只能在给定范围中选择,如单选框,多选框

    enum 单选 只能在给定的范围内选一个值,如性别 sex 男male/女female

    set 多选 在给定的范围内可以选择一个或一个以上的值(爱好1,爱好2,爱好3...)

    mysql> create table consumer(
        -> id int,
        -> name varchar(50),
        -> sex enum('male','female','other'),
        -> level enum('vip1','vip2','vip3','vip4'),#在指定范围内,多选一
        -> fav set('play','music','read','study') #在指定范围内,多选多
        -> );
    Query OK, 0 rows affected (0.03 sec)
    
    
    mysql> insert into consumer values
        -> (1,'赵云','male','vip2','read,study'),
        -> (2,'赵云2','other','vip4','play');
    Query OK, 2 rows affected (0.00 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    mysql> select * from consumer;
    +------+---------+-------+-------+------------+
    | id   | name    | sex   | level | fav        |
    +------+---------+-------+-------+------------+
    |    1 | 赵云    | male  | vip2  | read,study |
    |    2 | 赵云2   | other | vip4  | play       |
    +------+---------+-------+-------+------------+
    2 rows in set (0.00 sec)

    五.完整性约束

    约束条件与数据类型的宽度一样,都是可选参数

    作用:用于保证数据的完整性和一致性

    主要分为:

    PRIMARY KEY (PK)    #标识该字段为该表的主键,可以唯一的标识记录
    FOREIGN KEY (FK)    #标识该字段为该表的外键
    NOT NULL    #标识该字段不能为空
    UNIQUE KEY (UK)    #标识该字段的值是唯一的
    AUTO_INCREMENT    #标识该字段的值自动增长(整数类型,而且为主键)
    DEFAULT    #为该字段设置默认值
    
    UNSIGNED #无符号
    ZEROFILL #使用0填充

    说明:

    #1. 是否允许为空,默认NULL,可设置NOT NULL,字段不允许为空,必须赋值
    #2. 字段是否有默认值,缺省的默认值是NULL,如果插入记录时不给字段赋值,此字段使用默认值
    sex enum('male','female') not null default 'male'
    
    #必须为正值(无符号) 不允许为空 默认是20
    age int unsigned NOT NULL default 20 
    # 3. 是否是key
    主键 primary key
    外键 foreign key
    索引 (index,unique...)

    1.not null 与default

    是否可空,null表示空,非字符串
    not null - 不可空
    null - 可空

    默认值,创建列时可以指定默认值,当插入数据时如果未主动设置,则自动添加默认值

    create table tb1(
        nid int not null defalut 2,
        num int not null
    
    );

    验证1:

    mysql> create table t11(id int);# id字段默认可以为空
    Query OK, 0 rows affected (0.05 sec)
    
    mysql> desc t11;
    +-------+---------+------+-----+---------+-------+
    | Field | Type    | Null | Key | Default | Extra |
    +-------+---------+------+-----+---------+-------+
    | id    | int(11) | YES   |          | NULL    |       |
    +-------+---------+------+-----+---------+-------+
    1 row in set (0.03 sec)
    mysql> insert into t11 values(); #给t11表插一个空的值
    Query OK, 1 row affected (0.00 sec)
    
    #查询结果如下
    mysql> select * from t11;
    +------+
    | id   |
    +------+
    | NULL |
    +------+
    1 row in set (0.00 sec)

    验证2:

    mysql> create table t12(id int not null);#设置字段id不为空
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> desc t12;
    +-------+---------+------+-----+---------+-------+
    | Field | Type    | Null | Key | Default | Extra |
    +-------+---------+------+-----+---------+-------+
    | id    | int(11) | NO   |     | NULL    |       |
    +-------+---------+------+-----+---------+-------+
    row in set (0.01 sec)
    
    mysql> insert into t12 values();#不能插入空
    ERROR 1364 (HY000): Field 'id' doesn't have a default value
    
    设置not null,插入值时不能为空
    View Code
    # 第一种情况
    mysql> create table t13(id int default 1);
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> desc t13;
    +-------+---------+------+-----+---------+-------+
    | Field | Type    | Null | Key | Default | Extra |
    +-------+---------+------+-----+---------+-------+
    | id    | int(11) | YES  |           | 1              |              |
    +-------+---------+------+-----+---------+-------+
    row in set (0.01 sec)
    
    mysql> insert into t13 values();
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t13;
    +------+
    | id   |
    +------+
    |    1  |
    +------+
    row in set (0.00 sec)
    
    
    # 第二种情况
    mysql> create table t14(id int not null default 2);
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> desc t14;
    +-------+---------+------+-----+---------+-------+
    | Field | Type    | Null | Key | Default | Extra |
    +-------+---------+------+-----+---------+-------+
    | id    | int(11) | NO      |         | 2               |             |
    +-------+---------+------+-----+---------+-------+
    row in set (0.01 sec)
    
    mysql> select * from t14;
    +----+
    | id |
    +----+
    |  2 |
    +----+
    row in set (0.00 sec)
    
    设置id字段有默认值后,则无论id字段是null还是not null,都可以插入空,插入空默认填入default指定的默认值
    设置id字段有默认值后,则无论id字段是null还是not null,都可以插入空,插入空默认填入default指定的默认值

    创建学生表student2,设置每个字段的约束条件。

    mysql> create table student2(
        -> id int not null,
        -> name varchar(50) not null,
        -> age int(3) unsigned not null default 18,
        -> sex enum('male','female') default 'male',
        -> fav set('smoke','drink','tangtou') default 'drink,tangtou'
        -> );
    Query OK, 0 rows affected (0.01 sec)
    
    # 只插入了not null约束条件的字段对应的值
    mysql> insert into student2(id,name) values(1,'mjj');
    Query OK, 1 row affected (0.00 sec)
    
    # 查询结果如下
    mysql> select * from student2;
    +----+------+-----+------+---------------+
    | id | name | age | sex  | fav           |
    +----+------+-----+------+---------------+
    |  1 | mjj  |  18 | male | drink,tangtou |
    +----+------+-----+------+---------------+
    1 row in set (0.00 sec)

    2、unique

    中文翻译:不同的。在mysql中称为单列唯一

    举例说明:创建公司部门表(每个公司都有唯一的一个部门)。

    mysql> create table department(
        -> id int,
        -> name char(10)
        -> );
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> insert into department values(1,'IT'),(2,'IT');
    Query OK, 2 rows affected (0.00 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    mysql> select * from department;
    +------+------+
    | id   | name |
    +------+------+
    |    1 | IT   |
    |    2 | IT   |
    +------+------+
    2 rows in set (0.00 sec)
    # 发现: 同时插入两个IT部门也是可以的,但这是不合理的,所以我们要设置name字段为unique 解决这种不合理的现象。
    验证之前重复插入记录的操作是可行的,但是不符合场景

    使用约束条件unique

    #第一种创建unique的方式
    #例子1:
    create table department(
        id int,
        name char(10) unique
    );
    mysql> insert into department values(1,'it'),(2,'it');
    ERROR 1062 (23000): Duplicate entry 'it' for key 'name'
    
    #例子2:
    create table department(
        id int unique,
        name char(10) unique
    );
    insert into department values(1,'it'),(2,'sale');
    
    #第二种创建unique的方式
    create table department(
        id int,
        name char(10) ,
        unique(id),
        unique(name)
    );
    insert into department values(1,'it'),(2,'sale');

    联合唯一:

    # 创建services表
    mysql> create table services(
        -> id int,
        -> ip char(15),
        -> port int,
        -> unique(id),
        -> unique(ip,port)
        -> );
    Query OK, 0 rows affected (0.05 sec)
    
    mysql> desc services;
    +-------+----------+------+-----+---------+-------+
    | Field | Type      | Null | Key | Default | Extra |
    +-------+----------+------+-----+---------+-------+
    | id        | int(11)   | YES   | UNI  | NULL       |             |
    | ip        | char(15) | YES   | MUL  | NULL       |             |
    | port    | int(11) | YES   |          | NULL       |             |
    +-------+----------+------+-----+---------+-------+
    rows in set (0.01 sec)
    
    #联合唯一,只要两列记录,有一列不同,既符合联合唯一的约束
    mysql> insert into services values
        -> (1,'192,168,11,23',80),
        -> (2,'192,168,11,23',81),
        -> (3,'192,168,11,25',80);
    Query OK, 3 rows affected (0.01 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> select * from services;
    +------+---------------+------+
    | id   | ip            | port |
    +------+---------------+------+
    |    1 | 192,168,11,23 |   80 |
    |    2 | 192,168,11,23 |   81 |
    |    3 | 192,168,11,25 |   80 |
    +------+---------------+------+
    rows in set (0.00 sec)
    
    mysql> insert into services values (4,'192,168,11,23',80);
    ERROR 1062 (23000): Duplicate entry '192,168,11,23-80' for key 'ip'

    3.primary key

    一个表中可以:

    单列做主键
    多列做主键(复合主键)

    约束:等价于 not null unique,字段的值不为空且唯一

    存储引擎默认是(innodb):对于innodb存储引擎来说,一张表必须有一个主键。

    单列主键

    # 创建t14表,为id字段设置主键,唯一的不同的记录
    create table t14(
        id int primary key,
        name char(16)
    );
    
    insert into t14 values
    (1,'xiaoma'),
    (2,'xiaohong');
    
    mysql> insert into t14 values(2,'wxxx');
    ERROR 1062 (23000): Duplicate entry '6' for key 'PRIMARY'
    
    
    #   not null + unique的化学反应,相当于给id设置primary key
    create table t15(
        id int not null unique,
        name char(16)
    );
    mysql> create table t15(
        -> id int not null unique,
        -> name char(16)
        -> );
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> desc t15;
    +-------+----------+------+-----+---------+-------+
    | Field | Type         | Null | Key | Default | Extra |
    +-------+----------+------+-----+---------+-------+
    | id        | int(11)  | NO     | PRI | NULL       |             |
    | name   | char(16) | YES  |         | NULL       |             |
    +-------+----------+------+-----+---------+-------+
    2 rows in set (0.02 sec)

    复合主键

    create table t16(
        ip char(15),
        port int,
        primary key(ip,port)
    );
    
    insert into t16 values
    ('1.1.1.2',80),
    ('1.1.1.2',81);

    4.auto_increment

    约束:约束的字段为自动增长,约束的字段必须同时被key约束

    验证:

    # 创建student
    create table student(
    id int primary key auto_increment,
    name varchar(20),
    sex enum('male','female') default 'male'
    );
    
    mysql>  desc student;
    +-------+-----------------------+------+-----+---------+----------------+
    | Field | Type                  | Null | Key | Default | Extra          |
    +-------+-----------------------+------+-----+---------+----------------+
    | id    | int(11)               | NO   | PRI | NULL    | auto_increment |
    | name  | varchar(20)           | YES  |     | NULL    |                |
    | sex   | enum('male','female') | YES  |     | male    |                |
    +-------+-----------------------+------+-----+---------+----------------+
    rows in set (0.17 sec)
    
    #插入记录
    mysql>  insert into student(name) values ('老白'),('小白');
    Query OK, 2 rows affected (0.01 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    mysql> select * from student;
    +----+--------+------+
    | id | name   | sex  |
    +----+--------+------+
    |  1 | 老白   | male |
    |  2 | 小白   | male |
    +----+--------+------+
    rows in set (0.00 sec)
    
    不指定id,则自动增长
    不指定id,则自动增长
    mysql> insert into student values(4,'asb','female');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into student values(7,'wsb','female');
    Query OK, 1 row affected (0.01 sec)
    
    mysql> select * from student;
    +----+--------+--------+
    | id | name   | sex    |
    +----+--------+--------+
    |  1 | 老白   | male   |
    |  2 | 小白   | male   |
    |  4 | asb    | female |
    |  7 | wsb    | female |
    +----+--------+--------+
    rows in set (0.00 sec)
    
    # 再次插入一条不指定id的记录,会在之前的最后一条记录继续增长
    mysql>  insert into student(name) values ('大白');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from student;
    +----+--------+--------+
    | id | name   | sex    |
    +----+--------+--------+
    |  1 | 老白   | male   |
    |  2 | 小白   | male   |
    |  4 | asb    | female |
    |  7 | wsb    | female |
    |  8 | 大白   | male   |
    +----+--------+--------+
    rows in set (0.00 sec)
    
    也可以指定id
    指定id
    mysql> delete from student;
    Query OK, 5 rows affected (0.00 sec)
    
    mysql> select * from student;
    Empty set (0.00 sec)
    
    mysql> select * from student;
    Empty set (0.00 sec)
    
    mysql> insert into student(name) values('ysb');
    Query OK, 1 row affected (0.01 sec)
    
    mysql> select * from student;
    +----+------+------+
    | id | name | sex  |
    +----+------+------+
    |  9 | ysb  | male |
    +----+------+------+
    row in set (0.00 sec)
    
    #应该用truncate清空表,比起delete一条一条地删除记录,truncate是直接清空表,在删除大表时用它
    mysql> truncate student;
    Query OK, 0 rows affected (0.03 sec)
    
    mysql>  insert into student(name) values('xiaobai');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from student;
    +----+---------+------+
    | id | name    | sex  |
    +----+---------+------+
    |  1 | xiaobai | male |
    +----+---------+------+
    row in set (0.00 sec)
    
    mysql>
    
    对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增长
    对于自增的字段,在用delete删除后,再插入值,该字段仍按照删除前的位置继续增长

    清空表区分delete和truncate的区别:

    delete from t1; #如果有自增id,新增的数据,仍然是以删除前的最后一样作为起始。

    truncate table t1;数据量大,删除速度比上一条快,且直接从零开始。

    5.foreign key

    一 快速理解foreign key

    之前创建表的时候都是在一张表中添加记录,比如如下表:

    公司有3个部门,但是有1个亿的员工,那意味着部门这个字段需要重复存储,部门名字越长,越浪费。

    这个时候,

    解决方法:

    我们完全可以定义一个部门表

    然后让员工信息表关联该表,如何关联,即foreign key

    我们可以将上表改为如下结构:

    此时有两张表,一张是employee表,简称emp表(关联表,也就从表)。一张是department表,简称dep表(被关联表,也叫主表)。

    创建两张表操作:

    #1.创建表时先创建被关联表,再创建关联表
    # 先创建被关联表(dep表)
    create table dep(
        id int primary key,
        name varchar(20) not null,
        descripe varchar(20) not null
    );
    
    #再创建关联表(emp表)
    create table emp(
        id int primary key,
        name varchar(20) not null,
        age int not null,
        dep_id int,
        constraint fk_dep foreign key(dep_id) references dep(id) 
    );
    
    #2.插入记录时,先往被关联表中插入记录,再往关联表中插入记录
    
    insert into dep values
    (1,'IT','IT技术有限部门'),
    (2,'销售部','销售部门'),
    (3,'财务部','花钱太多部门');
    
    insert into emp values
    (1,'zhangsan',18,1),
    (2,'lisi',19,1),
    (3,'egon',20,2),
    (4,'yuanhao',40,3),
    (5,'alex',18,2);
    
    3.删除表
    #按道理来说,删除了部门表中的某个部门,员工表的有关联的记录相继删除。
    mysql> delete from dep where id=3;
    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`))
    
    #但是先删除员工表的记录之后,再删除当前部门就没有任何问题
    
    mysql> delete from emp where dep =3;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from emp;
    +----+----------+-----+--------+
    | id | name     | age | dep_id |
    +----+----------+-----+--------+
    |  1 | zhangsan |  18 |      1 |
    |  2 | lisi     |  18 |      1 |
    |  3 | egon     |  20 |      2 |
    |  5 | alex     |  18 |      2 |
    +----+----------+-----+--------+
    rows in set (0.00 sec)
    
    mysql> delete from dep where id=3;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from dep;
    +----+-----------+----------------------+
    | id | name      | descripe             |
    +----+-----------+----------------------+
    |  1 | IT        | IT技术有限部门       |
    |  2 | 销售部    | 销售部门             |
    +----+-----------+----------------------+
    rows in set (0.00 sec)
    View Code

    注意:在关联表中加入
    on delete cascade #同步删除
    on update cascade #同步更新

    修改emp表:

    create table emp(
        id int primary key,
        name varchar(20) not null,
        age int not null,
        dep_id int,
        constraint fk_dep foreign key(dep_id) references dep(id) 
        on delete cascade #同步删除
        on update cascade #同步更新
    );

    接下来的操作,就复合我们正常的生活中的情况了。

    #再去删被关联表(dep)的记录,关联表(emp)中的记录也跟着删除
    mysql> delete from dep where id=3;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from dep;
    +----+-----------+----------------------+
    | id | name      | descripe             |
    +----+-----------+----------------------+
    |  1 | IT        | IT技术有限部门       |
    |  2 | 销售部    | 销售部门             |
    +----+-----------+----------------------+
    2 rows in set (0.00 sec)
    
    mysql> select * from emp;
    +----+----------+-----+--------+
    | id | name     | age | dep_id |
    +----+----------+-----+--------+
    |  1 | zhangsan |  18 |      1 |
    |  2 | lisi     |  19 |      1 |
    |  3 | egon     |  20 |      2 |
    |  5 | alex     |  18 |      2 |
    +----+----------+-----+--------+
    4 rows in set (0.00 sec)
    
    #再去更改被关联表(dep)的记录,关联表(emp)中的记录也跟着更改
    
    mysql> update dep set id=222 where id=2;
    Query OK, 1 row affected (0.02 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    # 赶紧去查看一下两张表是否都被删除了,是否都被更改了
    mysql> select * from dep;
    +-----+-----------+----------------------+
    | id  | name      | descripe             |
    +-----+-----------+----------------------+
    |   1 | IT        | IT技术有限部门       |
    | 222 | 销售部    | 销售部门             |
    +-----+-----------+----------------------+
    2 rows in set (0.00 sec)
    
    mysql> select * from emp;
    +----+----------+-----+--------+
    | id | name     | age | dep_id |
    +----+----------+-----+--------+
    |  1 | zhangsan |  18 |      1 |
    |  2 | lisi     |  19 |      1 |
    |  3 | egon     |  20 |    222 |
    |  5 | alex     |  18 |    222 |
    +----+----------+-----+--------+
    4 rows in set (0.00 sec)
  • 相关阅读:
    Solidity notes
    Solidity by Example详解
    基本命令中部
    基本命令上部
    服务器介绍
    Linux发展史及安装
    ERROR: Unrecognized command line argument: 'use'
    RequireJs 深入理解
    Redis 安装教程 (Windows 2.6.13 稳定版)
    System.AccessViolationException: 尝试读取或写入受保护的内存 解决办法
  • 原文地址:https://www.cnblogs.com/chenxi67/p/9792308.html
Copyright © 2011-2022 走看看