【存储引擎】
引入:
日常生活中文件格式有很多中,并且针对不同的文件格式会有对应不同存储方式和处理机制(txtpdfword,mp4...)
针对不同的数据应该有对应的不同的处理机制来存储
1 补充:MySQL默认忽略英文的大小写,也可以改,但不推荐改! 2 3 存储引擎: 数据库针对数据采取的多种存取方式 4 ----------------------------- 5 查看mysql能够切换的引擎名称 的命令 show engines; 6 ----------------------------- 7 需要了解的四个存储引擎 8 MyISAM 9 MySQL5.5之前默认的存储引擎!!!!!! 10 存取数据的速度快 但是功能较少 安全性较低!!!!!! 11 ------------------------------------------- 12 InnoDB 13 MySQL5.5之后默认的存储引擎!!!!!! 14 支持事务、行锁、外键等操作 存取速度没有MyISAM快 但是安全性更高!!! 15 -------------------------------------------- 16 Memory 17 基于内存存取数据 仅用于临时表数据存取!!!!!! 18 -------------------------------------------- 19 BlackHole 20 任何写入进去的数据都会立刻丢失!!!!!! 21 主要做一些集群备份的时候数据的处理(了解即可)
了解不同存储引擎底层对应的文件个数
# 文件:是操作系统暴露给用户操作硬盘的快捷方式!!!
create database helloworld;
use helloworld;
create table t1(id int) engine=innodb;
create table t2(id int) engine=myisam;
create table t3(id int) engine=memory;
create table t4(id int) engine=blackhole;
-------------------------------------------------------
1.innodb引擎 对应两个文件
.frm 表结构
.ibd 表数据与表索引(加快数据查询的)
------
2.myisam引擎 对应三个文件 由于分工分的更细,所以速度比innodb快点
.frm 表结构
.MYD 表数据
.MYI 表索引
------
3.memory引擎 对应一个文件 由于是基于内存存储数据的,所以不需要有表数据文件,有一个表结构文件就行了
.frm 表结构
------
4.blackhole引擎 对应一个文件
.frm 表结构
-------------------------------------------------------
insert into t1 values(1);
insert into t2 values(1);
insert into t3 values(1); # 内存清掉,插入的数据就没了
insert into t4 values(1); # 往里面插入任何数据,数据都会丢!!!
。
。
。
创建表的完整语法
create table 表名(
字段名 字段类型(数字) 约束条件,
字段名 字段类型(数字) 约束条件,
字段名 字段类型(数字) 约束条件
);
-------------------------------
字段比较多可以换行编写!!!
注意事项:
1.字段名和字段类型是必须的!!!
2.数字和约束条件是可选的!!!
3.约束条件也可以写多个,空格隔开即可!!!
4.最后一行结尾不能加逗号!!!
--------------------------------
ps:编写SQL语句报错之后不要慌 仔细查看提示 会很快解决
一般就看 near后面的提示,提示你哪句话附近有问题!!
--------------------------------------------
补充:宽度一般情况下指的是对存储数据的限制
针对不同的版本会出现不同的效果
5.6版本默认没有开启严格模式 规定只能存一个字符你给了多个字符,那么我会自动帮你截取
5.7版本及以上或者开启了严格模式 那么规定只能存几个 就不能超,一旦超出范围立刻报错:Data too long for column 'name' at row 1
严格模式到底开不开呢?
MySQL5.7之后的版本默认都是开启严格模式的
=====================================================================================================
【整型字段】
(1bytes=8bit)
下面是4种不同的整型
tinyint 1bytes 正负号(占1bit)
smallint 2bytes 正负号(占1bit)
int 4bytes 正负号(占1bit)
bigint 8bytes 正负号(占1bit)
1个字节8个bit位八个比特位的二进制数据最多能表示到十进制数字255,二的8次方减1
如果涉及到有正负号的数字,正负号占一个bit位,
这样7个比特位的二进制最多只能表示到十进制数字+127
2个字节 那就是二的16次方减一 65535,同理有正负号的情况下,
最多只能表示到二的15次方减一 32767
3个字节 二的24次方减一 16777215,同理有正负号的情况下,
最多只能表示到二的23次方减一 8388607
4个字节 也同理计算!! 4294967295 有正负号情况下最大 2147483647
int 最大只能存10位的数字,要存手机号的话用int就不行了,手机号是11位数字!!
要用bigint了或者只用字符串去存手机号!!!
一些比较长的整形数字,用字符串存可能会更合适一点!!!
------------------------------------------
验证整型默认是否携带正负号
create table t1(id tinyint);
insert into t1 values(-129),(128);
结果是-128和127 因为在有正负号的情况下最小只能到-128 最大只能到127
所以你只要用tinyint 你输的再大再小,只要超范围了,最后存进去的都是127与-128
也就意味着tinyint默认自带正负号!!!牺牲掉一个比特位,
---------------------------------------------------
我们也可以取消正负号 在tinyint后面加unsigned
就表示不要正负号了 unsigned是一个约束条件
create table t2(id tinyint unsigned);
insert into t2 values(-199),(1000);
结果是0和255 还是一样的原理,超过了就存最大值最小值
。
。
。
【严格模式】
模糊匹配:
关键字 like
通配符:% 表示匹配任意多个字符
_ 表示匹配任意一个字符
这个时候应该让减少压力及工作量
修改严格模式:
set session 只在当前窗口有效
set global 在全局范围内有效
set global sql_mode = 'STRICT_TRANS_TABLES';
修改完之后,重新进入服务端
【浮点型】
# 3种不同的浮点型,类型从float---double---decimal 存进去的小数越来越精确!!! float(20,10) # 总共存储20位数,小数点后面占10位数 前一个数表示总共要存的位数,后一位表示小数点后面要存的位数 4个字节 # 注意浮点型计算最大数字的方法与整型不一样!!! ------------------------------------------------- double(20,10) # 总共存储20位数 小数点后面占10 8个字节 ------------------------------------------------ decimal(20,10) # 总共存储20位数 小数点后面占10 8个字节 ----------------------------------------------- 举例: create table t3(id float(60,20)); create table t4(id double(60,20)); create table t5(id decimal(60,20)); insert into t3 values(1.11111111111111111111); insert into t4 values(1.11111111111111111111); insert into t5 values(1.11111111111111111111); ---------------------------------------------------- 三者的核心区别在于精确度不同 float < double < decimal ---------------------------------------------------- 正常情况最低的精度float就足够用了!!!!!!
【字符型】
使用频率最高的!!!
char 定长字符
char(4)
最多存储四个字符 超出就报错 不够四个空格填充至四个
也就是说当创建一个表的时候,当指定了字段名与字段类型为char(4),且括号里面写了4,
就是说以后往该字段名下面插入数据时,数据最多就4个字符,数据超出4个字符就报错 ,
不够四个字符,就用空格填充至四个字符!!!
一个空格就是一个字符。
----------------------------------------------------------
varchar 变长字符
varchar(4) 最多存储四个字符 超出就报错 不够则有几位存几位!!!!!!!!
注意:varchar 括号里面的数字尽量写16的倍数
varchar的最大存储字节数是65535,如果我们用的utf8mb3编码格式,1个字符3个字节
3*21844 = 65532
那么括号里写的最大字符数就是21844,为了保险,加满足16的倍数,
# 最大字符数写21760左右就行了!!!
----------------------------------------------------------
create table t6(id int, name char(4));
create table t7(id int, name varchar(4));
insert into t6 values(1, 'jason1'); # 会报错,'jason1'字符长度超4了
insert into t7 values(1, 'jason2'); # 会报错,'jason1'字符长度超4了
insert into t6 values(1, 'tony');
insert into t7 values(1, 'jack');
insert into t6 values(1, 'j');
insert into t7 values(1, 'f');
------------------------------------
验证:t6的char 对应的j后面有3个空格 t7的varchar 对应的f后面没有空格
补充:char_length() 获取字段存储的数据长度
select char_length(name) from t6;
select char_length(name) from t7; # 查看字段存取的数据长度
-------------------------------------
默认情况下MySQL针对char的存储会自动填充空格和删除空格,所以看不出来!!!
mysql的底层针对char(4),假如这个时候存的是一个字符j
当存到硬盘的时候确实是j加3个空格,但是当mysql帮你把数据取出来的时候,
会自动把3个空格给去掉!!所以看到的字符长度还是1
--------------------------------------
set global sql_mode='strict_trans_tables,pad_char_to_full_length';
再退出一下
再进来,再查看字段存取的数据长度,就能看出来了!!!
pad_char_to_full_length
加了这句话后,就取消了底层自动帮你在你数据取出来的时候自动去掉空格的操作!!
char VS varchar 对比
char VS varchar
char
优势:整存整取,速度快
劣势:浪费存储空间
整存整取,char()括号里面写数字几,就按该数字的字符长度整存整取,速度块!!!
----------------------------------
varchar
优势:节省存储空间
劣势:存取数据的速度较char慢 ,因为数据存在硬盘里面是连在一起的,
jacktonyjasonkevintomjerry
因为varchar是变长的,有几位存几位的,所以这个时候就不知道当初是几位几位的存的!!!
所以varchar会将要存的数据前面用1bytes数据作为一个报头,
存数据的时候会计算一下存进去的数据的长度,
然后在该数据前面加一个固定长度的报头,将来在取得时候,先取一个字节长度的报头,
从报头里面解析出后面对应的数据的长度,然后再去拿固定长度的对应数据。如此循环往复!!
这样varchar在存数据的时候会先计算要存的数据的长度的,取数据的时候,
还要用报头解析出真实数据的长度!!!
所以char 肯定比varchar 存取速度块!!!
1bytes+jack1bytes+tony1bytes+jason1bytes+kevin1bytes+tom1bytes+jerry
================================================================
char与varchar的使用需要结合具体应用场景
比如姓名的数据存取,用varchar就比较合适
性别的数据存取,用char就比较合适
有一些字段要经常被查询(比如手机号码),
限制住字段的长度,那么用char比较合适!!!更快!!!
默认情况下MySQL针对char的存储会自动填充空格和删除空格,所以看不出来,
t6的char 对应的j后面有3个空格 t7的varchar 对应的f后面没有空格
。
。
字符类型字段使用参考
其中 char 和 varchar 是最常用到的。
char 类型是定长的,MySQL 总是根据定义的字符串长度分配足够的空间。
当保存 char 值时,在它们的右边填充空格以达到指定的长度,
当检索到 char 值时,尾部的空格被删除掉。
varchar 类型用于存储可变长字符串,存储时,如果字符没有达到定义的位数,也不会在后面补空格。
char(M) 与 varchar(M) 中的的 M 表示保存的最大字符数,
单个字母、数字、中文等都是占用一个字符。
char 适合存储很短的字符串,或者所有值都接近同一个长度。
例如,char 非常适合存储密码的 MD5 值,因为这是一个定长的值。
对于字符串很长或者所要存储的字符串长短不一的情况,varchar 更加合适。
我们在定义字段最大长度时应该按需分配,提前做好预估,
# 能使用 varchar 类型就尽量不使用 text 类型。
除非有存储长文本数据需求时,再考虑使用 text 类型。
-----------------------------------------------
BLOB 类型主要用于存储二进制大对象,例如可以存储图片,音视频等文件。
日常很少用到,有存储二进制字符串时可以考虑使用。
。
。
【SQL类型】
1.数据定义语言(ddl DATA DEFINITION LANGUAG)
用于创建或删除数据库以及数据表的语句,DDL包含以下几种指令:
CREATE: 创建数据库和表等对象
DROP: 删除数据库和表等对象
ALTER: 修改数据库和表等对象的结构
2.数据操纵语言(dml Data Manipulation Language)
用于对数据表中的数据进行增删查改的
SELECT: 查询表中的数据
INSERT: 向表中插入新数据
UPDATE: 变更表中的数据
DELETE: 删除表中的数据
3.数据控制语言(dclData Manipulation Language)
用于对控制数据库的操作权限的,包括用户权限以及数据操作权限。
COMMIT: 确认对数据库中的数据进行的变更
ROLLBACK: 取消对数据库中的数据进行的变更
GRANT: 赋予用户操作权限
REMOVE: 取消用户的操作权限
。
。
【日期类型】
datetime 年月日时分秒
date 年月日
time 时分秒
year 年
-----------------------------
create table t17(
id int,
name varchar(32),
register_time datetime,
birthday date,
study_time time,
work_time year
);
insert into t17 values(1,'jason','2000-11-11 11:11:11','1998-01-21','11:11:11','2000');
补充:以后涉及到日期相关字段,都不需要我们自己去填写数据,一般都是系统自动获取,
无需我们可以操作
【枚举类型与集合类型】
枚举字段类型 enum() 作用:多选一
gender enum('male','female','others')
# 这样定义后,将来该gender字段能够存的数据就只能是括号里面出现的数据了!!!
--------------------------------------
create table t15(
id int,
name varchar(32),
gender enum('male','female','others')
);
insert into t15 values(1,'tony','猛男'); # 报错!!!!!!!!
insert into t15 values(2,'jason','male');
insert into t15 values(3,'kevin','others');
---------------------------------------------------------
集合字段类型 set() 多选多(也包含多选一)
hobbies set('basketabll','football','doublecolorball')
# 这样定义后,将来hobbies字段能够存的数据,可以是括号里面的一个,
# 也可以是括号里面的多个!!!
# 但是不能是括号里面没出现过的数据!!!!否则会报错!!!
-------------------------------------------------------
create table t16(
id int,
name varchar(16),
hobbies set('basketabll','football','doublecolorball')
);
insert into t16 values(1,'jason','study'); # 报错!!!!!!!
insert into t16 values(2,'tony','doublecolorball');
insert into t16 values(3,'kevin','doublecolorball,football');
!
!
!
【约束条件】
(default 默认值)
create table t8( id int, name char(16), gender enum('male','female','others') default 'male' ); 那默认值什么时候生效呢? 插入数据查询表看看 insert into t8(id,name) values(1,'alex'); insert into t8 values(2,'egon','female'); ------------------- 会发现有值就不用你,没插入值则默认
。
。
(unique 唯一)
# 单列唯一: id字段要做到唯一,出现过一次,就不要出现第二次了 create table t9( id int unique, name char(16) ); desc t9;
1 联合唯一: 2 单个都可以重复,但是加载一起的时候必须是唯一的 3 id ip port 4 1 1 1 5 2 1 2 6 3 2 1 7 4 3 1 8 9 create table t10( 10 id int, 11 ip char(16), 12 port int, 13 unique(ip,port) 14 ); 最后声明哪几个加起来必须是唯一的
。
。
【primary key 主键】
主键又分为两种情况:
一:
1 单单从约束效果上来看,primary key等价于not null+unique 2 非空且唯一 3 4 创建表 5 create table t11( id int primary key); 6 7 查看表结构 8 desc t11; 9 10 插入值验证 11 insert into t11 values(null); 验证非空 报错:Column 'id' cannot be null 12 insert into t11 values(1),(1); 验证唯一 报错:Duplicate entry '1' for key 'PRIMARY' 13 insert into t11 values(1),(2); 不报错
二:
它除了有约束效果之外,它还是InnoDB存储引擎组织数据的依据,InnoDB存储引擎在创建表的时候必须要有primary key
因为它类似于书的目录,能够帮助提示查询效率并且也是建表的依据
而作为innodb存储引擎组织数据的依据,又分为3种情况
1 # 1 一张表中有且只有一个主键,如果没有设置主键,那么会从上而下搜索直到遇见一个非空且唯一的字段,然后将它自动升级位主键 2 创表 3 create table t12( 4 id int, 5 name char(16), 6 age int not null unique, 7 addr char(32) not null unique 8 ); 9 查看表结构 10 desc t12; 11 12 ****************************************** 13 # 2 如果表中没有主键也没有其他任何的非空且唯一的字段,那么InnoDB会采用字节内部提供的一个隐藏字段作为主键,隐藏意味着无法使用到它,就无法提示查询速度 14 15 ******************************************* 16 # 3 一个表中通常都应该有一个主键字段,并且通常将id字段作为主键 17 1)单个字段主键; 18 创建表 19 create table t13( 20 id int primary key, 21 name char(16) 22 ); 23 查看表结构 24 desc t13; 25 26 2)联合主键(多个字段联合起来作为表的主键,本质还是一个主键) 27 创建表 28 create table t14( 29 id int, 30 ip char(16), 31 port int, 32 unique(ip,port) 33 );
。
。
【主键自增 primary key auto_increment】
1 该约束条件不能单独出现,并且一张表中只能出现一次!!! 2 通常情况下主要就是配合主键一起用!!! 3 关键字:primary key auto_increment 4 5 ------------------------------ 6 create table t15( 7 id int primary key, 8 name varchar(32) 9 ); 10 11 这种情况下,由于规定了id字段为主键, 12 所以每次插入数据必须要输入对应的编号且不能与以前的编号重复,就比较麻烦了!!!!!! 13 14 ------------------------- 15 create table t16( 16 id int primary key auto_increment, 17 name varchar(32) 18 ); 19 20 insert into t16(name) values('jack'),('jax'),('kin'); 21 insert into t16(name) values('jason'); 22 insert into t16(name) values('george'); 23 24 auto_increment 就是自动增加的意思 25 这个时候就可以肆无忌惮的往表里面插数据,并且可以不用考虑主键的存在了!!! 26 ---------------------------------------------------- 27 28 自增特性注意事项: 29 自增不会因为数据的删除而回退!!! 永远自增往前!!, 30 后续再插入数据的时候id不会因为数据的删除而回退!!! 31 32 ----------------------------------------------------- 33 34 如果自己设置了更大的数!!!则之后按照更大的往前自增!!!! 35 后续再插入数据的时候id会顺着自己设置的更大的数往后增!!!
PS:
delete from 在删除表中数据的时候,主键的自增不会停止
truncate t1 清空表数据并且重置主键
。
。
【外键前戏】
我们需要一张员工表 id name age dep_name dep_desc 1.表语义不明确(主体到底是员工还是部门) 无所谓 2.存取数据过于冗余(浪费存储空间,有些数据重复了) 无所谓 3.数据的扩展性极差(比如你要讲一个部门的名称改了,那么所有的该部门名称都要改,扩展性差!!! 不能忽略 ------------------------------------------------------ 解决办法: 将上述表一分为二 id name age ------- id dep_name dep_desc 上述的三个问题全部解决 但是员工跟部门之间没有了关系 解决办法: 外键字段:用于标识数据与数据之间关系的字段(foregin key) ------------------------------------------------------
【表关系】:
表与表之间最多只有四种关系:
一对多
多对多
一对一
没有关系
-----------------------------------------------------------------------------------------------------------
【一对多关系】
以员工表和部门表为例 1.先站在员工表的角度 问:一名员工能否对应多个部门 答:不可以 2.再站在部门表的角度 问:一个部门能否对应多名员工 答:可以,所以部门是一,员工是多!!! 结论:一个方可以一个方不可以, 那么关系就是'一对多',表关系没有多对一的说法!!! ------ 针对'一对多'关系,外键字段建在'多'的一方!!!!!! 其实也很好理解假如员工有几万人,部门只有10几个,如果把外键字段建在部门表里面,那么每一个部门的外键就要对应很多人 如果把外键字段建在员工表里面,那么每一个员工的外键就只要要对应一个部门就行了!!! ---------------------------------------- 外键字段的建立------数据库层面的约束了!!! foreign key(当前表里面的外键字段) references 被关联表名(被关联表里面的字段名) 小技巧:先定义出含有普通字段的表,之后再考虑外键字段的添加 员工表(关联表): create table emp( id int primary key auto_increment, name char(32), gender enum('male','female','others') default 'male', dep_id int, foreign key(dep_id) references dep(id) ); dep_id int 外键字段名和外键字段对应的数据类型!!! 外键字段建立的关键字: foreign key(当前表里面的外键字段) references 被关联表名(被关联表里面的字段名) 有两个作用:1.让上面的字段变为外键字段!!! 2.与被关联的表里面对应的字段名建立关联!!! ------------------------------------------- 部门表(被关联表): create table dep( id int primary key auto_increment, dep_name char(32), dep_desc char(64) ); -------------------------------------------- 注意: 1.创建表的时候一定要先创建被关联表!!! 直接创员工表(关联表)会报错!!! 2.录入表数据的时候一定要先录入被关联表!!! 因为被关联表与关联表被创建后,假如先往关联表里面插入数据,就会出现外键字段对应的数据没法写的情况!!因为现在被关联表里面没有数据呢!!!mysql的外键关联语法,就规定了外键字段对应的数据只能够填写的是:被关联表里面的字段名里面出现过的值!!!! ------ 3.修改数据的时候需要先解除关系(外键字段无法修改和删除!!!) 不解除关系,直接删被关联表里面的数据会直接报错,不给你删,或者改!! 真想改或者删被关联表里面的数据,要先解除关联关系(看被关联表里面数据对应关联表里面数据的外键编号,先把外键编号改掉,这样就解除了与想要删或者改的被关联数据表对应的数据的关系了!!! 关联的人多的话,操作就很烦!!!) --------------------------------------------------
插入数据:
insert into dep(dep_name,dep_desc) values('讲师部','教书育人'),('财务部','发放工资'),('市场部','拉客户');
insert into emp(name,dep_id) values('jason',1),('tony',2),('jerry',3),('tom',1);
****************************** 如果插入一个没有的关联id,则会报错
级联更新on update cascade 级联删除on delete cascade
1 create table dep( 2 id int primary key auto_increment, 3 dep_name char(32), 4 dep_desc char(64) 5 ); 6 7 字段建在多的一方 8 create table emp ( 9 id INT PRIMARY KEY AUTO_INCREMENT, 10 name CHAR(32), 11 gender ENUM('male','female','others') DEFAULT 'male', 12 dep_id INT, 13 FOREIGN KEY (dep_id) REFERENCES dep(id) 14 ON UPDATE CASCADE # 级联更新 15 ON DELETE CASCADE # 级联删除 16 ); 17 18 插入数据 19 insert into dep(dep_name,dep_desc) values('讲师部','教书育人'),('财务部','发放工资'),('市场部','拉客户'); 20 insert into emp(name,dep_id) values('jason',1),('tony',2),('jerry',3),('tom',1); 21 22 修改 23 update dep set id=4 where id=2; 24 删除 25 delete from dep where id=1;
。
。
。
多对多关系
先写基表---再关系表里面关联对应的基表
以书籍表与作者表为例 1.先站在书籍表的角度 问:一本书能否对应多个作者 答:可以 2.再站在作者表的角度 问:一个作者能否对应多本书 答:可以 结论:两个都可以 关系就是'多对多' 针对'多对多'不能在表中直接创建 需要新建第三张关系表 如果不用第三张表的话,两个表里面都有一个外键关联对方的表里面的数据,这个时候创表的创不出来了,因为我们前面学过,必须先创被关联的表,现在两个表都是被关联的表了!!!所以连表都创不起来!!! 把两个表里面的所有的外键字典都建到第三张表里面去,用第3张表来专门存储两张表数据之间的关系!!! --------------------------------------------------- 书籍表: create table book( id int primary key auto_increment, title varchar(32), price int ); ------ create table author( id int primary key auto_increment, name varchar(32), age int ); ------
第三张关系表
create table book2author( id int primary key auto_increment, author_id int, foreign key(author_id) references author(id) on update cascade # 级联更新 on delete cascade, # 级联删除 book_id int, foreign key(book_id) references book(id) on update cascade # 级联更新 on delete cascade # 级联删除 ); ----------------- 多对多的关系是最好操作的,因为操作两张单表的时候可以随意操作,因为两个表里面的数据有没有关系完全是第3表说了算的,把表里面对应的关系删掉就可以改对应关联的数据了!!
。
。
一对一关系
以用户表与用户详情表为例 1.先站在用户表的角度 问:一个用户能否对应多个用户详情 答:不可以 2.再站在用户详情表的角度 问:一个用户详情能否对应多个用户 答:不可以 结论:两个都可以 关系就是'一对一'或者没有关系!!!!!! --------- 针对'一对一'外键字段建在任何一方都可以 冷数据就是使用频率较低的 热数据就是使用频率较高的!!! 但是推荐建在查询频率较高的表中!!!!!! ----------------------------------------- create table user( id int primary key auto_increment, name varchar(32),
age int, detail_id int unique, foreign key(detail_id) references userdetail(id) on update cascade on delete cascade ); create table userdetail( id int primary key auto_increment, phone int,
addr varchar(64) ); ----------------------------------------- 在关联表的里面外键后面加一个unique 用来限制在关联表里面外键字段detail_id存进去的数据不能重复,一旦重复就又变成一对多了!!!
限制住之后detail_id字段里面的数据,就又要在关联表里面不能重复,又要是被关联表里面id下面出现过的数据,而被关联表里面的id又是主键,非空且唯一,所以两边就只能是1对1的关系了!!!
。
。
【修改表和复制表的语法】
修改表名 alter table 旧表名 rename 新表名; 增加字段 alter table 表名 add 字段名 数据类型 约束条件; alter table 表名 add 字段名 数据类型 约束条件 first|after 字段名; 删除字段 alter table 表名 drop 字段名; 修改字段 alter table 表名 modify(修改) 字段名 数据类型 约束条件; alter table 表名 change 旧字段名 新字段名 字段类型 约束条件; 复制表 create table 表名 select * from 旧表名; 不能复制主键 外键 create table 表名 select * from 旧表名 where 1=2; 可以复制主键 外键