【002】Linux MySQL 学习笔记-数据类型与约束

1 数据类型

数据类型用来约束你能够存放在数据库中的数据内容

数据类型的分类
1、数值类型
2、字符串类型
3、日期时间类型

1.1 数值类型

  1. 整型
整型存储占的字节数有符号数范围无符号数范围
tinyint1B(8bits)-128~1270~255(2^8-1)
smallint2B-32768~327670~65535
mediumint3B-8388608~83886070~16777215
int4B-2147483648~21474836470~4294967295
bigint8B-9223372036854775808~92233720368547758070~18446744073709551615

在存储的时候,默认是有符号数的

整型可以指定显示宽度,但是并不影响取值范围。

  1. 浮点型
    float(M,D) M是总长度,D小数的位数 存储空间4B
    double(M,D) 存储空间8B ???
   MariaDB [test]> create table num(
    -> tiny tinyint,
    -> small smallint,
    -> medium mediumint,
    -> nint  int,
    -> big bigint);
MariaDB [test]> desc num;
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| tiny   | tinyint(4)   | YES  |     | NULL    |       |
| small  | smallint(6)  | YES  |     | NULL    |       |
| medium | mediumint(9) | YES  |     | NULL    |       |
| nint   | int(11)      | YES  |     | NULL    |       |
| big    | bigint(20)   | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

MariaDB [test]> select * from num;
+------+-------+---------+-----------+-----------+
| tiny | small | medium  | nint      | big       |
+------+-------+---------+-----------+-----------+
|  127 | 32767 | 8388607 | 123456789 | 123456789 |
+------+-------+---------+-----------+-----------+

无符号数例:

MariaDB [test]> create table unnum( tiny tinyint unsigned, small smallint unsigned);
MariaDB [test]> insert into unnum values (123456789,123456789);
MariaDB [test]> select * from unnum;
+------+-------+
| tiny | small |
+------+-------+
|  255 | 65535 |
+------+-------+

zerofill:零填充,补0
id

001
010
100

MariaDB [test]> create table zf (id tinyint zerofill);
MariaDB [test]> insert into zf values (1);
MariaDB [test]> insert into zf values (11);
MariaDB [test]> insert into zf values (111);
MariaDB [test]> select * from zf ;
+------+
| id   |
+------+
|  001 |
|  011 |
|  111 |
+------+

1.2 字符串类型

  • char 定长字符串 如:char(10) 占用10个字节 括号中的长度范围1~255
  • varchar 变长字符串 varchar(10) 按照存的字符串的长度分配 括号中的长度范围0~65535
    例:存字符A使用varchar会占用2个字节的存储空间
    为什么是2字节?
    变长字符串需要1个或2个字节存储字符串的长度

values char(4) storage varchar(4) storage
‘’ ’ ’ 4B ‘’ 1B
‘AB’ 'AB ’ 4B ‘AB’ 3B
‘ABCD’ ‘ABCD’ 4B ‘ABCD’ 5B
‘ABCDEF’ ‘ABCD’ 4B ‘ABCD’ 5B

对于char型,存储时候长度不够,默认会在字符串后面补空格,但是查询时,空格会被脱掉。

  • enum:枚举类型 多个给定值中选择一个 -------------- 单选
  • set:集合类型 多个给定值中选者一个或多个 -------------- 不定项选择

1.3 日期时间类型

DATE:日期型  3字节
    格式:'YYYY-MM-DD'

TIME:
    格式:'HH:MM:SS'

DATETIME
    格式:'YYYY-MM-DD HH:MM:SS'

TIMESTAMP
    格式:'YYYY-MM-DD HH:MM:SS'

YEAR
    格式:'YYYY'
    MariaDB [test]> create table time_test(
    -> d date,
    -> t time,
    -> dt datetime,
    -> ts timestamp,
    -> y year);
Query OK, 0 rows affected (0.04 sec)    

MariaDB [test]> insert into time_test values(now(),now(),now(),now(),now());

    MariaDB [test]> select * from time_test;
+------------+----------+---------------------+---------------------+------+
| d          | t        | dt                  | ts                  | y    |
+------------+----------+---------------------+---------------------+------+
| 2017-06-01 | 10:17:07 | 2017-06-01 10:17:07 | 2017-06-01 10:17:07 | 2017 |
+------------+----------+---------------------+---------------------+------+

2 约束

约束也叫完整性约束

  • 完整性:是指数据库中存放的数据是有意义的、正确的
  • 约束:为了保证数据的正确性和相容性,对关系模型提出的某些约束条件或者规则
    注意:约束一般用于字段上

约束有哪些?

非空唯一默认主键外键自增
not nulluniquedefaultprimary keyforeign keyauto_increment

语法:字段名 数据类型[宽度|not null|unique|default 默认值|auto_increment|

2.1 默认值

 MariaDB [test]> create table t1(name varchar(10),sex char(10) default 'male' );
    MariaDB [test]> insert into t1 values();
    Query OK, 1 row affected (0.02 sec)
    MariaDB [test]> select * from t1;
    +------+------+
    | name | sex  |
    +------+------+
    | NULL | male |
    +------+------+
    1 row in set (0.00 sec)

默认值:当用户向表中插入数据时,指定了该字段的值,那么就插入该值,否则就插入默认值

修改默认值的两种方法

  MariaDB [test]> alter table t1 modify sex varchar(10) default 'jim';
MariaDB [test]> alter table t1 alter sex set default 'tom';

2.2 非空 not null

   MariaDB [test]> select * from t1 where name is null;   #查询name字段为null的行
    MariaDB [test]> select * from t1 where name is not null;  #查询name字段为不为null的行
    MariaDB [test]> create table t2 (id int not null ,name char(10));
    MariaDB [test]> insert into t2 values();
    MariaDB [test]> select * from t2;    #会将不允许为空的id字段转换成0
    +----+------+
    | id | name |
    +----+------+
    |  0 | NULL |
    +----+------+

字段类型为字符串型,非空约束会将空值转换成空字符串

  MariaDB [test]> alter table t2 modify name char(10) not null;
    MariaDB [test]> select * from t2;
    +----+------+
    | id | name |
    +----+------+
    |  0 |      |
    +----+------+

2.3 唯一

MariaDB [test]> create table t3 (id int unique,name char (10));
MariaDB [test]> insert into t3 values ();
MariaDB [test]> insert into t3 values ();   #唯一性约束对空值无效
MariaDB [test]> select * from t3;
+------+------+
| id   | name |
+------+------+
|    1 | jim  |
|    2 | jim  |
| NULL | NULL |
| NULL | NULL |
+------+------+
4 rows in set (0.00 sec)

MariaDB [test]> insert into t3 values (1,'tom');   
ERROR 1062 (23000): Duplicate entry '1' for key 'id'

2.4 自增 auto_increment

    要求:
 >1)该字段必须是数值型
    2)字段上要有唯一性索引或者主键
 MariaDB [test]> create table t5 (
        -> id int primary key auto_increment,name char(10));

    MariaDB [test]> desc t5;
    +-------+----------+------+-----+---------+----------------+
    | Field | Type     | Null | Key | Default | Extra          |
    +-------+----------+------+-----+---------+----------------+
    | id    | int(11)  | NO   | PRI | NULL    | auto_increment |
    | name  | char(10) | YES  |     | NULL    |                |
    +-------+----------+------+-----+---------+----------------+

    MariaDB [test]> insert into t5 values ();    #id 为1
    MariaDB [test]> insert into t5 values ();    #id 为2
    MariaDB [test]> insert into t5 values (6);  #id 为6
    MariaDB [test]> insert into t5 values ();    #id 为7
总结:
1.当自增字段发生断档时,值会从最大值继续自增
2.delete删除最大值时,下一个值仍然从删除之前的最大值继续自增
3.当truncate表时,值从1开始重新计算         DDL   

2.5 主键

    主键是表中的特殊字段,这个字段能够唯一标识表中的每一条记录。
    一张表只能有一个主键
    主键的用途:快速定位数据
    主键要满足的条件:非空且唯一
    primary key == not null  + unique

    1)使用单个字段做主键
        a、在字段后直接指定主键约束(列级约束,默认值为null)
 MariaDB [test]> create table t6 (id int primary key,age int , name char(10));
            MariaDB [test]> desc t6;
            +-------+----------+------+-----+---------+-------+
            | Field | Type     | Null | Key | Default | Extra |
            +-------+----------+------+-----+---------+-------+
            | id    | int(11)  | NO   | PRI | NULL    |       |
            | age   | int(11)  | YES  |     | NULL    |       |
            | name  | char(10) | YES  |     | NULL    |       |
            +-------+----------+------+-----+---------+-------+
            3 rows in set (0.00 sec)

            MariaDB [test]> insert into t6 values (1,15,'jim');
            MariaDB [test]> insert into t6 values (1,16,'tom');
                ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
                
            MariaDB [test]> insert into t6 values();
            MariaDB [test]> insert into t6 values();
                ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'

        b、整张表的所有字段都定义完成之后再来指定主键(表级约束,默认值是0)
            MariaDB [test]> create table t8 ( id int,name char(10),primary key (id));
            MariaDB [test]> desc t8;
            +-------+----------+------+-----+---------+-------+
            | Field | Type     | Null | Key | Default | Extra |
            +-------+----------+------+-----+---------+-------+
            | id    | int(11)  | NO   | PRI | 0       |       |
            | name  | char(10) | YES  |     | NULL    |       |
            +-------+----------+------+-----+---------+-------+
            MariaDB [test]> insert into t8 values ();
            MariaDB [test]> insert into t8 values ();
            ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'

            MariaDB [test]> insert into t8 values (1,'jim');
            MariaDB [test]> insert into t8 values (1,'tom');
            ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
    2)多个字段做联合主键    
        注意:联合主键只能在所有字段都定义完成之后,才能定义主键。
        MariaDB [test]> desc mysql.user\G;    #host和user字段做联合主键
  ***************** 1. row ************
          Field: Host
           Type: char(60)
           Null: NO
            Key: PRI
        Default: 
          Extra: 
        ****************** 2. row ************
          Field: User
           Type: char(16)
           Null: NO
            Key: PRI
        Default: 
          Extra: 
        ******************* 3. row ************
          Field: Password
           Type: char(41)
           Null: NO
            Key: 
        Default: 
          Extra: 

        HOST           NAME   PASSWORD
        127.0.0.1     root      123
        127.0.0.1     tom      123
        127.0.0.1     root      456
        192.168.1.2 root      456

        MariaDB [test]> create table t8 ( HOST char(15),NAME char(10),PASSWORD char(50) ,primary key (HOST,NAME));

2.6 外键 foreign key

外键:一个表的数据依赖另一张表的主键列的数据,如果在主键列没有出现的值,是不能够出现在外键字段的。

创建外键的条件:
1)存储引擎必须是innodb
2)相关联字段数据类型要一致
3)最好在外键列上建索引(目的是为了减少扫描范围,不创建也可以,值是影响性能)

例:
class 班级表 (父表)

IDClass
1yun 0215
2yun 0308
3yun 0316
4yun 0411

student (子表)

CLASS_IDNAMEAGE
1jim18
1tom19
2xiao20
2ming21
5hong19

创建父表

MariaDB [test]> create table class (ID int primary key,class char(20));

创建子表

MariaDB [test]> create table student (CLASS_ID int,NAME char(20),AGE int,foreign key(CLASS_ID)  references class(ID));

向父表内插入数据

MariaDB [test]> insert into class values(1,'yun0215'),
            -> (2,'yun0308'),
            -> (3,'yun0316'),
            -> (4,'yun0411');
        MariaDB [test]> select * from class;
        +----+---------+
        | ID | class   |
        +----+---------+
        |  1 | yun0215 |
        |  2 | yun0308 |
        |  3 | yun0316 |
        |  4 | yun0411 |
        +----+---------+

向子表内插入数据

  MariaDB [test]> insert into student values 
            -> (1,'jim',18),
            -> (1,'tom',19),
            -> (2,'xiao',20);
MariaDB [test]> insert into student values (5,'hong',19);   #插入父表中不存在的班级号
    ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`CLASS_ID`) REFERENCES `class` (`ID`))
MariaDB [test]> delete from class where ID=1;   #删除父表中有外键依赖的数据
            ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`CLASS_ID`) REFERENCES `class` (`ID`))

总结:

  • 子表中的关联数据依赖于父表,不能向子表中插入父表中不存在的值
    2)不能删除父表中被子表所依赖的记录

  • 删除父表中被依赖的行的方法:
    1)删除外键约束
    2)指定级联操作的选项

on delete cascade 级联删除
on update cascade 级联更新

 MariaDB [test]> drop table student;
    
    MariaDB [test]> create table student (CLASS_ID int ,NAME char(20),AGE int,foreign key(CLASS_ID) references class (ID) on delete cascade on update cascade);
    
    MariaDB [test]> insert into student values 
        -> (1,'jim',18), 
        -> (1,'tom',19),
        -> (2,'xiao',20),
        -> (2,'ming',21);
        
    MariaDB [test]> select * from student;
    +----------+------+------+
    | CLASS_ID | NAME | AGE  |
    +----------+------+------+
    |        1 | jim  |   18 |
    |        1 | tom  |   19 |
    |        2 | xiao |   20 |
    |        2 | ming |   21 |
    +----------+------+------+
    
    MariaDB [test]> delete from class where ID=2;
    
    MariaDB [test]> select * from class;
    +----+---------+
    | ID | class   |
    +----+---------+
    |  1 | yun0215 |
    |  3 | yun0316 |
    |  4 | yun0411 |
    +----+---------+
    
    MariaDB [test]> select * from student;
    +----------+------+------+
    | CLASS_ID | NAME | AGE  |
    +----------+------+------+
    |        1 | jim  |   18 |
    |        1 | tom  |   19 |
    +----------+------+------+
    
    MariaDB [test]> update class set ID=2 where ID=1;

    MariaDB [test]> select * from class;
    +----+---------+
    | ID | class   |
    +----+---------+
    |  2 | yun0215 |
    |  3 | yun0316 |
    |  4 | yun0411 |
    +----+---------+
    
    MariaDB [test]> select * from student;
    +----------+------+------+
    | CLASS_ID | NAME | AGE  |
    +----------+------+------+
    |        2 | jim  |   18 |
    |        2 | tom  |   19 |
    +----------+------+------+

总结:有了级联删除和级联更新选项,父表中的数据发生删除或者更新时,子表中相关数据也会发生相应的变化。

删除外键
语法:

alter table 表名 drop foreign key 外键的名字

查看外键的名字

  MariaDB [test]> show create table student\G;   #红色字体为外键的名字
            **************** 1. row **************
                   Table: student
            Create Table: CREATE TABLE `student` (
              `CLASS_ID` int(11) DEFAULT NULL,
              `NAME` char(20) DEFAULT NULL,
              `AGE` int(11) DEFAULT NULL,
              KEY `CLASS_ID` (`CLASS_ID`),
              CONSTRAINT `student_ibfk_1` FOREIGN KEY (`CLASS_ID`) REFERENCES `class` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE
            ) ENGINE=InnoDB DEFAULT CHARSET=latin1
            1 row in set (0.03 sec)

            ERROR: No query specified

    MariaDB [test]> alter table student drop foreign key student_ibfk_1; 

    MariaDB [test]> show create table student\G; 
    *************** 1. row ***************
           Table: student
    Create Table: CREATE TABLE `student` (
      `CLASS_ID` int(11) DEFAULT NULL,
      `NAME` char(20) DEFAULT NULL,
      `AGE` int(11) DEFAULT NULL,
      KEY `CLASS_ID` (`CLASS_ID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1
    1 row in set (0.00 sec)

3 练习

  1. 在qiangfeng库中创建一个表 stu_info ,有如下字段:
    stu_id 整型,数据不能为空,不能重复. 学生人数最多4万左右
    stu_name 字符串,学生名字为2-16个英文字符,不能为空
    sex 字符串,性别为male或female,不能为空
    phone 手机号码,国内手机号码为11位数字,不能为空
    QQ QQ号, 5-11位数字,可以为空

创建此表,并使用合适的数据类型及约束

use qianfeng
create table stu_info (
stu_id mediumint primary key,
stu_name char(16) not null,
sex enum('male','female') not null,
phone bigint not null,
QQ bigint);
  1. 在qiangfeng库中创建一个表 score, 有如下字段
    id 整型, 只有在 stu_info 存在的数据才可以insert进来
    linux 整型, 此字段及以下字段内容都是0-100的数字
    shell 整型
    mysql 整型
create table score (
id smallint,
linux int,
shell int,
mysql int,
foreign key(id) reference stu_info(stu_id));
  1. 往以上两表中导入数据.
    stu_id从1开始,依次递增
    stu_name为系统用户所有的用户名
    sex随机
    phone随机
    QQ随机
    linux,shell,mysql随机,范围为0-100
#!/bin/bash
i=1
while read line;do
        stu_id=$i
        let i++
        stu_name=$(echo $line|awk -F: '{print $1}')
        shuiji=$[RANDOM%2]
        [ $shuiji -eq 0 ] && sex='male' || sex='female'
        phone=$[RANDOM% 10000+ 10000]$[RANDOM% 99999+ 10000]$[RANDOM% 9+1]
        QQ=$[RANDOM% 900+100]$[RANDOM%10000]$[RANDOM% 10000]
        linux=$[RANDOM% 101]
        shell=$[RANDOM% 101]
        mysql=$[RANDOM% 101]
        echo $stu_id$stu_name$sex$phone$QQ$linux$shell$mysql
done < /etc/passwd

方法2

#!/bin/bash
j=1
sx=(female male)
ph=(13 14 15 17 18 19)
for i in $(awk -F: '{print $1}' /etc/passwd);do
        stu_name=$i
        stu_id=$j
        sex=${sx[RANDOM%2]}
        phone=${ph[RANDOM%6]}$[RANDOM%90000+10000]$[RANDOM%9000+1000]
       
        #生成随机的QQ
        n5=$[RANDOM%9+1]$[RANDOM%10]$[RANDOM%10]$[RANDOM%10]$[RANDOM%10]
        n6=$n5$[RANDOM%10]
        n7=$n6$[RANDOM%10]
        n8=$n7$[RANDOM%10]
        n9=$n8$[RANDOM%10]
        n10=$n9$[RANDOM%10]
        n11=$n10$[RANDOM%10]
        qq=($n5 $n6 $n7 $n8 $n9 $n10 $n11)
        k=$[RANDOM%7]
        QQ=${qq[k]}
       
        linux=$[RANDOM%101]
        shell=$[RANDOM%101]
        mysql=$[RANDOM%101]
        mysql -e "insert into qianfeng.stu_info values ($stu_id,'$stu_name','$sex',$phone,$QQ);"
        mysql -e "insert into qianfeng.score values ($stu_id,$linux,$shell,$mysql);"
        let j++
done 

方法3

#!/bin/bash
i=1
while read line;do
    stu_name=`echo $line|awk -F: '{print $1}'`
    stu_id=$i
    let i++
    [ $[RANDOM%2] -eq 1 ] && sex="male" || sex="female"
    a=$[RANDOM%7+3]
    b=
    for((j=1;j<=9;j++));do
        b=$b$[RANDOM%10]
    done
    phone=1$a$b
    qqa=$[RANDOM%7+4]
    qqb=$[RANDOM%8+1]
    qqc=
    for c in `seq $qqa`;do
        qqc=$qqc$[RANDOM%10]
    done
    qq=$qqb$qqc
    #mysql -p1 -e "insert into qianfeng.stu_info values($stu_id,'$stu_name','$sex','$phone','$qq')"
    linux=$[RANDOM%101]
    shell=$[RANDOM%101]
    mysql=$[RANDOM%101]
    mysql -p1 -e "insert into qianfeng.score values($stu_id,$linux,$shell,$mysql)"
done < /etc/passwd 

  1. 创建一个表stu_score,内容为所有学生的id,姓名及各科的分数
create table stu_score select * from score;
alter table stu_score add stu_name varchar(16) after id;
insert into stu_score(stu_name) select stu_name from stu_info;
  1. 在stu_score表的id列创建索引
create index id on stu_score(id);
  1. 将stu_score表的存储引擎修改为myisam
alter table stu_score engine=myisam

Reference

  1. 课堂笔记
  2. 课堂作业
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值