day--37 msyql 表,库,行操作 小结

                                     MySQL数据库 表,库,行操作

一:创建数据库
01:创建方式:
create databases 数据库名 charsetutf8
02:数据库命名规则:(基本和python和js一样)
001:字母,数字,下划线,@,#,$
002:区分大小写
003:唯一性
004:不能使用数据库的关键字,如create select
005:不能用纯数字
006:最长128位

二:数据库基本操作:
01:数据库操作:(增删改查)
001:查看数据库:
01:show databases;
02:show create databases 数据库名;
例子:
mysql> show create database day01;
+----------+----------------------------------------------------------------+
| Database | Create Database |
+----------+----------------------------------------------------------------+
| day01 | CREATE DATABASE `day01` /*!40100 DEFAULT CHARACTER SET utf8 */ |
+----------+----------------------------------------------------------------+
1 row in set (0.00 sec)

03:select databases();

002:选择数据库
use 数据库名;

003:删除数据库
drop database 数据库名;

004:修改数据库
alter database 数据库名 utf8;

三:存储引擎:
1:存储引擎:
存储引擎即表类型,mysql根据不同的表类型会有不同的处理机制,存储引擎的概念是MySQL才有的,不是所有的关系型数据库都有这个概念。
2:关系型的数据库中,数据是以表的形式存储的,所以存储引擎也可以称之为表类型,(即:对表的存储、操作等的实现方法不同),表是什么,
表本质上就是磁盘上的文件。,MySQL支持多种存储引擎,每种引擎有着一些自己独特的功能,用户在使用的时候,可以根据自己的业务场景
来使用不同的存储引擎,其中MySQL最常用的存储引擎为:MyISAM和InnoDB。
MySQL默认有一个存储引擎,我记得MySQL5.5之前,默认的存储引擎是MyISAM,之后都改为InnoDB了,我们的重点就是这个InnoDB,也是
公司中最常用的、最好用的引擎,但是还是一些公司在用MyISAM引擎,除了历史原因之外,还有MyISAM的效率比InnoDB高一点,InnoDB在
这方面做了很多优化,效率已经和MyISAM差不多了,但是InnoDB引擎还有好多其他的NB的功能,下面我们就介绍几种存储引擎。

3:创建表时指定存储引擎
01:先看我们mysql默认的存储引擎

#截取部分代码:
mysql> show create table t1;

| t1 | CREATE TABLE `t1` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`age` int(3) DEFAULT NULL,
`name` char(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 |

显示我们用的默认的存储引擎是InnoDB:ENGINE=InnoDB。

02:我们还可以查看mysql支持的所有引擎:
show engines:
03:查看我们当前使用的引擎:
mysql> show variables like "storage_engine%";
+----------------+--------+
| Variable_name | Value |
+----------------+--------+
| storage_engine | InnoDB |
+----------------+--------+
1 row in set (0.06 sec)
注意:在存储大文件的时候,可以存到数据库,但是尽量别直接存到数据库里面,会影响数据库的效率,我们就存文件的路径、地址,
用户想要这个大文件,我们可以到对应的路径下取读取这个文件给用户。
04:存储引擎的使用:
001:创建数据库时指定存储引擎:
mysql> create table t3(id int) engine=innodb;
Query OK, 0 rows affected (0.17 sec)

002:在配置文件中指定默认的存储引擎:
linux:vim /etc/my.cnf windows:my.ini文件
[mysqld]
default-storage-engine=INNODB #配置默认引擎,现在用的mysql默认基本都是InnoDB,所以其实都可以不用配置了
innodb_file_per_table=1 #表示独立表空间存储,可以不写

003:不同的引擎在创建表时生成的文件不同
创建四个表,分别使用innodb,myisam,memory,blackhole存储引擎,进行插入数据测试
创建文件后缀名的含义:
1.db.opt文件:用来记录该库的默认字符集编码和字符集排序规则用的。也就是说如果你创建数据库指定默认字符集和排序规则,
那么后续创建的表如果没有指定字符集和排序规则,那么该新建的表将采用db.opt文件中指定的属性。
2.后缀名为.frm的文件:这个文件主要是用来描述数据表结构(id,name字段等)和字段长度等信息
3.后缀名为.ibd的文件:这个文件主要储存的是采用独立表储存模式时储存数据库的数据信息和索引信息;
4.后缀名为.MYD(MYData)的文件:从名字可以看出,这个是存储数据库数据信息的文件,主要是存储采用独立表储存模式时存储的数据信息;
5.后缀名为.MYI的文件:这个文件主要储存的是数据库的索引信息;
6.ibdata1文件:主要作用也是储存数据信息和索引信息,这个文件在mysql安装目录的data文件夹下。
从上面可以看出,.ibd储存的是数据信息和索引信息,ibdata1文件也是存储数据信息和索引信息,.MYD和.MYI也是分别储存数据信息和索引信息,那他们之间有什么区别呢?
主要区别是再于数据库的存储引擎不一样,如果储存引擎采用的是MyISAM,则生成的数据文件为表名.frm、表名.MYD、表名的MYI;
而储存引擎如果是innoDB,开启了innodb_file_per_table=1,也就是采用独立储存的模式,生成的文件是表名.frm、表名.ibd,
如果采用共存储模式的,数据信息和索引信息都存储在ibdata1(在里面进行分类,从外面看是一个文件)中;
在进行数据恢复的时候,如果用的是MYISAM数据引擎,那么数据很好恢复,只要将相应.frm, .MYD, .MYI文件拷贝过去即可。但是
如果是innodb的话,则每一个数据表都是一个单独的文件,只将相应的.frm和.ibd文件拷贝过去是不够的,必须在你的ibd文件的
tablespace id和ibdata1文件中的元信息的tablespace id一致才可以。msyql人家设定的规则就是这样存储表的,使用人家的系统,
就要理解人家的规则。

Oracle中不存在引擎的概念,数据处理大致可以分成两大类:联机事务处理OLTP(on-line transaction processing)、联机分析处理
OLAP(On-Line Analytical Processing)。OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如银行交易。
OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果

四:表操作
01:基本操作:
表:相当于文件,表中德一条记录就相当于文件的一行内容,表中的一条记录有对应的标题,称为字段。
例子:
创建表:
mysql> create table t1(id int,name char,age int);
Query OK, 0 rows affected (0.17 sec)

查看创建的表:
mysql> desc t1;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | char(1) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
3 rows in set (0.04 sec)

往表里面添加数据:按照表里面的格式添加:-->insert into t1 values
mysql> insert into t1 values(1,"张三",12),(2,"李斯特",23),(3,"Tom",19);
Query OK, 3 rows affected, 3 warnings (0.07 sec)
Records: 3 Duplicates: 0 Warnings: 3

显示刚刚添加的效果:
mysql> desc t1;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | char(1) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)

只想显示id和名字:
select id,name from t1;

查看某一个数据库下面的表:
use 数据库名;
show tables;

删除数据库:
drop 数据库名;

删除一个表: drop table 表的名字;

查看表结构:desc 表名;

查看详细结构: show cteate table t2\G;

02:表的名字和字段的修改
000:修改表alter table
001:修改表名:
alter table 旧名字 rename 新名字;
002:增加字段
语法:alter table 表名 add 字段名
1. 修改表名
ALTER TABLE 表名 RENAME 新表名;

2. 增加字段
ALTER TABLE 表名 ADD 字段名 数据类型 [完整性约束条件…],ADD 字段名 数据类型 [完整性约束条件…];
#注意这里可以通过逗号来分割,一下添加多个约束条件

ALTER TABLE 表名 ADD 字段名 数据类型 [完整性约束条件…] FIRST; #添加这个字段的时候,把它放到第一个字段位置去。

ALTER TABLE 表名 ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名;#after是放到后的这个字段的后面去了,我们通过一个first和一个after就可以将新添加的字段放到表的任意字段位置了。

3. 删除字段
ALTER TABLE 表名 DROP 字段名;

4. 修改字段
ALTER TABLE 表名 MODIFY 字段名 数据类型 [完整性约束条件…];

ALTER TABLE 表名 CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…]; #change比modify还多了个改名字的功能,这一句是只改了一个字段名

ALTER TABLE 表名 CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];#这一句除了改了字段名,还改了数据类型、完整性约束等等的内容

注意一点:在mysql里面表名是不区分大小写的,如果你将一个名为t1的(小写的t1)改名为一个T1(大写的T1),是完全没用的,因为在数据库里面表名都是小写的。

03:存储引擎的修改
1. 修改存储引擎
mysql> alter table 表名;
-> engine=innodb;

2. 添加字段
mysql> alter table 表名字
-> add ages int(3) not null default 22;

添加案例:
mysql> alter table tt
-> add ages varchar(20) not null;
Query OK, 0 rows affected (0.25 sec)
Records: 0 Duplicates: 0 Warnings: 0

显示效果:
mysql> desc tt;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| name | char(10) | YES | | NULL | |
| xx | char(100) | YES | | NULL | |
| ages | varchar(20) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

3:添加到name字段之后:
mysql> alter table student10
-> add stu_num varchar(10) not null after name; //添加name字段之后
显示例子:
mysql> alter table tt
-> add sut_num char not null after name;
Query OK, 0 rows affected (0.34 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> desc tt;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| name | char(10) | YES | | NULL | |
| sut_num | char(1) | NO | | NULL | |
| xx | char(100) | YES | | NULL | |
| ages | varchar(20) | NO | | NULL | |
+---------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

4:删除字段:
mysql> alter table tt #删除的命令;
-> drop xx;
Query OK, 0 rows affected (0.28 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> desc tt;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| name | char(10) | YES | | NULL | |
| sut_num | char(1) | NO | | NULL | |
| ages | varchar(20) | NO | | NULL | |
+---------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
5:修改字段类型modify
mysql> alter table tt
-> modify age int(3); #将原来的11长度 改为3
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> desc tt;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| age | int(3) | YES | | NULL | |
| name | char(10) | YES | | NULL | |
| sut_num | char(1) | NO | | NULL | |
| ages | varchar(20) | NO | | NULL | |
+---------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

6:增加约束(针对已有的主键增加auto_increment)
说明:id 允许
mysql> alter table tt modify id int (20) not null primary key auto_increment;
Query OK, 0 rows affected (1.29 sec)
Records: 0 Duplicates: 0 Warnings: 0

显示:
mysql> desc tt;
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| id | int(20) | NO | PRI | NULL | auto_increment |
| age | int(3) | YES | | NULL | |
| name | char(10) | YES | | NULL | |
| sut_num | char(1) | NO | | NULL | |
| ages | varchar(20) | NO | | NULL | |
+---------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

7:对已经存在的表增加复合主键


8:删除主键
a:删除自增约束

9:往表格里面添加数据后,然后打印显示:(tt是表格名)
先查看一下表格的结构:
mysql> desc tt;
+-------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+----------------+
| id | int(20) | NO | PRI | NULL | auto_increment |
| age | int(3) | YES | | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

再添加内容:
mysql> insert into tt values(1,23,"xxx"),(2,21,"张三"),(3,"李斯特",12);
Query OK, 3 rows affected, 1 warning (0.06 sec)
Records: 3 Duplicates: 0 Warnings: 1

先生添加=内容后的效果:
mysql> select * from tt;
+----+------+-----------+
| id | age | name |
+----+------+-----------+
| 1 | 23 | xxx |
| 2 | 21 | 张三 |
| 3 | 0 | 12 |
+----+------+-----------+
3 rows in set (0.00 sec)
将表格名字修改为t1;
alter table 旧名字 rename 新名字;

mysql> show tables;
+---------------+
| Tables_in_day |
+---------------+
| t1 | #表格名字已经修改
+---------------+
1 row in set (0.00 sec)

显示一下现在表格t1的样子:
mysql> select * from t1;
+----+------+-----------+
| id | age | name |
+----+------+-----------+
| 1 | 23 | xxx |
| 2 | 21 | 张三 |
| 3 | 0 | 12 |
+----+------+-----------+
3 rows in set (0.00 sec)

???怎么将xxx 修改呢? ##################################################################

#################
10:对已经存在的表增加复合主键
alter table tt


11:复制表:
01:语法:复制表结构+记录 (key不会复制: 主键、外键和索引)

#这句话的意思是:从t1表中C查询出来的数据不用打印出来了,直接给新建的表t2 就可以了
例子:mysql> create table t2 select * from t1;
先查看一下t1表的结构:
mysql> desc t1;
+-------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+----------------+
| id | int(20) | NO | PRI | NULL | auto_increment |
| age | int(3) | YES | | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

#查看t1表的内容:
mysql> select * from t1;
+----+------+-----------+
| id | age | name |
+----+------+-----------+
| 1 | 23 | xxx |
| 2 | 21 | 张三 |
| 3 | 0 | 12 |
+----+------+-----------+
3 rows in set (0.00 sec)

执行复制表操作后:
mysql> create table t2 select * from t1;
Query OK, 3 rows affected (0.20 sec)
Records: 3 Duplicates: 0 Warnings: 0

显示当前库中有多少个表格:
mysql> show tables;
+---------------+
| Tables_in_day |
+---------------+
| t1 |
| t2 |
+---------------+
2 rows in set (0.00 sec)

#显示表2 的内容
mysql> select * from t2;
+----+------+-----------+
| id | age | name |
+----+------+-----------+
| 1 | 23 | xumingkai |
| 2 | 21 | 张三 |
| 3 | 0 | 12 |
+----+------+-----------+
3 rows in set (0.00 sec)

再查看t2表的结构:
mysql> desc t2;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(20) | NO | | 0 | |
| age | int(3) | YES | | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

#观察:
#比较t1和t2 的内容,可以发现复制后,t1表的Key 和 Extra 没有 复制给t2表
虽然不能复制,但是我们可以给其添加回去:
操作:
mysql> alter table t2 modify id int primary key auto_increment;
Query OK, 3 rows affected (0.44 sec)
Records: 3 Duplicates: 0 Warnings: 0

mysql> desc t2;
+-------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| age | int(3) | YES | | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
02:只复制表结构,不复制数据
我要一个只有结构没有数据的表t3
第一种:
操作代码:
mysql> create table t3 like t2; #主要代码
Query OK, 0 rows affected (0.14 sec)

mysql> select * from t3;
Empty set (0.00 sec)

查看t3显示:里面是空的数据
mysql> select * from t3;
Empty set (0.00 sec)

再查看t3的结构:里面的结构和t2也是一样的。
mysql> desc t3;
+-------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| age | int(3) | YES | | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

第二种:复制一份t4 没有数据,只有结构的t4
#where 1=2筛选数据的条件为假,那么只拿到了结构,并没有查询出任何的数据,所以做到了只复制表结构
mysql> create table t4 select * from t2 where 1=2; #主要代码
Query OK, 0 rows affected (0.20 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> show tables;
+---------------+
| Tables_in_day |
+---------------+
| t1 |
| t2 |
| t3 |
| t4 |
+---------------+
4 rows in set (0.00 sec)

mysql> select * from t4;
Empty set (0.00 sec)
第一种和第二种的区别呢?###################################

五:MySQL基本数据类型:
01: 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型。每种数据类型都有自己的宽度,但是
宽度是可选的。

mysql常用数据类型:
1:数字类型:
整型:tinyint int bigint
小数:
float:在位数比较短的情况下不精准
double:在位数比较短的情况下不精准
0.000001230123123123 存成 0.000001230000

decimal:小数,精准,内部是用字符串形式去存的

2:字符串:
char(10):简单,但是浪费时间,存取速度快
root存成root000000
varchar:精准,节省空间,存取速度慢

aql:创建表时,定长的类型往前放(比如性别),变长的往后放(地址等描述信息)

大于255个字符,超过了这个长度就把文件路径存放在数据库中,比如图片,视频等找一个文件服务器,
数据库只存放路径或则url
3:时间类型:
最常用:database

4:枚举类型与集合类型

02:数值类型:
01:整数类型:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT
整型用来存储:年龄,等级,id,号码等

tinyint[(m)] [unsigned] [zerofill]
小整数,数据类型用来保存一些范围的整数数字范围
有符号: -128--127
无符号: 0--255
ps;mysql中无布尔值,使用tinyint(1)构造

使用案例:因为tinyint 的范围是-128--127,我们先尝试插入一个-128数字看看
删除多个表:drop tables t1,t2,t3,t4..

创建一个表t2,里面声明id数据类型是tinyint类型:
mysql> create table t2(id tinyint);
Query OK, 0 rows affected (0.30 sec)

往t2插入一个数字
mysql> insert into t2 values(-128);
Query OK, 1 row affected (0.10 sec)

显示查看一下t2表的结构:
mysql> desc t2;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id | tinyint(4) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)

再查看一下它的数据内容:
mysql> select * from t2;
+------+
| id |
+------+
| -128 |
+------+
1 row in set (0.00 sec)
显示在范围内时已经插入。

我们再插入-129 看看是否成功:
mysql> insert into t2 values(-129);
Query OK, 1 row affected, 1 warning (0.05 sec)
没有报错,但是显示的是-128。但是有一个警告,为什么呢?
因为它的范围就是-128,超过就给你显示-128,我们希望它在我插入超过范围时候能报错。提示我。

解决办法:
第一步:我们先查下它的sql模式
mysql> select @@sql_mode;
+------------------------+
| @@sql_mode |
+------------------------+
| NO_ENGINE_SUBSTITUTION |
+------------------------+
1 row in set (0.00 sec)


解决步骤:
NO_ENGINE_SUBSTITUTION:显示没有指定sql模式。那我们那样插入是不会报错了。
我们先创建一个t3表,指定字符类型是tinyint,而且是指定是(unsigned)无符号的
mysql> create table t3(num tinyint unsigned);
Query OK, 0 rows affected (0.16 sec)

然后我们插入一个数字-129给表t3;
mysql> insert into t3 value(-129);
Query OK, 1 row affected, 1 warning (0.05 sec)

mysql> select * from t3;
+------+
| num |
+------+
| 0 |
+------+
1 row in set (0.00 sec)

显示结果是一个 0 (tinyint在无符号的时候,他的范围是0-255)
在符号的情况下再插入一个超过它的数字256 (无符号的范围在 0--255)
mysql> insert into t3 value(256);
Query OK, 1 row affected, 1 warning (0.05 sec)

mysql> select * from t3;
+------+
| num |
+------+
| 0 |
| 255 |
+------+
2 rows in set (0.00 sec)

显示插入的是255,因为插入的数据已经超过它的无符号的最大范围了,所以只能最大显示。

1:有符号和无符号的tinyint
01:tinyint 默认为有符号(范围是 -127--127)
使用实例:
01:创建一个有符号的表t4 默认为有符号
mysql> create table t4(x tinyint);
Query OK, 0 rows affected (0.17 sec)

02:查看结构看看:
mysql> desc t4;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| x | tinyint(4) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)

03:往里面添加值:
mysql> insert into t4 values
-> (-129),
-> (-128),
-> (127),
-> (128);
Query OK, 4 rows affected, 2 warnings (0.05 sec)
Records: 4 Duplicates: 0 Warnings: 2

04: 查看里面的值:
mysql> select * from t4;
+------+
| x |
+------+
| -128 | #-129存成了-128
| -128 | #-128正常存储,有符号,范围是-127--127
| 127 | #127正常村属,有符号,范围是-127--127
| 127 | #128存成了127,有符号。最大值是127
+------+
4 rows in set (0.00 sec)

02:设置无符号的t5表看看:
01:建立一个无符号表t5,范围是 0--255
mysql> create table t5(x tinyint unsigned);
Query OK, 0 rows affected (0.19 sec)

mysql> create table t5(x tinyint unsigned);
mysql> insert into t2 values
-> (-1),
-> (0),
-> (255),
-> (256);
mysql> select * from t5;
+------+
| x |
+------+
| 0 | -1存成了0
| 0 | #无符号,最小值为0
| 255 | #无符号,最大值为255
| 255 | #256存成了255
+------+

2:设置无符号的int
有符号:-2147483648 ~ 2147483647
无符号:0 ~ 4294967295

01:建一个无符号的int表 t6:int默认有符号

mysql> create table t6(x int unsigned);
Query OK, 0 rows affected (0.20 sec)

02:往里面添加值:
mysql> insert into t6 values
-> (-2147483649),
-> (-2147483648),
-> (2147483647),
-> (2147483648);

查看存的数据看看:
mysql> select * from t6;
+-------------+
| x |
+-------------+
| -2147483648 | #-2147483649存成了-2147483648
| -2147483648 | #有符号,最小值为-2147483648
| 2147483647 | #有符号,最大值为2147483647
| 2147483647 | #2147483648存成了2147483647
+-------------+

3.设置无符号int,无符号:0 ~ 4294967295
mysql> create table t7(x int unsigned);
mysql> insert into t7 values
-> (-1),
-> (0),
-> (4294967295),
-> (4294967296);
mysql> select * from t7;
+------------+
| x |
+------------+
| 0 | #-1存成了0
| 0 | #无符号,最小值为0
| 4294967295 | #无符号,最大值为4294967295
| 4294967295 | #4294967296存成了4294967295
+------------+


4:有符号和无符号bigint
有符号:-9223372036854775808 ~ 9223372036854775807

无符号:0 ~ 18446744073709551615


1.有符号bigint()范围:-9223372036854775808 ~ 9223372036854775807
mysql> create table t6(x bigint);
mysql> insert into t5 values
-> (-9223372036854775809),
-> (-9223372036854775808),
-> (9223372036854775807),
-> (9223372036854775808);

mysql> select * from t5;
+----------------------+
| x |
+----------------------+
| -9223372036854775808 |
| -9223372036854775808 |
| 9223372036854775807 |
| 9223372036854775807 |
+----------------------+


2.无符号bigint 范围:0 ~ 18446744073709551615
mysql> create table t6(x bigint unsigned);
mysql> insert into t6 values
-> (-1),
-> (0),
-> (18446744073709551615),
-> (18446744073709551616);

mysql> select * from t6;
+----------------------+
| x |
+----------------------+
| 0 |
| 0 |
| 18446744073709551615 |
| 18446744073709551615 |
+----------------------+

5:用zerofill测试整数类型的显示宽度
zerofill规定了插入的x的长度是在显示的时候必须是3位,而不是说存储的长度只能是3位,但是输入的数字不足三位的时,显示出来的时
候会在数字前面补0

我们重点测试下超过三位的看看
mysql> create table t7(x int(3) zerofill); #int(3),3表示的是显示的数字长度
mysql> insert into t7 values
-> (1),
-> (11),
-> (111),
-> (1111);
mysql> select * from t7;
+------+
| x |
+------+
| 001 |
| 011 |
| 111 |
| 1111 | #超过宽度限制仍然可以存
+------+

注意:对于整型来说,数据类型后面的宽度并不是存储长度限制,而是显示限制,假如:int(8),那么显示时不够8位则用0来填充,
够8位则正常显示,通过zerofill来测试,存储长度还是int的4个字节长度。默认的显示宽度就是能够存储的最大的数据的长度,
比如:int无符号类型,那么默认的显示宽度就是int(10),有符号的就是int(11),因为多了一个符号,所以我们没有必要指定整数类型的数据,
没必要指定宽度,因为默认的就能够将你存的原始数据完全显示

6:int的存储宽度是4个Bytes,即32个bit,即2**32  
  无符号最大值为:4294967296-1
  有符号最大值:2147483648-1
  有符号和无符号的最大数字需要的显示宽度均为10,而针对有符号的最小值则需要11位才能显示完全,所以int类型默认的显示宽度为11是非常合理的
  最后:整形类型,其实没有必要指定显示宽度,使用默认的就ok。


7:浮点型:
0. 定点数类型 DEC,等同于DECIMAL  
浮点类型:FLOAT DOUBLE
作用:存储薪资、身高、温度、体重、体质参数等


1.FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]

定义:单精度浮点数(非准确小数值),m是整数部分总个数,d是小数点后个数。m最大值为255,d最大值为30,例如:float(255,30)


有符号: -3.402823466E+38 to -1.175494351E-38,
1.175494351E-38 to 3.402823466E+38

无符号: 1.175494351E-38 to 3.402823466E+38



精确度: **** 随着小数的增多,精度变得不准确 ****




2.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要高,但也会变得不准确 ****



3.decimal[(m[,d])] [unsigned] [zerofill]

定义: 准确的小数值,m是整数部分总个数(负号不算),d是小数点后个数。 m最大值为65,d最大值为30。比float和double的整数个数少,但是小数位数都是30位



精确度: **** 随着小数的增多,精度始终准确 ****
对于精确数值计算时需要用此类型
decimal能够存储精确值的原因在于其内部按照字符串存储。

精度从高到低:decimal、double、float
decimal精度高,但是整数位数少
float和double精度低,但是整数位数多
float已经满足绝大多数的场景了,但是什么导弹、航线等要求精度非常高,所以还是需要按照业务场景自行选择,如果又要精度高又要整数位数多,那么你可以直接用字符串来存。


8:日期类型:
工作中一般都用datetime就可以了。 
01:YEAR--年
YYYY(范围:1901/2155)2018
例子:
01:创建一个表t2:
mysql> create table t2(shengri year);
Query OK, 0 rows affected (0.18 sec)

02:往里面添加时间;
mysql> insert into t2 values(1901),(1987),(2155),(2156),(2178);
Query OK, 5 rows affected, 2 warnings (0.05 sec)
Records: 5 Duplicates: 0 Warnings: 2

03:显示结果:
mysql> select * from t2;
+---------+
| shengri |
+---------+
| 1901 | #最小值1901
| 1987 |
| 2155 | #常显示,范围是1901--2155
| 0000 | #2156变成了0000,超过最高范围2156了
| 0000 | #2178变成了0000,超过最高范围2156了
+---------+
5 rows in set (0.00 sec)


02:DATE --年月日
YYYY-MM-DD(范围:1000-01-01/9999-12-31)例:2018-01-01

03:TIME
HH:MM:SS(范围:'-838:59:59'/'838:59:59')例:12:09:32

04:DATETIME
YYYY-MM-DD HH:MM:SS(范围:1000-01-01 00:00:00/9999-12-31 23:59:59 Y)例: 2018-01-01 12:09:32

date,time,datetime;
01:先创建一个t3表:
mysql> create table t3(d date,t time,dt datetime);
Query OK, 0 rows affected (0.26 sec)

02:显示一下结构:
mysql> desc t3;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| d | date | YES | | NULL | |
| t | time | YES | | NULL | |
| dt | datetime | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)

03:往里面添加时间日期:
mysql> insert into t3 values(now(),now(),now()); #now 表示添加的时当前时间
Query OK, 1 row affected, 1 warning (0.07 sec)

04:显示表:已经将当前的时间都添加进去了
mysql> select * from t3;
+------------+----------+---------------------+
| d | t | dt |
+------------+----------+---------------------+
| 2018-12-07 | 00:22:47 | 2018-12-07 00:22:47 |
+------------+----------+---------------------+
1 row in set (0.00 sec)



05:TIMESTAMP #某年某月某时日某时某分
YYYYMMDD HHMMSS(范围:1970-01-01 00:00:00/2037 年某时)

01:创建一个t4表:
mysql> create table t4(time timestamp)
Query OK, 0 rows affected (0.17 sec)

02:显示看看:
mysql> select * from t3;
+------------+----------+---------------------+
| d | t | dt |
+------------+----------+---------------------+
| 2018-12-07 | 00:22:47 | 2018-12-07 00:22:47 |
+------------+----------+---------------------+
1 row in set (0.00 sec)

mysql> select * from t4;
Empty set (0.00 sec)

03:往里面添加元素:
mysql> insert into t4 values();
mysql> insert into t4 values(null);
Query OK, 2 row affected (0.05 sec)

04:查询看看:
显示了当前的的时分秒
mysql> select * from t4;
+---------------------+
| time |
+---------------------+
| 2018-12-07 00:33:25 |
| 2018-12-07 00:35:22 |
+---------------------+
2 rows in set (0.00 sec)

注意:单独插入年份时候:
1. 单独插入时间时,需要以字符串的形式,按照对应的格式插入
2. 插入年份时,尽量使用4位值
3. 插入两位年份时,<=69,以20开头,比如50, 结果2050
>=70,以19开头,比如71,结果1971

例子:
mysql> insert into t5 values
-> (89),
-> (45),
-> (21),
-> (69),
-> (70);
Query OK, 5 rows affected (0.05 sec)
Records: 5 Duplicates: 0 Warnings: 0

mysql> select * from t5;
+------+
| y |
+------+
| 1989 |
| 2045 |
| 2021 |
| 2069 |
| 1970 |
+------+
5 rows in set (0.00 sec)


9:字符串类型:char,varchar(char 0--255,varchar 0--65535)
作用:存储名字,信息等等
01:char类型:定长,简单,但是浪费存储空间,存取速度快
说明:存储长度 例子: name char(10) 表示存储的最长是10,就算只输入一个 a ,char也会另外增加9个字符的空间来存储,因此也就非常浪费空间了

char也会开辟10个长度的空间出来给存储。
字符长度:0--255(一个中文是一个字符,是utf8编码的3个字节)
存储:
存储char类型的时候,会往右填充空格来满足长度
例如:指定长度为10,存>10个字符则报错(严格模式下),存<10个字符则用空格填充直到凑够10个字符存储

检索:
在检索或则说查询的时候,查处的结果会自动删除尾部的空格,如果你想看到它补全空格之后的内容,除非打开
pad_to_full_length SQL模式((SET sql_mode = 'strict_trans_tables,PAD_CHAR_TO_FULL_LENGTH';)

02:varchar类型:定长,精准,节省空间,存取速度慢。
优缺点说明:varchar在存储数据的时候,你有多少长度的字符,我就给你开辟多少空间,但是我们存储的时候,并不知道我们要存储的数据长度,所以
varchar在存储的时候,还会在存储的数据前庙加上一到两个字节的长度信息,表明需要存储的数据长度是多少!
varchar在取数据的时候,还要先判断这个数据有多长,然后再按照这个长度去取数据。

001:基本说明:
字符长度:0--65535(如果大于21845会提示用户其他类型,mysql 行最大限制为65535字节,字符编码为utf-8

存储: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
检索:尾部的空格会被保存下来,在检索或则说查询的时候,也会正常显示包含空格在内的内容

002:测试
length(字段):查看该字段数据的字节长度
char_length(字段):查看该字段数据的字符长度


通过mysql提供的一个char_length()方法来查看一下所有数据的长度
mysql> select char_length(name) from t1;
+-------------------+
| char_length(name) |
+-------------------+
| 4 |
| 1 |
| 2 |
| 3 |
| 1 |
+-------------------+
5 rows in set (0.00 sec)

mysql> select char_length(name) from t2;
+-------------------+
| char_length(name) |
+-------------------+
| 4 |
| 1 |
| 2 |
| 3 |
| 1 |
+-------------------+
5 rows in set (0.00 sec)
通过查看结果可以看到,两者显示的数据长度是一样的,不是说好的char会补全吗,我设置的字段是char(4),那么长度应该都是4才对啊?这是因为mysql在你查询的时候自动帮你把结果里面的空格去掉了,如果我们想看到它存储数据的真实长度,需要设置mysql的模式,通过一个叫做PAD_CHAR_TO_FULL_LENGTH的模式,就可以看到了,所以我们把这个模式加到sql_mode里面:
mysql> set sql_mode='PAD_CHAR_TO_FULL_LENGTH';
Query OK, 0 rows affected (0.00 sec)

然后我们在查看一下t1和t2数据的长度:
mysql> select char_length(name) from t1;
+-------------------+
| char_length(name) |
+-------------------+
| 4 |
| 4 |
| 4 |
| 4 |
| 4 |
+-------------------+
5 rows in set (0.00 sec)

mysql> select char_length(name) from t2;
+-------------------+
| char_length(name) |
+-------------------+
| 4 |
| 1 |
| 2 |
| 3 |
| 1 |
+-------------------+
5 rows in set (0.00 sec)
通过结果可以看到,char类型的数据长度都是4,这下看到了两者的不同了吧,至于为什么mysql会这样搞,我们后面有解释的,先看现象就可以啦。

现在我们再来看一个问题,就是当你设置的类型为char的时候,我们通过where条件来查询的时候会有一个什么现象:
mysql> select * from t1 where name='a';
+------+------+
| id | name |
+------+------+
| 2 | a |
+------+------+
1 row in set (0.00 sec)
ok,结果没问题,我们在where后面的a后面加一下空格再来试试:
mysql> select * from t1 where name='a ';
+------+------+
| id | name |
+------+------+
| 2 | a |
+------+------+
1 row in set (0.00 sec)
ok,能查到,再多加一些空格试试,加6个空格,超过了设置的char(4)的4:
mysql> select * from t1 where name='a ';
+------+------+
| id | name |
+------+------+
| 2 | a |
+------+------+
1 row in set (0.00 sec)
ok,也是没问题的
总结:通过>,=,>=,<,<=作为where的查询条件的时候,char类型字段的查询是没问题的。
但是,当我们将where后面的比较符号改为like的时候,(like是模糊匹配的意思,我们前面见过,show variables like '%char%';来查看mysql字符集的时候用过)
其中%的意思是匹配任意字符(0到多个字符都可以匹配到),还有一个符号是_(匹配1个字符),这两个字符其实就像我们学的正则匹配里面的通配符,那么我们通过这些符号进行一下模糊查询,看一下,char类型进行模糊匹配的时候,是否还能行,看例子:
mysql> select * from t1 where name like 'a';
Empty set (0.00 sec)
发现啥也没查到,因为char存储的数据是4个字符长度的,不满4个是以空格来补全的,你在like后面就只写了一个'a',是无法查到的。
我们试一下上面的通配符来查询:
mysql> select * from t1 where name like 'a%';
+------+------+
| id | name |
+------+------+
| 2 | a |
+------+------+
1 row in set (0.00 sec)
这样就能看到查询结果了

试一下_是不是匹配1个字符:
mysql> select * from t1 where name like 'a_';
Empty set (0.00 sec)
发现一个_果然不行,我们试试三个_。
mysql> select * from t1 where name like 'a___';
+------+------+
| id | name |
+------+------+
| 2 | a |
+------+------+
1 row in set (0.00 sec)
发现果然能行,一个_最多匹配1个任意字符。
如果多写了几个_呢?
mysql> select * from t1 where name like 'a_____';
Empty set (0.00 sec)
查不到结果,说明_匹配的是1个字符,但不是0-1个字符。

其实在多数的用户量少的工作场景中char和varchar效率差别不是很大,最起码给用户的感知不是很大,并且其实软件级别的慢远比不上
硬件级别的慢,所以你们公司的运维发现项目慢的时候会加内存、换nb的硬盘,项目的效率提升的会很多,但是我们作为专业人士,我们
应该提出来这样的技术点来提高效率。

但是对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本
质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列性能要好。因而,主要的性能因素是数据行使用的存储总量。
由于CHAR平均占用的空间多于VARCHAR,因此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。



六:枚举类型(enum)和集合类型(set)
1:枚举类型(enum) 只能在给定的范围内选择一个值,例如sex 性别,男male/female女,如果选择多个值,则此字段不会被显示

例子:
01:创建一个shirts 表
mysql> create table shirts(
-> nmae varchar(40),
-> size enum("x-small","small","medium","large","x-large")
-> );
Query OK, 0 rows affected (0.16 sec)

02:正常选择一个数据插入:
mysql> insert into shirts(nmae,size) values("dress shirt","large"),("t-shirt","medium"),("polo short","small"),("fengyi","large");
Query OK, 3 rows affected (0.05 sec)
Records: 3 Duplicates: 0 Warnings: 0

03:在size里面多插入一个数据看看:
mysql> insert into shirts(name,size) values("fengyia","large,small");
uery OK, 1 row affected, 1 warning (0.05 sec)

04:查看正常数据:
mysql> select * from shirts;
+-------------+--------+
| name | size |
+-------------+--------+
| dress shirt | large |
| t-shirt | medium |
| pool shirt | small |
| fengyi | large | #正常插入的数据 可以正常显示
| fengyia | | #多插入的数据size 没有显示出来
+-------------+--------+
5 rows in set (0.02 sec)

2:set多选,在给定的范围内可以选择一个或一个以上的值(例如:爱好1,爱好2等等)。
例子:
01:创建一个consumer的set集合表
mysql> create table consumer(
-> name varchar(50),
-> sex enum("male","female"), #多选一
-> level enum("vip1","vip2","vip3","vip4","vip5"), #多选一
-> hobby set("play","music","read","study") #多选多
-> );
Query OK, 0 rows affected (0.14 sec)


02:给表set表插入数据:
mysql> insert into consumer values
-> ("xiaobai","male","vip5","read,study"), #正常插入数据
-> ("xxxxxx","female","vip1,vip2,vip3","aaa"), #enum字段插入的数据不正常,插入了多个数据,结果会造成不显示
-> ("qqqqq","female","vip2","study"); #正常插入数据
Query OK, 3 rows affected, 2 warnings (0.08 sec)
Records: 3 Duplicates: 0 Warnings: 2

03:显示数据:
mysql> select * from consumer;
+---------+--------+-------+------------+
| name | sex | level | hobby |
+---------+--------+-------+------------+
| xiaobai | male | vip5 | read,study | #多选多
| xxxxxx | female | | | #多选一插入,由于插入了多个数据,所以不显示了
| qqqqq | female | vip2 | study | #正常的插入数据
+---------+--------+-------+------------+
3 rows in set (0.00 sec)

总结:在多选一enum字段选择时,如果选择多个则在select内容的时候不会被显示。

猜你喜欢

转载自www.cnblogs.com/one-tom/p/10149153.html