Go to comments

MySQL创建数据表

一、Mysql 基本管理

端口

mysql 数据库端口  3306

Oracle 数据库端口 1521

用户分配、权限管理都可以使用工具来完成


MySql 启动

1. mysql的启动关闭方式,我的电脑右键 - 管理 - 服务和应用程序 - 服务 - mysql(停止/启动)


2. window命令行

net stop mysql  停止mysql

net start mysql  启动mysql


3. liunk

service mysqld start    开启

service mysqld stop    停止

service mysqld restart 重新启动


用的是xampp集成环境,window下启动和停止命令用不了,liunk系统没有用过


Mysql的目录结构

1. my.ini 配置文件

2. bin 目录存的是mysql管理和运行客户端、服务器的一些命令

    mysql.exe 客户端的命令

    mysqladmin.exe 命令行管理的命令

    ysqldump.exe 备份的命令

3. data目录存的是数据库文件,里面每一个文件夹就是一个库,库里面是表


设置 Mysql 的环境变量

1 .我的电脑 -> 右键属性 -> 高级 -> 环境变量

2. user用户变量 -> Path -> 编辑

3. 新建 - 添加路径 D:\xampp\mysql\bin,在任何目录下都可以直接使用bin目录下的命令


了解数据库的SQL语句操作 [重点]

对于数据库服务器里面的数据管理,必须使用客户机程序成功链接以后,再通过必要的操作指令对其进行操作,这种数据操作指令通常成为sql。

SQL(Structured Query Language) 结构化查询语言,mysql支持sql这种查询语言,sql是一种专门查询和修改数据库与数据,以及对数据库进行进行管理和维护的标准化语言。


sql是高级的非过程化的编程语言,他不要求用户指定对数据的存储方法,也不需要用户了解具体的数据存储方式。

所以具有完全不同底层结构的,不同的数据库系统,可以使用相同的sql作为数据库输入与管理的接口。


1 .sql语句以记录集合作为操作对象,所以sql语句接收集合作为输入,返回集合作为输出

2. 这种集合特性允许一条sql语句的输出,作为另一条sql语句的输入,所以sql语句可以嵌套。

这使sql具有极大的灵活性及强大的功能,在大多数情况下在其它语言中,需要一大段程序实现的功能,只需要一个条sql语句就可以达到目的,这意味sql语句可以写出一些非常复杂的语句来,有的sql语句要占好多行才能写出来。


sql语句结构简洁功能强大,而且比较简单易学,所以自IBM自1981年推出sql语句以来,sql语句就得到了广泛的应用。

Oracle, DB2, SQL Server, Mysql等等,基本上都支持sql语句作为查询语言。


SQL语句又分为DDL, DML, DQL, DCL


DDL:

用来定义和管理数据对象,比如创建库,创建表这样的语句

create database 库名;

create table [库名.]表名;  -- 使用"use 库名"后就不用加库名了

drop database 库名;

drop table 表名;


DML:

数据库、数据表创建完了,表里面有数据了,对数据进行操作,比如插入、更新、删除有影响的语句,也叫数据操作语句

insert into users( id, name ) values ( '1', 'zhangsan' );

update users set name='aa', age='10' where id='1';

delete from 表名 where id = '2';


DQL:

专门查询数据的语言,用于查询数据库对象中所包含的数据

能够进行单表查询,链接查询,嵌套查询,以及集合查询等专门查询数据的语句

select * from 表名;


DCL:

数据控制语句,是用来管理数据库的语言,包含管理权限以及数据的更改

show databases;  -- 查看所有库

show tables; -- 查看所有表

desc 表名; -- 查看表结构

show variables -- 看配置文件中的变量和值


sql 语句

1. 链接数据库服务器

mysql -hlocalhost -uroot -P3306 -p   --连接到数据库服务器


看状态

 \s   命令

Current database:   当前的数据库

Current user:           当前用户

Using delimiter;      sql语句的分隔符用分号";"

Server version:        数据库版本

Server characterset: utf8mb4   服务字符集

Db     characterset: utf8mb4     数据库的字符集

Client characterset: gbk    客户端的字符集

Conn.  characterset: gbk   链接的字符集

TCP port:            3306       端口


单独查看

show variables;  看系统默认配置中所有的变量

show variables like 'time_zone';  单独查看时间变量

show variables like 'port';   单独查端口


退出数据库

 exit; 


2. 链接mysql数据库服务器后,创建数据库(DDL语句)

show databases; -- 看所有库

create database namedb; -- 创建数据库

create database if not exists namedb; -- 如果数据库不存在再创建,这样写在PHP程序里不会报错


删除数据库的语句

drop database namedb; -- 删除数据库

drop database if exists namedb; -- 如果库存在再删除,这样写如果数据库不存在不会报错


创建完数据库,在数据库里创建表

create table namedb.users( -- namedb.users,意思是在namedb库里创建用户表
    id int,
    name char(30),
    age tinyint,
    sex char(3)
);


3. 选择一个数据库作为默认的数据库,操作这个库下面所有表的时候,sql语句里都不用加数据库的名

use namedb; -- 选择namedb的库

\s -- 查看:Current database

show tables; -- 查看namedb库下所有表

desc users;  -- 查看users表的结构

drop table if exists users; -- 如果users表存在再删除,这样不会报错误信息

create table if not exists users( -- 如果users表不存在,再创建表
    id int,
    name char(30),
    age tinyint,
    sex char(3)
);


4. 对数据插入、更新、删除,属于DML数据操作语句

如果在PHP程序里写sql语句,插入值的时候,所有字段都按照"字符串"插入,不管什么类型的,都按单引号写

insert into users values('1', 'lin', '40', '男');

insert into users (id, name, age, sex)values('2', 'lili', '20', '女');

id字段和age字段是整形,为什么还要按照字符串操作呢?

mysql会自动把他转成列对应的类型,这样在PHP程序里不容易出错,

所以myslq操作的时候,所有的数据都按照"字符串"处理,mysql会自动根据字段的类型,是整形或者是字符串类型,自动的去转换。


修改插入的数据

update users set name='QiQi' where id = '2';

update users set name='Qi', age='30' where id = '1';


删除插入的数据

delete from users where id = '2';


查看插入的数据,属于DQL语句

select * from users;


帮助的使用

如果有些sql语句不会写,可以看帮助的使用

按照层次来看帮助:

第一步

如果不知道帮助能给我们提供什么内容,可以使用  ? contents  命令

categories:

Account Management

Administration

Compound Statements

Data Definition

Data Manipulation

Data Types                   数据类型

Functions

Functions and Modifiers for Use with GROUP BY

Geographic Features

Help Metadata

Language Structure      语言结构

Optimization and Indexes

Plugins

Procedures

Sequences

Storage Engines

Table Maintenance

Transactions

User-Defined Functions

Utility


对应上面的分类,使用问号加类别名字方式,比如  ? Data Types  查看msyql中支持那些数据类型 

For more information, type 'help <item>', where <item> is one of the following

topics:

  AUTO_INCREMENT

  BIGINT

  BINARY

  BIT

  BLOB

  BLOB DATA TYPE

  BOOLEAN

  CHAR

  CHAR BYTE

  DATE

  DATETIME

  DEC

  DECIMAL

  DOUBLE

  DOUBLE PRECISION

  ENUM

  FLOAT

  INT

  INTEGER

  ……


查出支持的类型了,列出的类型里面的int类型,int的具体介绍怎么查看呢?

 ? int  可以看到,name和

Name: 'INT'

Description:

INT[(M)] [UNSIGNED] [ZEROFILL]


如果需要快速查到某些项的语法,可以使用关键字

比如:

 ? show      show命令相关

 ? create    创建表结构不会了,查找create命令

 ?update  查看更新语句语法


MySQL创建数据表(上)

创建数控表的SQL语句模型

数据值和列类型

数据字段属性

创建索引

创建表类型及存储位置

数据l默认字符集

修改表


二、创建数据表的SQL语句模型

创建数据表,先创建数据库

show databases; -- 查看所有的的库

create database IF NOT EXISTS dbname charset utf8; -- 创建dbname库

use dbname; -- 选择dbname进入该数据库

 \s  命令,查看一下dbname库的状态:

……

Current database   当前数据库名

Current user           当前使用的用户

TCP port                 链接的端口

……


删除数据库

DROP DATABASE IF EXISTS dbname;


创建数据表

? create table 查看创建表的帮助文件


创建数据表的模型都需要什么?

1). 创建表使用的是DDL数据对象定义语句,sql语句虽然不区分大小写,但所有的关键字尽量大写,显着专业吧

     CREATE TABLE [IF NOT EXISTS] 表名称 (

          字段名1 列类型,

          字段名2 列类型,

          ...

          字段名n 列类型,

     );

2). 一张表必须有字段名(列名),每个列必须有列类型(整形还是字符串),表可以有多个字段,

     这是创建表的最基本结构

3). 但是为了确保数据的完整性和一致性,创建表的时候除了必须指定字段名称字段类型

     还需要指定一些 [属性] 以及一些约束的 [索引],比如主键、外键等一些功能。

     中括号的意思是可选的部分,为了完整性和一致性最好加上

     CREATE TABLE [IF NOT EXISTS] 表名称(

          字段名1 列类型 [属性] [索引],

          字段名2 列类型 [属性] [索引],

           ...

          字段名n 列类型 [属性] [索引],

      ) [表类型] [表字符集];

4). 表里面的列(字段)有类型,mysql表也是分类型的,所以也可以指定[表类型],

     当然不指定[表类型],会选用默认的类型

5). 然后表可以指定用什么[字符集]来存储,

     当然除了表可以指定字符集,每个列也可以指定字符集

这就是创建表需要的、必须的几部分


表名称 和 字段名需要我们自己定义名称,比如,users用户表、articles文章表(因为表里面要存多个记录,所以加s是表示复数的意思)

首先SQL是不区分大小写的,但是表名和字段名的命名:

1). 命名要有意义,表名和字段名一定要有意义(用英文、英文组合或多个单词的缩写都可以)

2). 自己定义的名称最好都是小写的,创建的表名就是一个文件名

     在mysql/data文件下,表名转换文件名,库名转换为目录名,

     不同的操作系统不一样,比如windows不区分大小写,Linux和UNIX是区分大小写,大小写有可能使项目运行不了

3). SQL语句的关键字最好都大写,自己定义的名称最好都小写,这样一看就知道那些是sql语句,那些是自己定义的名称


三、数据值和列类型

sql语句写到一般半想退出,直接用\c退出(c小写)

mysql>CREATE TABLE IF NOT EXISTS users(

        ->id INT,

        ->\c


如果写到一半写错了,前面写了一个单引号,'\c'是退出不了的,怎么怎么办呢?

mysql>CREATE TABLE IF NOT EXISTS users(

        ->id INT'

        '> \c

        '> \c

        '> \c


补上一个单引号后,出现-> 再 \c才能退出

mysql> CREATE TABLE IF NOT EXISTS users(

        -> id INT'

        '> \c

        '> \c

        '> '

       -> \c



USE 数据库名  选择一个数据库,

创建一个数据表,表名users

CREATE TABLE IF NOT EXISTS users(
	id INT,
	name CHAR(40)
)CHARSET UTF8;

SHOW TABLES; -- 查看数据表

DESC users; -- 查看表结构

Mysql数据值和列类型有四种

1.数值型

2.字符型

3.日期型

4.null型


PHP、JAVA等开发语言都可以处理数据库,那Mysql的数据类型应该比编程语言里的存在数据类型还应该多啊!

比如,PHP里面有八种数据类型,JAVA里面也有八种数据类型,为什么mysql只有四种数据类型?


这只是大的分类,每种类型还可以分为更细致的一些分类,所以只要是编程语言里有的类型,数据表就能把他的数据存到数据表里面,这样的一个类型关系。

所以Mysql表类型和一般的编程语言的数据分类都差不多。


另外Mysql数据库的表是一个二维表,由一个或多个数据列构成的,每个数据列都有他特定的类型,这个类型就决定了Mysql如何看待该列的数据。

我们可以把整形数值存放到字符类型列中,Mysql则会把整形看成字符串来处理。

Mysql中的列类型就有三种,NULL(空)是一个值就不看了

1. 数值型

2. 字符型

3. 日期时间型

每一种列类型还可以细分,下面开始学习

1、数值型


整型(整数)


名称占用空间存储范围(有符号)存储范围(无符号)
TINYINT非常小的整型1字节-128 ~ 1270 ~ 255
SMALLINT较小的整型2字节-32768 ~ 327670 ~ 65535
MEDIUMINT中等大小的整型3字节-8388608 ~ 83886070 ~ 16777215
INT标准的整数型4字节-2147483648 ~ 21474836470 ~ 4294967295
BIGINT大整数型8字节
2^64

整数型细分是按空间大小来区分的,可以存下就可以

比如非常小整形TINYINT,占用一个字节空间,一个字节是八位的二进制 0000 0000,范围在-128 ~ 128之间或者0 ~ 255

存一个人的年龄就够了,当然年龄很少有往数据库字段里存的,通常存出生日期。

再比如,存用户权限1代表有权限,0代表没有权限,就没有必要用4个字节存,用一个字节的就够了

TINYINT类型

CREATE TABLE IF NOT EXISTS tab1(
    id TINYINT
);

insert into tab1(id) values (100);
insert into tab1(id) values (200);
insert into tab1(id) values (-200);

SELECT id FROM tab1;

+------+

 |   id    |

+------+

 |  100  |    插入100正确的

 |  127  |    200超过了最大值127,就以最大值127显示

 | -128  |    -200低过了最小值-128,就以负的最大值-128显示 

+------+

UNSIGNED无符号属性

创建无符号列

CREATE TABLE IF NOT EXISTS tab2(
    id TINYINT UNSIGNED
);

insert into tab2(id)values(90);
insert into tab2(id)values(900);
insert into tab2(id)values(-900);

SELECT id FROM tab2;

+------+

 |   id    |

+------+

 |  90    |    90是正确的值是可以的

 |  255  |

 |    0    |

+------+

注意:

Mysql5.7.18下,超过存储范围,插入是不成功的,并返回错误信息

ERROR 1264 (22003): Out of range value for column 'id' at row 1

浮点型(小数)


类型名称占用空间
float(M, D)浮点型4字节
double(M, D)浮点型8字节
decimal(M, D)定点型M+2字节


什么是浮点数?

浮点数一般用于表示含有小数部分的数值。


当一个字段被定义成浮点数类型后,如果插入数据的精度,超过了该列定义的实际精度,

1). 那么插入的数值会被四舍五入,到实际定义的精度值,

2). 然后再插入

3). 四舍五入的过程中不会报错

float和double都是表示浮点数的,decimal是定点数则不同。


什么是定点数?

定点数不同于浮点数定点数实际上是以字符串形式存放的,所以定点数可以更精确的保存数据。

如果实际插入的数值精度 大于 实际定义的精度,则Mysql会发出一些警告,但是数据库还按照实际的精度进行插入。

下面看浮点数和定点数的区别:

浮点数

float(5, 2)  类型,一共是五位(包括小数一共五位)保留小数后两位

CREATE TABLE IF NOT EXISTS tab3(
    price FLOAT(5, 2)
);

insert into tab3 (price)values(1234567.123); -- 插入超过范围的数值

select price from tab3;

一共是五位,五位的最大值是999.99

+--------+

 |  price   |

+--------+

 |  999.99|

+--------+

注意:

Mysql5.7.18版本下,超过存储范围,插入是不成功的,并返回错误信息

ERROR 1264 (22003): Out of range value for column 'price' at row 1


插入在五位范围之内的小数,存储成功

insert into tab3 (price)values(123.123);

select price from tab3;

储存成功

+--------+

 |  price   |

+--------+

 | 999.99 |

 | 123.12 |

+--------+

浮点数会四舍五入,下面插入 123.125 没有四舍五入

,insert into tab3 (price)values(123.125);

select price from tab3;

+--------+

 |  price   |

+--------+

 | 999.99 |

 | 123.12 |

 | 123.12 |   没有四舍五入

+--------+

调整一下,再插入123.126

insert into tab3 (price)values(123.126);

select price from tab3;

+--------+

 |  price   |

+--------+

 | 999.99 |

 | 123.12 |

 | 123.12 |

 | 123.13 |   四舍五入了

+--------+


另外浮动数还有一个问题:

如果用浮点数进行比较的话,浮点数存在着误差,因为浮点数是一个近似数,

比如8.0其实不是8,是7.99999……

所以浮点数不能用于等号去比较

比如在JAVA和PHP里面,如果非要用浮点数比较,最好用使用范围比较,而不是使用等号比较


flaot类型和double类型他两的用法是一样的

下面看定点数decimal的例子

定点类型decimal

创建decimal定点型和double类型,两个类型字段比较一下

CREATE TABLE tab4(
    one double(8, 1),
    two decimal(8, 1)
);

DESC tab4;

查看表结构

+-------+--------------+------+-----+---------+-------+

 | Field   | Type             | Null   | Key  | Default  | Extra  |

+-------+--------------+------+-----+---------+-------+

 | one     | double(8,1)  | YES   |         | NULL     |            |

 | two     | decimal(8,1) | YES   |         | NULL     |            |

+-------+--------------+------+-----+---------+-------+


上面的float类型,四舍五入的时候连warning警告都没有,

这次先插入正确范围内的值(12.3),没有出现任何warning警告

insert into tab4(one, two) values (12.3, 12.3);

select one, two from tab4;

插入正确范围的值,是没有问题的

+------+------+

 | one   | two   |

+------+------+

 | 12.3  | 12.3  |

+------+------+

再插入一个12.38,命令行出现一个警告,这个警告是定点数字段发出的 Query OK, 1 row affected, 1 warning (0.00 sec)

insert into tab4(one, two) values (12.38, 12.38);

select one, two from tab4;

两个字段都四舍五入了,two字段定点数字段,后面的小数点值四舍五入了,高老师的意思,定点数不应该四舍五入!

+------+------+

 | one   | two   |

+------+------+

 | 12.3  | 12.3   |

 | 12.4  | 12.4   |

+------+------+

再来换一个12.21,又产生了一个警告 Query OK, 1 row affected, 1 warning (0.00 sec)

insert into tab4(one, two) values (12.21, 12.21);

select one, two from tab4;

+------+------+

 | one   | two  |

+------+------+

 | 12.3  | 12.3  |

 | 12.4  | 12.4  |

 | 12.2  | 12.2  |

+------+------+

用字符串形式插入看看,因为mysql会自动转换成"列"对应的类型,插入12.36还是产生了一次warning警告

insert into tab4(one, two) values ('12.36', '12.36');

select one, two from tab4;

存储结果是12.4,四舍五入了,定点数不应该四舍五入

+------+------+

 | one   | two  |

+------+------+

 | 12.3  | 12.3 |

 | 12.4  | 12.4 |

 | 12.2  | 12.2 |

 | 12.4  | 12.4 |

+------+------+

下面插入12.211111,依然产生了一次warning警告

insert into tab4(one, two) values (12.211111, 12.211111);

select one, two from tab4;

+------+------+

 | one   | two   |

+------+------+

 | 12.3  | 12.3  |

 | 12.4  | 12.4  |

 | 12.2  | 12.2  |

 | 12.4  | 12.4  |

 | 12.2  | 12.2  |

+------+------+

高老师没有比较出区别,但是,总之浮点数会出现一些误差,

在对浮动数进行操作的时候,会经常发生一些误差,所以使用浮点数的时候要特别的小心。


浮动数存在误差的问题,所以对货币等精度铭感的数据应该用定点型(decimal)来表示和存储,

在编程中如果用到浮点数,要特别注意误差的问题,并尽量避免做浮点数的比较,

所以要注意浮动数中的一些特殊值的处理,具体那些特殊值,高老师忘记了什么是特殊值,

浮点数类型数据会因为四舍五入产生误差,所以不适合用于精度要求比较高的运算。


浮点数 与 定点数的存储格式不同

定点数的存储的格式,CPU不能直接对其进行运算,会影响到一些存储效率,

所以定点数优点就是精确,但是会影响到一些效率,因为存储格式是以字符串形式存的,不能直接进行运算,他要转化一下。


自己总结

上面插入出现的一系列warning,是定点数引起的。

定点数要求比较严格,如果超出设置的位数范围,会出warning警告信息

decimal(8, 1)类型只设置了一位小数,只存储一位小数的数就不会出现warning警告了

CREATE TABLE dnum(
    num decimal(8, 1)
);

insert into dnum values (12.3);
insert into dnum values (12.2);
insert into dnum values (12.3);
insert into dnum values (12.1);

select * from dnum;

2、字符型

字符串可以用来表示任何一种数据类型,包括整数、浮点数也可以用字符串类型来存储,

我们可以用字符串类型存储图像或者声音之类的二进制数据,也可以存储压缩的数据


mysql支持单引号或双引号的字符串,

1). 比如存数据的时候,双引号"mysql"或者是单引号'mysql'都是可以的

2). mysql能识别PHP程序,字符串中的转义字符 \ 

字符串char和varchar类型


char和varchar最大存储空间都255个字符,超过255个字符会被截断(varchar类型这里有点变化,看下面注意说明),

我们也可以指定长度,char(m)指定一个m长度,指定多长就可以存储多长


注意:

varchar最大长度这里,网上查了Mysql4.1以下的版本中的最大长度限制为255,MySQL5.0以上的版本中, varchar数据类型的长度支持到了65535, 也就是说可以存放65532个字节的数据,

https://www.cnblogs.com/M-D-Luffy/p/4125900.html


继续

名字name列指定10个字符,介绍description列也用10个字符,插入3个字符长的的字符串,存储成功

CREATE TABLE IF NOT EXISTS tab5(
	name char(10),
	description varchar(10)
);

insert into tab5 (name, description)values('abc', 'abc'); -- 插入3个字符长度的字符串

select name, description from tab5;

+------+-------------+

 | name| description |

+------+-------------+

 | abc   | abc              |

+------+-------------+

如果两个字段都插入超过10个字符的范围,会出现两个warnings警告 Query OK, 1 row affected, 2 warnings (0.00 sec)

insert into tab5 (name, description)values('abcdefghigkmln', 'abcdefghigkmln');

select name, description from tab5;

+------------+-------------+

 | name         | description |

+------------+-------------+

 | abc            | abc              |

 | abcdefghig| abcdefghig |   只储存10个字符

+------------+-------------+

char和varchar都是表示字符串的,他们的类型相似,都是存储字符串的,但是他们保存和解锁的方式不同,

char属于固定长度字符串,varchar属于可变长度字符串


什么是固定长度和可变长度呢?

比如,char(4)和varchar(4)都设置4个字节

1). 储存''空字符串,char(4)占4字节,varchar(4)占1字节

2). 存储'ab'2个字符,char(4)还是占4字节,varchar(4)占3字节

3). 储存'abcd'正好范围4个字符,char(4)的时候还是占4字节,而varchar(4)占5字节,他永远比字符多一个字节

4). 'abcdefg'超过储存范围,

     -1 超过范围会被截断 

     -2 char(4)还是占4字节,varchar(4)占5字节

总结:

varchar类型根据内容不同,他永远是内容加一个字节,永远多占一个字节,

char永远是固定长度字节,不管是不存还是存储都是这样的


另外varchar和char解锁的值并不总是相同的,就算存相同的值也不是总相同的,因为解锁时char类型的列会删除尾部的空格

例如,tab6表中的列都设置4个字符长度,"ab "插入的ab后面有空格,长度是3个字符

create table tab6(
	v varchar(4),
	c char(4)
);

insert into tab6 (v, c)values('ab ', 'ab '); -- "ab "插入ab后面有空格,长度是3个字符

select v, c from tab6;

+------+------+

 | v       |    c    |

+------+------+

 | ab     |   ab   |

+------+------+

存储的都是ab,看不出什么不同,但是他们的解锁方式不同,

下面用concat()链接函数,给两个列分别链接一个#号

select concat(v,"#"), concat(c,"#") from tab6;

+---------------+---------------+

 | concat(v,"#") | concat(c,"#")  |

+---------------+---------------+

 | ab #               | ab#                |

+---------------+---------------+

v字段声明的是varchar类型,不会删除空格,而c字段的char类型删除了空格,这就是解锁方式的不同


什么时候用char?

1). char是固定长度,所以处理速度要比varchar快的多,

2). 如果字段长度是固定的,比如性别就用char声明,

3). 缺点是浪费存储空间,程序需要对尾部的空格进行处理,所以对于长度变化不大的,并对查询速度有要求的数据用char类型


什么时候用varchar?

1). 变化比较大,比如文章标题变化比较大用varchar,但是速度不如char快

2). 但是随着mysql版本的不断升级,varchar性能也不断的改进在提高,所以在许多应用中varchar类型都被更多的使用


字符类型的char和varchar的长度才255个(varchar类型mysql5以上,存储长度不是255了),下面看另外几种字符串类型

文本类型数据(存文章)

一般报存少量字符串的时候,我们选择用var和varchar,而保存较文本的时候采用text和blob类型


text和blob的区别

blob类型,用来保存二进制数据,比如照片、电影、压缩包等…

text类型,保存文本数据,比如文章、日记、评论、商品介绍等…


text文本数据

text                    2^16 - 1   文本数据

MEDIUMTEXT   2^24 - 1   中型文本

LONGTEXT        2^32 - 1   长文本


blob二进制数据

blob                   2^16 - 1

MEDIUMBLOB   2^24 - 1

LONGBLOB        2^32 - 1 

字符串还有ENUM和SET这两种类型

ENUM是枚举类型,SET是集合类型,ENUM枚举和SET集合占用的空间是很少的


ENUM枚举类型和SET集合类型区别是什么?

ENUM枚举,占用1或2字节,一次只能存一个值,最多有65535个成员

SET集合,1,2,3,4,8字节,因为可以存多个值,最多有64个成员


为什么字符串用ENUM枚举类型会占这么少的空间呢?

1). 因为枚举就相当一个标号一样,比如枚举类型列, ENUM("one", "two", "three", "four") 列举出这四个值

2). 某个列设置了这个枚举类型,只能有这四个值

3). 为什么能占一个字节呢?就像数组一样,通过下标去取里面的某一个值


枚举里面最多可以有65535个成员,而集合最多有64个成员。


实例,枚举和集合类型

one字段枚举类型,里面只能存a, b, c, d

flag字段集合类型,里面也是a, b, c, d

create table tab7(
	one ENUM("a", "b", "c", "d"),
	flag set('a', 'b', 'c', 'd') 
);

insert into tab7 values('a', 'a');

select * from tab7;

插入的'a'都是可以的,因为'a'的值在枚举和集合之中

+------+------+

 | one   |  flag  |

+------+------+

 | a       |  a      |

+------+------+

但是插入'w',出现两个警告Query OK, 1 row affected, 2 warnings (0.00 sec)

insert into tab7 values('w', 'w');

select * from tab7;

数据表存储是空的,因为'w'不在枚举和集合中

+------+------+

 | one   | flag   |

+------+------+

 | a       | a       |

 |          |          |

+------+------+


枚举和集合什么区别呢?

比如插入'a,b'两个值,出现一个警告Query OK, 1 row affected, 1 warning (0.00 sec)

insert into tab7 values('a,b', 'a,b');

select * from tab7;

集合字段flag插入进去了,而枚举one字段没有插入进去是空的

+------+------+

 | one   | flag   |

+------+------+

 | a       | a       |

 |          |          |

 |          | a,b    |

+------+------+


枚举和集合区别是:

ENUM("a", "b", "c", "d"), 枚举一次只能使用的一个值,

而 set('a', 'b', 'c', 'd') 集合一次可以用多个集合里面的值,插入时多个值中间使用逗号分开


枚举和集合占用空间少,在设计表的时候,如果是固定的几个值,

比如性别,就"男、女、保密"两个值或三个值,可以用枚举。

存星期,一共就七天也可以用枚举类型

如果想存枚举里面的多个值就用集合,多个值用","分开就可以了,所以集合占用的字节不固定的(1,2,3,4,8字节),要看存多少个值

3、日期型

类型格式作用
DATEYYYY-MM-DD年-月-日
TIMEhh:mm:ss时:分:秒
DATETIMEYYYY-MM-DD hh:mm:ss日期和时间
TIMESTAMPYYYYMMDDhhmmss存时间邮戳
YEARYYYY四位的年

创建表

create table if not exists tab8(
	id tinyint unsigned primary key auto_increment,
	d date,
	t time,
	dt datetime,
	ts timestamp,
	y year
)charset utf8;

插入字符串形式的'2010-12-03',mysql会自动的转成日期类型

insert into tab8 (d) values ('2010-12-03');

select * from tab8;

字段d是date类型,ts是默认的先不看

+----+------------+------+------+---------------------+------+

 |   id |       d          |     t    |    dt   |           ts                  |     y    |

+----+------------+------+------+---------------------+------+

 |   1  |2010-12-03 |NULL | NULL |2021-08-20 11:50:08 | NULL |

+----+------------+------+------+---------------------+------+

还可以这样'20101203'存,只要位数够了也可以

insert into tab8 (d) values ('20101203');

select * from tab8;

+----+------------+------+------+---------------------+------+

 |   id |       d          |     t    |    dt   |            ts                  |    y    |

+----+------------+------+------+---------------------+------+

 |  1   | 2010-12-03| NULL| NULL | 2021-08-20 11:50:08 | NULL |

 |  2   | 2010-12-03| NULL| NULL | 2021-08-20 11:53:06 | NULL |

+----+------------+------+------+---------------------+------+


存储时间,t字段TIME类型,插入'11:55:52'

insert into tab8 (d, t) values ('20101203', '11:55:52');

select * from tab8;

+----+------------+----------+------+---------------------+------+

 | id   | d                | t              |    dt   |           ts                  |     y    |

+----+------------+----------+------+---------------------+------+

 |  1   | 2010-12-03 | NULL     | NULL | 2021-08-20 11:50:08 | NULL |

 |  2   | 2010-12-03 | NULL     | NULL | 2021-08-20 11:53:06 | NULL |

 |  3   | 2010-12-03 | 11:55:52| NULL | 2021-08-20 11:56:12 | NULL |

+----+------------+----------+------+---------------------+------+

时间也可以连写'115707',只要位数够了就行

insert into tab8 (d, t) values ('20101203', '115707');

select * from tab8;

+----+------------+----------+------+---------------------+------+

 | id   | d                |       t        |    dt   |           ts                  |     y    |

+----+------------+----------+------+---------------------+------+

 |  1   | 2010-12-03 | NULL     | NULL | 2021-08-20 11:50:08 | NULL |

 |  2   | 2010-12-03 | NULL     | NULL | 2021-08-20 11:53:06 | NULL |

 |  3   | 2010-12-03 | 11:55:52 | NULL | 2021-08-20 11:56:12 | NULL |

 |  4   | 2010-12-03 | 11:57:07 | NULL | 2021-08-20 11:57:29 | NULL |

+----+------------+----------+------+---------------------+------+

而且时间还可以默认写两位,比如'1158'不写小时

insert into tab8 (d, t) values ('20101203', '1158');

select * from tab8;

+----+------------+----------+------+---------------------+------+

 | id   | d                | t              | dt      |            ts                  |    y    |

+----+------------+----------+------+---------------------+------+

 |  1 | 2010-12-03 | NULL     | NULL | 2021-08-20 11:50:08 | NULL |

 |  2 | 2010-12-03 | NULL     | NULL | 2021-08-20 11:53:06 | NULL |

 |  3 | 2010-12-03 | 11:55:52 | NULL | 2021-08-20 11:56:12 | NULL |

 |  4 | 2010-12-03 | 11:57:07 | NULL | 2021-08-20 11:57:29 | NULL |

 |  5 | 2010-12-03 | 00:11:58 | NULL | 2021-08-20 11:58:19 | NULL |

+----+------------+----------+------+---------------------+------+


dt字段是datetime类型,插入'2010-12-03 12:01:21'

insert into tab8 (d, t, dt) values ('20101203', '120121', '2010-12-03 12:01:21');

select * from tab8;

+----+------------+----------+---------------------+---------------------+------+

 | id   |       d          |       t        |           dt                  |           ts                  |     y    |

+----+------------+----------+---------------------+---------------------+------+

 |  1  | 2010-12-03 | NULL      |       NULL                | 2021-08-20 11:50:08 | NULL |

 |  2  | 2010-12-03 | NULL      |       NULL                | 2021-08-20 11:53:06 | NULL |

 |  3  | 2010-12-03 | 11:55:52 |       NULL                | 2021-08-20 11:56:12 | NULL |

 |  4  | 2010-12-03 | 11:57:07 |       NULL                | 2021-08-20 11:57:29 | NULL |

 |  5  | 2010-12-03 | 00:11:58 |       NULL                | 2021-08-20 11:58:19 | NULL |

 |  6  | 2010-12-03 | 12:01:21 | 2010-12-03 12:01:21| 2021-08-20 12:02:38 | NULL|

+----+------------+----------+---------------------+---------------------+------+


ts字段:TIMESTAMP类型,默认的就是当前时间

y字段:YEAR类型,就存四位的年就可以了


创建表时最好不要使用这些类型中的时间格式,虽然有一个时间邮戳但是不是PHP中时间邮戳

PHP中时间戳是从1970-1-1 0:0:0到现在的秒数是一整数

实际应用中用整数int类型保存时间time()时间戳



有些人根本不是整个世界,但他会让我变的更好

1630491254454


MySQL创建数据表(中)

上面是mysql数据库创建表的上的部分,为确保数据的完整性和一致性,在创建表的时候,

1). 除了指定字段名称、字段类型之外,

2). 还需要为字段指定一些属性,而且需要使用一些约束条件,

3). 比如索引,主键索引、唯一索引等等,

4). 还需要设置表的表类型,字符集等等


上半部分重点主要是创建表的列类型,除了列类型还有一些可选部分,

数据库字段属性

创建索引

数据表类型及存储位置

Mysql默认字符集

修改表

四、数据字段属性

1、unsigned属性

1). 作用设置无符号,也就是不允许这个数据列出现负数,可以让空间增加一倍,

2). 比如tinyint类型的范围是 -128 ~ 127,增加一倍没有负数了就变成了0 ~ 255

3). 无符号属性只能用在数值型字段,数值型字符分整数和浮点数,

创建t1表,id字段int类型不能插入负数了

create table if not exists t1(
	id int unsigned
);

insert into t1 values(100);

select id from t1;

插入100是正常

+------+

 |   id    |

+------+

 |  100  |

+------+

如果插入-100(负一百)呢?

1). 出现一个警告 Query OK, 1 row affected, 1 warning (0.00 sec)

2). 会按照字段的极限值存储,仅限最小值就是0

insert into t1 values(-100);

select id from t1;

+------+

 |   id    |

+------+

 |  100  |

 |    0    |

+------+

如果不需要插入负数,就用unsigend属性来修饰列,另外只有数值型能用


PS:

超出储存范围,有些Mysql数据库插入不进去并且会报错,可能与Mysql配置或者版本有关

ERROR 1264 (22003): Out of range value for column 'id' at row 1

2、zerofill

zerofill直接翻译是零填充

1). 该属性只能用在数值型字段

2). 作用是前导0前导0的意思是在数值之前,自动用0补齐不足的位置


float(7,2) 类型的意思是长度总限制7位,小数点后面有两位

varchar(10) 类型括号里写10,意思是最多不能超过10个字符

float(7,2) 和 varchar(10)里面的参数,都是限制长度的,

只有整数的int(5)括号里面的参数5是限制不了长度的,不要看括号里面写了5,只要不超过整数int的存储范围就可以


看例子:

int类型和float类型都加了前导零属性zerofill

create table t2(
	num int(5) zerofill,
	price float(7, 2) zerofill,
	name varchar(10)
);

desc t2;

有了无符号unsigned、前导零zerofill两个属性

+-------+------------------------------+------+-----+---------+-------+

 | Field   | Type                                    | Null   | Key   | Default |  Extra  |

+-------+------------------------------+------+-----+---------+-------+

 | num    | int(5) unsigned zerofill       | YES    |         | NULL    |            |

 | price   | float(7,2) unsigned zerofill  | YES    |         | NULL    |            |

 | name  | varchar(10)                          | YES    |         | NULL    |            |

+-------+------------------------------+------+-----+---------+-------+

有符号是不能加"前导零"属性的,加"前导零"属性该字段自动应用UNSIGNED无符号属性


下面插入数据都超过设置的值

num字段插入'88888888'

price字段插入'1234567.123'

name字段插入"黄图霸业谈笑中,不负人生一场醉"

insert into t2(num, price, name)values('88888888', '1234567.123', '黄图霸业谈笑中,不负人生一场醉');

select * from t2;

插入操作返回两个警告 Query OK, 1 row affected, 2 warnings (0.009 sec)

+----------+----------+----------------------+

 | num        |    price    | name                       |

+----------+----------+----------------------+

 | 88888888| 99999.99| 黄图霸业谈笑中,不负 |

+----------+----------+----------------------+

可以看到整数num字段插入的'88888888'是可以的,int(5)括号里面的5是限制不住长度的

price字段和name字段都被限制住了

PS:

有些版本Mysql插入不成功,并且报出错误信息

ERROR 1264 (22003): Out of range value for column 'price' at row 1


前导零"zerofill"属性有什么作用呢?

就插入num、price两个字段,num字段插入小于5位,price字段小于7位数会怎么样

num字段写两位'88'

price字段写两位'12.123'

insert into t2 (num, price, name) values ('88', '12.123', '这个没有关系了');

select * from t2;

+----------+----------+----------------------+

 | num       | price        | name                       |

+----------+----------+----------------------+

 | 88888888| 99999.99| 黄图霸业谈笑中,不负|

 |    00088  |  0012.12  | 这个没有关系了        |

+----------+----------+----------------------+

整数 和 浮点数字段前面都加了0,整数保证是5位,浮动数是7位

加上前导零zero属性,该字段自动应用UNSIGNED属性

3、自动增长AUTO_INCREMENT

AUTO_INCREMENT是设置字段自动增产的属性

1). 设置这个属性,只能是整数类型

2). 数据每增加一条,就会在原有的字段值自动增加1

3). 这个字段的值是不充许重复

 

使用atuo_increment属性修饰的字段,在插入新数据的时候,

1). 当自动添加为NULL0留空,这三种情况都会在此字段上自动加1,作为此次字段的值

2). 插入时候也可以,指定某一非0的数值,这时如果表中已存在此值将会出错,

     否则使用指定的值,作为自动的值,而且下次插入时下一次字段的值,在此字段基础上加1

3). 所以想作为自动增长,还要加上primary key唯一索引属性,因为字段值不能重复


下面是有自动增加字段的表,能创建成功吗?

create table t3(
	id int auto_increment,
	name char(10)
);

没有创建成功 ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key

为什么没有创建成功?

因为这么直接创建自增长列是不行的,列的值必须不能重复,加上primary key不重复的键索引就可以了。

create table t3(
	id int auto_increment primary key,
	name char(10)
);

所以加primary key索引的目的,是让这个列的值不能重复,下面看看是怎么自动增长。

id字段插入null值,null是一个值表示没有的意思,连续插入三次

insert into t3 (id, name)values(null, '淡淡');
insert into t3 (id, name)values(null, '轻轻');
insert into t3 (id, name)values(null, '余温');

select id, name from t3;

id字段自动增长了

+----+------+

 | id   | name |

+----+------+

 |  1   | 淡淡   |

 |  2   | 轻轻   |

 |  3   | 余温   |

+----+------+

或者是连续插入0

insert into t3 (id, name)values(0, '岁月');
insert into t3 (id, name)values(0, '积攒');
insert into t3 (id, name)values(0, '干枯');

select id, name from t3;

id字段也是可以自动增长的

+----+------+

 | id   | name |

+----+------+

 |  1   | 淡淡  |

 |  2   | 轻轻  |

 |  3   | 余温  |

 |  4   | 岁月  |

 |  5   | 积攒  |

 |  6   | 干枯  |

+----+------+

或者id字段留空,怎么留空呢?id字段不插入,只插入一个name字段

insert into t3 (name)values('雕琢');
insert into t3 (name)values('一席');
insert into t3 (name)values('交织');

select id, name from t3;

id字段也会自动增长

+----+------+

 | id   | name |

+----+------+

 |  1   | 淡淡  |

 |  2   | 轻轻  |

 |  3   | 余温  |

 |  4   | 岁月  |

 |  5   | 积攒  |

 |  6   | 干枯  |

 |  7   | 雕琢  |

 |  8   | 一席  |

 |  9   | 交织  |

+----+------+


如果删除了一些数据,有空缺了,再插入的是把删除的空缺的补上,还是在最大值上加1呢?

分两种情况来说:

第一种:先删除一部分

比如,把id大于1,小于10的都删掉了

delete from t3 where id > 1 and id < 9;

select id, name from t3;

删除后剩下两条数据

+----+------+

 | id   | name |

+----+------+

 |  1   | 淡淡   |

 |  9   | 交织   |

+----+------+

再插入

insert into t3 (id, name)values(0, '岁月');
insert into t3 (id, name)values(0, '积攒');
insert into t3 (id, name)values(0, '干枯');

select id, name from t3 order by id; -- 按顺序查看

+----+------+

 | id   | name |

+----+------+

 |  1   | 淡淡  |

 |  9   | 交织  |

 | 10  | 岁月  |

 | 11  | 积攒  |

 | 12  | 干枯  |

+----+------+

第二种:

删除表里的全部数据

全部删除,一条记录都没有了,表里id最大值是12

delete from t3; -- 受影响的五条数据 Query OK, 5 rows affected (0.003 sec)

select id, name from t3; -- 再查询表是空的 Empty set (0.001 sec)

再插入

insert into t3 (name)values('雕琢');
insert into t3 (name)values('一席');
insert into t3 (name)values('交织');
insert into t3 (name)values('积攒');
insert into t3 (name)values('干枯');

select id, name from t3;

id值是从最大值12的基础上增加

+----+------+

 | id   | name |

+----+------+

 | 13  | 雕琢   |

 | 14  | 一席   |

 | 15  | 交织   |

 | 16  | 积攒   |

 | 17  | 干枯   |

+----+------+

永远是从插入过的最大值增加


那可以不可以指定一个数值,插入到自增长字段呢?

比如,id字段插入一个100的数值,再插入一个条数据,结果是什么样呢

insert into t3 (id, name)values(100, '淡淡');

insert into t3 (name)values('余温');

select id, name from t3;

如果手动的插入一个最大值,会从最大值后面加1,这就是自动增长的属性

+-----+------+

 | id     | name|

+-----+------+

 |  13   | 雕琢  |

 |  14   | 一席  |

 |  15   | 交织  |

 |  16   | 积攒  |

 |  17   | 干枯  |

 | 100  | 淡淡  |

 | 101  | 余温  |

+-----+------+

建议,每张表都最好有一个ID字段,设置为自动增涨 auto_increment

4、NULL 和 NOT NULL

如果表里面不指定空(NULL)和非空(NOT NULL),那么默认值就是空值(NULL),

空(NULL)是一个值,它不是没有也不是空,相当于是一种单独的类型,就是空数据


将来将这个表的数据转为PHP程序的数据时,

1). 整数列里面有NULL值,能转成PHP的0吗?

2). 字符串列里面有NULL值,能转成PHP的这种空字符串 '' 吗?

3). double类型的空置,能转成PHP的 0.00 吗?

这些都不一定,所以建议在创建表时,每个字段都不要插入空值NULL

因为NULL值读取的数据,转成PHP变量的时候不一定转成我们想要的值,我们不好处理。


所以创建表的时候使用not null属性,这样就插入不了空值了。

每个字段都加上not null(非空)

create table t4(
	id int not null,
	name varchar(30) not null,
	price double not null
);

insert into t4 values(null, null, null);

这样插入空值NULL的时候,返回错误 ERROR 1048 (23000): Column 'id' cannot be null

告诉我们id列不能为空,空值就不能插入,这样就必须插入数据,


如果就想留空或者不插入值的时候怎么办呢?

比如就插入name列,其它id、price列不插入值的时候,返回两个警告Query OK, 1 row affected, 2 warnings (0.002 sec)

insert into t4 (name)values('aaa');

select * from t4;

id列和price自动转成默认0,不是空值了(null)

+----+------+-------+

 |  id  | name | price  |

+----+------+-------+

 |  0   | aaa    |     0     |

+----+------+-------+

如果id列、price列不设置not null,这两个列都会是空(null),

price价钱字段默认0也不太好,所以用default属性和NOT NULL配合用

5、default属性是缺省值

id列,非空缺省值用的是0

name列,缺省值用的是字符串的空'',这种空值转成PHP程序的的时候,就会直接转成空字符串,因为name字段是字符串类型的

price列(价钱),不传值用的缺省值是'0.00'

create table t5(
	id int not null default 0,
	name varchar(30) not null default '',
	price double not null default '0.00'
);

insert into t5 (name)values('aaa'); -- 插入时没有警告了

select * from t5;

+----+------+-------+

 |  id  | name| price   |

+----+------+-------+

 |  0   | aaa    |     0     |

+----+------+-------+

这次只插入price字段

insert into t5 (price) value ('12.8');

select * from t5;

name列默认是字符串的空''

+----+------+-------+

 |  id  | name| price   |

+----+------+-------+

 |  0   | aaa    |     0     |

 |  0   |           |  12.8   |

+----+------+-------+

不插入值的时候就使用缺省值


下面创建一个完整的用户表,把上面的属性全用上

CREATE TABLE users(
	id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
	name VARCHAR(30) NOT NULL DEFAULT '',
	height DOUBLE(10,2) NOT NULL DEFAULT 0.00,
	age INT NOT NULL DEFAULT 0,
	sex CHAR(4) NOT NULL DEFAULT '女'
);

属性就这五个了

1.无符号unsigned

2.前导0 zerofill

3.自动增长AUTO_INCREMENT

4.非空 not null

5.缺省值 default

五、创建索引

索引在数据库开发中起到非常重要的作用,通常在表的字段中建立索引,可以提高查询优化,确保数据的唯一性,以及可以对任何全文索引字段中,大量文本的搜索进行优化。


在Mysql中主要有四类索引

1.主键索引

2.唯一索引

3.常规索引

4.全文索引

1、主键索引

主键索引(primary key)是关系型数据库中最常见的索引类型,主要作用是确定数据库表里一条特定数据记录的位置。

主键索引这一列的数据是完全不允许重复的,是用来标识唯一性的。用来唯一标识每一条记录,这样加快寻址定位时的速度。

最好为每一张数据表定义一个主键,而且一张表只能指定一个主键,主键的值不能为空


创建id列为primary key主键索引,这里没有设置自动增长属性,也可以设置自动增长属性

create table t6(
	id int not null primary key,
	name varchar(30) not null default ''
);

desc t6;

查看表结构,id字段设置成了PRI主键索引 

+-------+-------------+------+-----+---------+-------+

 | Field   | Type            | Null  | Key  | Default   | Extra  |

+-------+-------------+------+-----+---------+-------+

 | id       | int(11)         | NO    | PRI   | NULL     |            |

 | name | varchar(30)  | NO    |         |               |           |

+-------+-------------+------+-----+---------+-------+

这样id字段就不能存重复的值了

第一次id字段可以插入数值1

insert into t6 (id, name)values(1, '一点');

第二次id字段再插入数值1就出错了,返回 ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY' 主键值重复

insert into t6 (id, name)values(1, '二点');

select * from t6;

没有插入进入,只有第一次插入的一条记录

+----+------+

 |  id  | name|

+----+------+

 |   1  | 一点  |

+----+------+


主键索引,也可以在创建表时,字段的下面设置

create table t7(
	id int not null auto_increment,
	name varchar(30) not null default '',
	age tinyint not null default 0,
	primary key(id) -- 可以在这指定主键
);

desc t7;

id字段是PRI,Null列NO的意思是不允许为空

+-------+-------------+------+-----+---------+----------------+

 | Field   | Type            | Null  | Key   | Default | Extra                |

+-------+-------------+------+-----+---------+----------------+

 | id       | int(11)          | NO   | PRI   | NULL     | auto_increment |

 | name | varchar(30)  | NO   |          |              |                         |

 | age    | tinyint(4)      | NO   |          | 0           |                         |

+-------+-------------+------+-----+---------+----------------+

建议每张表都建立一个主键索引

2、唯一索引

唯一索引的作用和主键索引一样,都可以防止创建重复的值

不同在于每一个数据表中只能有一个主键索引,但是可以有多个唯一索引。

唯一索引用unique关键字来创建


如果能确保某个数据列,只包含彼此各不同的值,在为这个数据库列创建索引的时候,就应该使用唯一索引unique来修饰。

这样在新记录插入的时候,就会自动检查新记录这个字段的值,是否已经在某个现有记录的字段里出现过了,如果出现过了Mysql将拒绝插入。

其实创建唯一索引的目的,往往不是为了提高访问速度,而只是为了避免数据出现重复。


比如创建用户表,

1). 不想让用户名name列重复,使用unique属性来修饰

2). id字段设置主键索引primary key(id)

create table users(
	id int not null auto_increment,
	name varchar(30) not null default '' unique,
	age tinyint unsigned not null default 0,
	primary key(id)
);

id列自动增长不用插入,就插入name名字列和age年龄列,第一次插入成功

insert into users (name, age) values ('zhu', '40');

第二次再插入就拒绝了,返回 ERROR 1062 (23000): Duplicate entry 'zhu' for key 'name'

insert into users (name, age) values ('zhu', '40');

查看表结构

desc users;

name字段是UNI唯一索引,不能插入重复的值

+-------+---------------------+------+-----+---------+----------------+ 

 | Field   | Type                       | Null   | Key  | Default  | Extra                |

+-------+---------------------+------+-----+---------+----------------+

 | id        | int(11)                    | NO    | PRI   | NULL     | auto_increment |

 | name  | varchar(30)             | NO   | UNI  |               |                         |

 | age     | tinyint(3) unsigned | NO   |         | 0            |                         |

+-------+---------------------+------+-----+---------+----------------+


name列插入一不同的数据值'zhu2'就可以了

insert into users (name, age) values ('zhu2', '40');

select * from users;

+----+------+-----+

 | id   | name | age |

+----+------+-----+

 |  1   | zhu    |  40   |

 |  3   | zhu2  |  40   |

+----+------+-----+

一张表可以在多个字段设置唯一索引,比如文章名字,个人介绍等等,都不让重复的字段设置唯一索引,而主键索引一张表只能设置一个列。

主键索引是标识唯一性的,每张表只能有一个,唯一索引一个张表可以给多个字段设置。

3、常规索引

常规索引是创建数据表最重要的技术,

为什么常规索引是最重要的技术?因为他能提升数据库的性能。

索引优化,首先应该考虑的就是"常规索引"。


要查询数据库就需要进行全表扫描,有索引的列表,是在一个索引列上排序的一个数据表,可以通过索引快速的定位到记录。


如果没有加索引呢?

假设有一万(10000)条记录,

如果要查询的数据恰巧在第一条,很快就能查出来,

如果要查询的数据表的最后面,也就是最后一条,就要先读过前边9999条才能找到这第一万条,效率是很低的。


假如,去图书馆找一本书《细说PHP》,不知道书在哪,就要一本一本的找,要花很长时间

而我们按 索引顺序,

1). 先看在那个楼层,第5层全是计算机的书,就直接排除掉了很多小说、文学等别的书

2). 然后在5层的计算机的书里面找软件开发的书,其它的网络、数据库等书又过滤掉了

3). 软件开发中就定位到PHP

4). PHP那么多书就在一个书架上了,然后就能找到《细说PHP》


数据表加索引也是这个意思,按照索引的值很快就能找这条记录的位置,哪怕数据在表的最后一条,比如一万条件记录,有可能就找十次左右或上百次左右就能找到了,不用一万条记录都遍历。

所以数据库里面有索引,就能得到最佳性能方面的提升。

如果是没有索引的数据表就是没有排序数据的集合,如果查询数据就需要进行全表扫描,有索引只是在索引列上进行排序的表,可以很快定义到记录。


另外不同的表类型,索引也是不一样的,

常规索引也是有缺点的,例如多占用磁盘空间,要好好设计一下,不然不仅不会提升性能,还会减少性能,怎么设计常规索引呢?

常规索引可以提高查找速度,因为访问网站主要是查找,但是会减慢数据列上插入、删除、修改的速度。


比如还是书店的例子,

在书店按照索引顺序很快找到《细说PHP》这本书了,

但是新书上架时,也是按照索引的顺序,比如把计算机的书搬到到五层,然后必须找到PHP的书架,然后把新书插入到书架上,这是插入的速度。


如果新书放错了错了,修改的速度,或者书下架了删除的速度,都要按照这个索引的顺序,那层放什么方面的书,那层的书怎么分类。

如果没有索引的话,就可以不按这个顺序。

因为有索引,在插入、删除、修改数据的时候,也会按照索引顺序去摆放数据,所以查询上提高了,但是插入、删除、修改上减慢了


虽然多个字段都可以建立常规索引,但是不要把表的每个字段都创建成常规索引,

1). 关系型数据库可以把表分开,

     有索引的字段专门放到一张表里面,没有索引的放到另外一张表里面,

     然后两张表用一个字段关联就可以了,这是分表。

2). 不分表也要注意,在什么字段上创建常规索引,

     比如需要作为条件搜索的字段(where条件搜索的)、

     需要作为条件排序的(order by)、

     需要作为条件分组的(group by),

     涉及到这样的数据列上,最适合创建常规索引,

     当然索引也不要创建太多,索引会消耗系统资源适可而止。


怎么创建常规索引?

1). 常规索引和表一样是独立的数据对象,可以单独的增删改查

2). 也可在创建表时,直接就创建了


常规索引最主要的就是知道索引的原理,为什么要加索引,加索引就很简单了。

比如刚才创建的这张用户表users,是没有常规索引的

create table users(
	id int not null auto_increment,
	name varchar(30) not null default '' unique,
	age tinyint unsigned not null default 0,
	primary key(id)
);


因为有两种创建索引方法,

第一种是在创建表的时候创建,

第二种是单独创建索引,


下面单独创建

因为跟表是一样的数据对象,

语法 CREATE INDEX 索引名 ON 表名字段名1字段名2 ); 

create index ind1 on users(name, age);

desc users;

查询表结构,看不到常规索引

+-------+---------------------+------+-----+---------+----------------+

 | Field   | Type                       | Null   | Key  | Default  | Extra                |

+-------+---------------------+------+-----+---------+----------------+

 | id        | int(11)                    | NO    | PRI   | NULL     | auto_increment|

 | name  | varchar(30)            | NO    | UNI  |               |                         |

 | age     | tinyint(3) unsigned| NO    |         | 0            |                         |

+-------+---------------------+------+-----+---------+----------------+


查看users中的索引

show index from users;

show index from users\G -- 竖着的形式查看

表比较长,截取一部分

+-------+--------------+-----------+---------------+------------

 | Table  | Non_unique | Key_name | Seq_in_index | Column_name

+-------+--------------+-----------+---------------+------------

 | users  |          0          | PRIMARY  |            1         | id

 | users  |          0          | name        |            1         | name

 | users  |          1          | ind1          |            1         | name

 | users  |          1          | ind1          |            2         | age

+-------+--------------+-----------+---------------+-----------

这样查询的时候,如果数据量比较多时,按照name名字查询或者age年龄查询,都会加快查询速度,所以索引是必须设置的。


既然是独立创建了,就可以删除这个索引,因为是独立管理的,可以单独管理。

语法:DROP INDEX 索引名 on 数据库名;

drop index ind1 on users;

这样这个表又没有索引了,这是后期的管理,增删改查都可以


怎么在创建表的时候加索引?

比如创建一个购物车carts表

uid:用户id

sid:商品id

number:购物车数量

indexkey是同义词,使用index和key是同一个作用

语法:key 索引名字段名 )  最好索引名和字段名是一样的

create table carts(
	id int auto_increment not null,
	uid int not null,
	sid int not null,
	number int not null,
	primary key(id),
	key cuid(uid),  -- 常规索引
	index csid(sid)  -- 常规索引
);

多列都可以一起指定索引,写一个索引名字,括号里写两个字段名

create table carts1(
	id int,
	uid int,
	sid int,
	num int,
	key snid(sid, num)
);

索引写在一起用一个名字,删除索引时,两个字段的索引都删除了

语法:DROP INDEX 索引名 ON 数据表名

drop index snid on carts1;

两个索引分别指定,有两个索引名字,一次只能删除一个索引

drop index cuid on carts;

另外还有一个索引,要删除两次,才能把carts表里的索引都删除

drop index csid on carts;

索引写在一起指定,当然也可以一个一个写索引名,可以单独管理,各有各的好处和优缺点


常规索引是创建表时候的优化,最主要的一分部分,因为其它优化第是sql语句的优化,是增删改查中的优化,

创建表的优化主要是在索引上,因为别的都是步骤,主要就在索引这块。

4、全文索引

mysql版本从3.23开始就支持全文索引搜索了

在不使用匹配模式的前提下,去搜索单词或者短语


全文索引在Mysql中是fulltext类型索引

1). 全文索引只能在MyISAM表类型上使用,

2). 并且只有在varcharchartext这样文本字符串上使用

3). 也可以在多个数据列使用

全文索引是一种特殊的索引,他会把某个数据表中的某个数据列里出现过的所有单词生成一份清单


全文索引用的比较少,比如创建一个书的表

bookname书的名称

price书的价格

detail书的介绍

然后,

1). 在书的名字bookname、书的介绍detail这两个字符串类型的字段上加全文索引

2). 按价格查询的时候会用到索引,在书的价格price字段上加常规索引

3). 在id字段上加主键

create table books(
	id int auto_increment not null,
	bookname varchar(30) not null,
	price double not null,
	detail text not null,
	fulltext(detail, bookname), -- 全文索引
	index price(price),
	primary key(id)
)engine=MyISAM charset=utf8;


如果不设置全文索引,通常这样写sql语句

查看书名中有没有包含'php'的字符,用like匹配的方式效率很低

select * from books where bookname like '%php%';


有了全文索引

1). 用系统的函数MATCH(detail)去指定查询那个字段,

2). 在detail字段中查询什么单词,用AGAINST('PHP')

3). 就是在detail字段中查找有'PHP'的单词

只要包含'PHP'这个片段的,书名和价格都查询出来,以相关性从高到第的顺序排序。

select bookname ,price from books where MATCH(detail) AGAINST('PHP');

另外match、against这两个函数不光是做where条件,

比如除了在where子句中应用,还可以放在where查询体中

select match(detail) against('php') from books;


注意:

全文索引返回错误 ERROR 1191 (HY000): Can't find FULLTEXT index matching the column list

解决方法 match(detil, bakname里面要把全文索引的字段都写了

select * from books where MATCH(detail, bookname) AGAINST('PHP');

select match(detail, bookname) against('php') from books;

从下面的地址查到,报错解决方法

http://www.gaodaima.com/6124.html


MySQL创建数据表(下)

有三部分内容:

1.创建表的时候还需要指定[表类型]

2.和指定[表字符集]

3.以及在运行过程中如何修改表


CREATE TABLE [ IF NOT EXISTS ] 表名称(

    字段名1 列类型 [属性] [索引],

    字段名2 列类型 [属性] [索引],

    ...

    字段名n 列类型 [属性] [索引],

) [表类型] [表字符集];

六、数据表类型及存储位置

Mysql和大多数数据库不同,Mysql有一个存储引擎的概念。针对不同的存储需要,可以选择最优的存储引擎

这是Mysql的特点,是别的数据库是不具备的,但是有这个特点给创建表时,稍稍带来一点麻烦。


下面学习用哪个存储引擎,然后使用的时候该选择哪个存储引擎

Mysql存储引擎属于插件式的,这种插件式的存储引擎,是Mysql数据库最重要的特性之一。


可以根据应用的需要,选择如何储索引数据,是否使用事务等等。

Myslq默认支持多种存储引擎,以适用于不同领域数据库的应用的需要。

可以通过选择使用不同的存储引擎,提高应用的效率,提供灵活的存储,甚至可以按照自己的需求,定制和使用自己的存储引擎,以实现最大成度的可制定性。

自从mysql5.0以上,支持的存储引擎有很多,通常我们把这种支持的存储引擎也叫做数据表类型


下面的命令,查看当前Mysql支持多少中存储引擎

show engines;

支持这么多种存储引擎,有就是表的类型,目前版本DEFAULT缺省值默认的是InnoDB

+--------------------+---------+-------

 | Engine                   | Support | Comment

+--------------------+---------+--------

 | MEMORY              | YES        | Hash based, stored in 

 | CSV                       | YES        | CSV storage engine

 | MyISAM                | YES        | MyISAM storage engine

 | BLACKHOLE          | YES        | /dev/null storage engine

 | InnoDB                  | DEFAULT | Supports transactions, 

 | MRG_MYISAM      | YES        | Collection of 

 | ARCHIVE               | YES        | Archive storage 

 | PERFORMANCE_SCHEMA | YES     | Performance 

 | FEDERATED          | NO         | Federated 

+--------------------+---------+----------

如果不设置就使用默认的InnoDB表类型


默认的表类型是配置文件指定的,所以还可以从配置文件里看默认的表类型

show variables like 'table_type';  -- MySQL5.5.3后这个参数被取消了,所以返回Empty set (0.012 sec)

这么多表类型,重要的是MySIAM 和 InnoDB两种常用的


创建表的时候不用默认的,如何自己指定表类型?

使用type或者engine这个关键字来指定表类型,typeengine是一个意思,或者是别名的意思

create table 表名 () type = InnoDB;

create table 表名 () engine = InnoDB;


Mysql针对不同的存储选择最优的表类型,选择MyISAM还是选择InnoDB,这两种存储引擎之间是什么差别?

有一点需要注意,在一个Mysql库中,创建表时候可以为每张表,指定不同的表类型,也就是同一个库中可以有多种不同的表类型存在。


MyISAM类型的特点:

1). 成熟稳定易于管理,他使用一种表格锁定的机制,用来优化多个并发的读写操作

2). 其代价是创建完表后,需要经常使用 OPTIMIZE TABLE 表名命令,来恢复和更新机制所浪费的空间,

     有就是说MyISAM表类型在我们经常增添改查的时候会出现一些碎片,用 OPTIMIZE TABLE 表名命令进行碎片整理,用来恢复被更新机制所浪费的空间。

3). MyISAM类型还有一些有用的扩展,比如用来修复数据库浪费的空间,主要是强调快速读取操作,而且是一种成熟的引擎,

     PHP操作网站的时候,大量的数据操作都是读取操作,所以很多空间提供商只允许使用这种格式。


但是MyISAM类型也有缺点,有一些功能不支持

每种表类型(引擎)都有各自的优缺点,我们用的时候,就选择这种表类型的优点用就可以了。


InnoDB类型的特点:

InnoDB类型可以看做是MyISAM的更新换代产品,

1). InnoDB提供了具有事务的提交、回滚、还有崩溃恢复能力的这些事务安全的存储引擎

2). InnoDB也支持外键的机制,MyISAM引擎不支持外键,所以一些开源的项目很少使用外键索引

3). InnoDB这种类型的表,可以与其它Mysql其它类型的表混合起来,甚至在同一查询中可以混合的使用


InnoDB支持MyISAM所不支持的功能,但也有缺点

1). InnoDB引擎的表类型空间占用量,要比MyISAM表要大的多

2). InnoDB引擎读写速度也没有MyISAM快

3). 不支持全文索引等内容


这两个引擎如何选择呢?

MySIAM类型的表和InnoDB类型的数据表,可以同时出现在一个数据库里面,

这样可以根据每一个数据表的内容数据和具体的用途,选择一个最佳的数据表类型。

对比一下:

功能MyISAMInnoDB
事务处理不支持支持
数据行锁定不支持支持
外键约束不支持支持
表空间占用相对小相对大,最大2倍数
全文索引支持不支持(后来也支持了)

如果希望想节省空间和时间,想要速度快的方式来管理表MyISAM擎管是首选

如果程序需要用到事务、使用外键、需要更高的安全性,以及需要允许很多用户同时修改某个数据表里的数据InnoDB的数据表就更值得考虑了。


创建表并指定表引擎:

t1表,指定InnoDB型

t2表,指定MyISAM型

t3表,不指定类型是用默认类型

create database engdome; -- 创建数据库engdome

create table t1(
	id int
)engine=InnoDB;

create table t2(
	id int
)type=MyISAM;

create table t3(
	id int
);


表存储位置

\mysql\data目录下有一个engdome库

mysql数据库以记录形式记录在表中,而表则是以文件的形式存储在磁盘目录中

engdome文件就存储表的目录,每一种类型的表有不同的存储格式,但是有一个共同的特点

每个表至少有一存放文件结构 .frm 的文件


MyISAM类型的数据表有三个文件

t2.frm是存储表结构的,

t2.MYD是存储表数据的,

t2.MYI是专门保存索引的文件,索引也是一个独立的数据对象。


InnoDB类型的表,只有t1.frm一个文件存表结构(目前这个地方有写变化)

七、MySQL默认字符集

在我们数据库里面和程序里面能使用的汉字字符集有那些?

ACSII:最早的奠基性的一个字符集,用七个字节,所以字符集都支持ACSII

ISO-8859-1也称为latin1:西欧字符集,八位的编码,经常被一些程序员用来转码用

gb2312-80:gb是国标的缩写,80是八零年代,80年或81年发布的,双字编码的字符集定长,收录了大概有6700多个汉字

gb13000:全称是"信息即使通用的……",93年发布的,大概收录了27400多个汉字,以及一些偏旁部首等等,几乎没有得到业界的支持,用的很少

GBK:gb是国标,k是扩展,95年发布的,在gb2312的基础上进行了扩充……

GB18030:2000年发布的,占用空间两个字节或四个字节,数据支持的比较少见


UTF-32 四个字节字符集,很少使用

USC-2  两个字节字符集,window2000内部使用的就是这个字符集

UTF-16 两个或四个字节的编码,JAVA、winxp、winNT内部使用的是这个字符集

UTF-8  一个字节到4个字节编码,是互联网、UNIX、LINUK广泛支持的字符集,强烈推荐使用

UTF-8统一用这个字符集,变长,汉字占三个字符,


mysql可以支持多种字符集,在同一台服务器,同一个数据库,甚至同一张表的不同字段,都可以指定不同的字符集

查看mysql支持的所有字符集,课程里说有36个,实际显示的是有40左右个

show character set;

+----------+---------------------------------+------------------

 | Charset   | Description                              | Default collation

+----------+---------------------------------+------------------

 | big5        | Big5 Traditional Chinese         | big5_chinese_ci

 | latin1      | cp1252 West European           | latin1_swedish_ci 

 | gbk         | GBK Simplified Chinese          | gbk_chinese_ci

 | utf8        | UTF-8 Unicode                        | utf8_general_ci

 | utf32      | UTF-32 Unicode                      | utf32_general_ci

……

注意:数据库中写的是UTF-8,我们在使用的时候要写成 utf8 没有中间的杠(有些初学者中间加杠,所以设置失败)

查看默认的字符集和校对的字符集。这个存疑,老师也没说,不知道体现在哪!不是这个命令

desc information_schema.character_sets;

+----------------------+-------------

 | Field                         | Type

+----------------------+-------------

 | CHARACTER_SET_NAME     | varchar(32)

 | DEFAULT_COLLATE_NAME | varchar(32)

 | DESCRIPTION                     | varchar(60)

 | MAXLEN                             | bigint(3)

+----------------------+-------------

Mysql的字符集包括,字符集和校对规则两个概念,

1). 字符集:是用来定义Mysql存储字符串的方式

2). 校对规则:是对规则,是定义了比较字符串的方式


字符集和校对规则是一对多的关系,一个字符集可对应多个校对规则

mysql支持的字符集比如有30多个,校对规则大概有70多个,是字符集的2倍以上


比如查看gbk的校对规则

show collation like 'gbk%';

gbk字符集对应的校对规则有两个 gbk_chinese_ci  gbk_bin

+----------------+---------+----+---------+----------+---------+

 | Collation         | Charset | Id    | Default  | Compiled| Sortlen  |

+----------------+---------+----+---------+----------+---------+

 | gbk_chinese_ci| gbk       | 28   | Yes        | Yes          |       1     |

 | gbk_bin           | gbk       | 87   |               | Yes          |       1     |

+----------------+---------+----+---------+----------+---------+


再来查看utf8的校对规则

show collation like 'utf8%';

utf8是多个国家用的字符集,所以他校对规则很多

+--------------------------+---------

 | Collation                        | Charset

+--------------------------+---------

 | utf8_general_ci              | utf8

 | utf8_bin                         | utf8

 | utf8_unicode_ci             | utf8


校对规则有三种结尾

_ci 结尾的意思是,比较的时候大小写不铭感的,不区分大小写的

_cs 结尾的是对大小写铭感的,没看到这个结尾,没看到_cs结尾的

_bin 是二进制的比较,PS:我觉得既然是二进制,那大小写应该铭感


服务器的字符集 和 校对规则

打开Mysql配置文件,位置在xampp\mysql\bin目录下my.ini文件

在mysql启动的时候会自动加载这个配置文件,我在这个文件下没找到 default-character-set = utf8 这个行设置

视频里高老师用的是AppServ集成环境,配置文件在MYSQL目录下就直接有my.ini文件

如果安装Mysql的时候没有特定的指定服务器的字符集,默认的字符集是latin1


\s   查看一下

Server characterset: utf8mb4   服务器字符集,如果没有指定默认是latin1西欧字符集

Db     characterset: utf8mb4

Client characterset: gbk

Conn.  characterset: gbk


我们只看到了字符集,没有看到校对规则,所以使用默认的校对规则

如果想使用字符集的非默认的校对规则,就需要指定字符集的同时指定校对规则


查看Mysql服务器的字符集(这是查看服务器变量)

show variables like 'character_set_server';

设置的是utf8mb4

+----------------------+---------+

 | Variable_name         | Value     |

+----------------------+---------+

 | character_set_server| utf8mb4|

+----------------------+---------+

查看Mysql服务器的校对规则

show variables like 'collation_server';

校对规则是utf8mb4_general_ci不区分小写的

+------------------+--------------------+

 | Variable_name   | Value                    |

+------------------+--------------------+

 | collation_server | utf8mb4_general_ci |

+------------------+--------------------+


数据库的字符集和校对规则,可以在创建数据库的时候指定

也可以在创建完数据库,通过更改数据库命令进行修改,也是可以的。


创建数据库的时候指定字符集校对规则

create database dblemon default character set utf8 collate utf8_general_ci;

use dblemon; -- 进入dblemon库

\s -- 查看

Server characterset: utf8mb4   服务器的字符集还是utf8mb4

Db     characterset: utf8            数据的字符集指定的是utf8

Client characterset: gbk

Conn.  characterset: gbk


如果创建数据库时候不指定字符集

create database dblemon2;

use dblemon2;

\s

Server characterset: utf8mb4   服务器默认字符集 

Db     characterset: utf8mb4    不指定就用的是服务器默认的字符集utf8mb4

Client characterset: gbk

Conn.  characterset: gbk


创建表的时候不指定字符集,默认就用数据库的,根数据库一样,创建表的时候也可以指定字符集

use lemon2

create table t1(
	id int
)engine=MyISAM default character set utf8 collate utf8_general_ci;

表里的每个字段也可以指定字符集,方法是一样的,但是没有必要了

其实还有设置链接字符集和校队规则,

也就是说前面的设置只是数据保存的时候,所用的字符集和校对规则

对于实际的应用访问来说,还存在客户端和服务器之间这种,相互的字符集和校对的设置

比如客户端和服务器交互的操作,mysql提供了三种不同的一些参数


客户端与服务器交互的时候,用什么字符集呢?

我们可以指定三种

character_set_client            设置客户端字符集

character_set_connection   设置链接字符集

character_set_results           设置返回的结果集,使用什么字符集


通常情况下,这三个字符集应该是相同的,尤其是中文环境下。注意是通常情况下,高老师的用词还是很严谨的。


这条命令可以同时修改上面三条命令的值

set names gbk;

查看一下,上面创建的dblemon2库的字符集

\s   现在链接和客户端的字符集都变gbk了,服务器、数据库的还是utf8mb4

Current database:    dblemon2

Server characterset: utf8mb4

Db     characterset: utf8mb4

Client characterset: gbk          客户端字符集被改变了

Conn.  characterset: gbk         链接字符集被改变了


还可以更改数据库的字符集,

1). use dblemon2 数据库命令

2). 执行下面命令

alter database character set gbk;

\s    数据库的字符集变gbk了

Current database:    dblemon2

Server characterset: utf8mb4  服务器这里就要更改配置文件了

Db     characterset: gbk           数据库的字符集变gbk

Client characterset: gbk

Conn.  characterset: gbk


更改表的字符集也是一样的

语法:alter table 表名 character set utf8; 

alter table t1 character set utf8;

备份数据库

备份数据库 dblemon2库

1). 先退出 exit;

2). 备份命令(命令后面不加分号,https://segmentfault.com/q/1010000002544120)

3). 输入密码,回车

exit;

mysqldump -h localhost -u root -p --default-character-set=gbk -d dblemon2 > d:/bak/tab.sql -- 按照gbk字符集导出来

再导进去

1). 新建一个库,不新建也行

2). exit退出

3). 导入语句

create database dblemon3;

exit;

mysql -u root -p dblemon3 < d:/bak/tab.sql


总结

mysql支持那些字符集,各种字符集之间的区别

utf8字符集用起来比较好

怎么改服务器字符集,怎么改数据库的字符集,怎么改表字符集,怎么改链接客户端的字符集

八、修改表

alter table 修改表的语句

看一下帮 ? alter table 

语法还是很多

……

ADD COLUMN [IF NOT EXISTS]

ADD INDEX [IF NOT EXISTS]

ADD FOREIGN KEY [IF NOT EXISTS]

ADD PARTITION [IF NOT EXISTS]

CREATE INDEX [IF NOT EXISTS]


DROP COLUMN [IF EXISTS]

DROP INDEX [IF EXISTS]

DROP FOREIGN KEY [IF EXISTS]

DROP PARTITION [IF EXISTS]

CHANGE COLUMN [IF EXISTS]

MODIFY COLUMN [IF EXISTS]

DROP INDEX [IF EXISTS]

……


创建一个库dbsummer,一张表t1

create database dbsummer;

CREATE TABLE `t1` (
  `id` int(11) not null DEFAULT 0
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


给t1表,增加一个名字name字段,varchar的类型、属性

alter table t1 add name varchar(30) not null default '';

desc t1;

+-------+-------------+------+-----+---------+-------+

 | Field   | Type            | Null  | Key   | Default | Extra   |

+-------+-------------+------+-----+---------+-------+

 | id        | int(11)         | NO   |          | 0           |            |

 | name  | varchar(30) | NO   |          |              |            |

+-------+-------------+------+-----+---------+-------+

再增加一个age年龄字段,要求无符号,不为空,缺省值是0

alter table t1 add age tinyint unsigned not null default 0;

desc t1;

+-------+---------------------+------+-----+---------+-------+

 | Field   | Type                       | Null   | Key  | Default  | Extra   |

+-------+---------------------+------+-----+---------+-------+

 | id       | int(11)                     | NO    |         | 0            |           |

 | name | varchar(30)             | NO    |         |               |           |

 | age    | tinyint(3) unsigned | NO    |         | 0            |           |

+-------+---------------------+------+-----+---------+-------+

如果想按自己指定的顺序,比如在名字name字段后面,加一个性别sex字段

alter table t1 add sex char(3) not null default '女' after name;

desc t1;

+--------+---------------------+------+-----+---------+-------+

 | Field    | Type                        | Null   | Key  | Default  | Extra   |

+--------+---------------------+------+-----+---------+-------+

 | id         | int(11)                    | NO     |        | 0            |           |

 | name   | varchar(30)             | NO    |         |              |            |

 | sex       | char(3)                    | NO    |         | 女          |           |

 | age      | tinyint(3) unsigned | NO    |         | 0           |            |

+--------+---------------------+------+-----+---------+-------+

怎么在第一个id字段前面加字段?

alter table t1 add height double(4,1) not null default 180.3  first;

desc t1;

+--------+---------------------+------+-----+---------+-------+

 | Field    | Type                        | Null   | Key  | Default  | Extra   |

+--------+---------------------+------+-----+---------+-------+

 | height | double(4,1)             | NO     |        | 180.3     |           |

 | id         | int(11)                    | NO     |        | 0            |           |

 | name   | varchar(30)             | NO    |         |              |            |

 | sex       | char(3)                    | NO    |         | 女          |           |

 | age      | tinyint(3) unsigned | NO    |         | 0           |            |

+--------+---------------------+------+-----+---------+-------+


修改字段有change 和 modify两个关键字,这两个有什么区别?


把性别sex字段,var类型改成varchar(3)类型

alter table t1 modify sex varchar(3) not null default '男';

desc t1;

+--------+---------------------+------+-----+---------+-------+

 | Field     | Type                       | Null   | Key | Default   | Extra   |

+--------+---------------------+------+-----+---------+-------+

 | height  | double(4,1)             | NO   |         | 180.3      |           |

 | id         | int(11)                     | NO   |          | 0            |           |

 | name   | varchar(30)              | NO   |         |               |           |

 | sex       | varchar(3)               | NO    |         | 男          |            |

 | age      | tinyint(3) unsigned | NO    |         | 0           |            |

+--------+---------------------+------+-----+---------+-------+

用户名name改成username,就不能用关键字modify,modify适合改类型

如果链改字段名都要改用change

alter table t1 change name username varchar(30) not null default '';

desc t1;

+----------+---------------------+------+-----+---------+-------+

 | Field       | Type                        | Null   | Key | Default  | Extra   |

+----------+---------------------+------+-----+---------+-------+

 | height    | double(4,1)              | NO   |         | 180.3     |            |

 | id           | int(11)                      | NO   |         | 0            |            |

 | username | varchar(30)           | NO    |        |               |            |

 | sex          | varchar(3)               | NO    |        | 男           |           |

 | age         | tinyint(3) unsigned | NO    |        | 0            |            |

+----------+---------------------+------+-----+---------+-------+


数据表名t1本身也可以改成users

alter table t1 rename as users;

desc users;

show tables;


删除表中的height字段

alter table users drop height;

desc users;

+----------+---------------------+------+-----+---------+-------+

 | Field       | Type                        | Null  | Key   | Default | Extra   |

+----------+---------------------+------+-----+---------+-------+

 | id            | int(11)                     | NO   |          | 0           |            |

 | username| varchar(30)            | NO   |           |              |           |

 | sex          | varchar(3)               | NO   |          | 男          |            |

 | age         | tinyint(3) unsigned | NO   |          | 0           |            |

+----------+---------------------+------+-----+---------+-------+


删除数据表users

drop table if exists users;


mysql常用反斜杠命令 https://blog.csdn.net/weixin_30718391/article/details/96543644


合抱之木, 生于毫末; 九层之台, 起于累土; 千里之行, 始于足下。




Leave a comment 0 Comments.

Leave a Reply

换一张