数据表的每行称为一条记录(record);每一列称为一个字段(field)【列之间以英文逗号隔开】。
简单语法:在当前数据库中创建一张表
CREATE TABLE 表名(
列名 列数据类型,
列名 列数据类型
);
mysql8.0 [chap03]>create table t1(id int,name char(30));
在 MySQL 中,有三种主要的类型:文本、数值和日期/时间类型。
文本类型:
数据类型 | 描述 |
---|---|
CHAR(size) | 保存固定长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的长度。最多 255 个字符。 |
VARCHAR(size) | 保存可变长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的最大长度。最多 255 个字符。 注释:如果值的长度大于 255,则被转换为 TEXT 类型。 |
TINYTEXT | 存放最大长度为 255 个字符的字符串。 |
TEXT | 存放最大长度为 65,535 个字符的字符串。 |
BLOB | 用于 BLOBs (Binary Large OBjects),二进制形式的长文本数据。存放最多 65,535 字节的数据。 |
MEDIUMTEXT | 存放最大长度为 16,777,215 个字符的字符串。 |
MEDIUMBLOB | 用于 BLOBs (Binary Large OBjects),二进制形式的中等长度文本数据。存放最多 16,777,215 字节的数据。 |
LONGTEXT | 存放最大长度为 4,294,967,295 个字符的字符串。 |
LONGBLOB | 用于 BLOBs (Binary Large OBjects),二进制形式的极大文本数据。存放最多 4,294,967,295 字节的数据。 |
ENUM(x,y,z,etc.) | 允许你输入可能值的列表。可以在 ENUM 列表中列出最大 65535 个值。如果列表中不存在插入的值,则插入空值。 注释:这些值是按照你输入的顺序存储的。 可以按照此格式输入可能的值: ENUM(‘X’,‘Y’,‘Z’) |
SET | 与 ENUM 类似, SET 最多只能包含 64 个列表项,不过 SET 可存储一个以上的值。 |
数值类型:
类型 | 用途 | 存储需求 | 范围(有符号) | 范围(无符号) |
---|---|---|---|---|
TINYINT | 小整数值 | 1 Bytes | (-128,127) | (0,255) |
SMALLINT | 大整数值 | 2 Bytes | (-32 768,32 767) | (0,65 535) |
MEDIUMINT | 大整数值 | 3 Bytes | (-8 388 608,8 388 607) | (0,16 777 215) |
INT或INTEGER | 大整数值 | 4 Bytes | (-2 147 483 648,2 147 483 647) -(2^31-1)~ (2^31-1) | (0,4 294 967 295) 2^32-1 |
BIGINT | 极大整数值 | 8 Bytes | (-9,223,372,036,854,775,808,9 223 372 036 854 775 807) | (0,18 446 744 073 709 551 615) |
类型 | 用途 | 存储需求 | 范围(有符号) | 范围(无符号) |
---|---|---|---|---|
FLOAT(size,d) | 带有浮动小数点的小数字。在括号中规定最大位数。在 d 参数中规定小数点右侧的最大位数。 | 4Byte | (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) | 0,(1.175 494 351 E-38,3.402 823 466 E+38) |
DOUBLE(size,d) | 带有浮动小数点的大数字。在括号中规定最大位数。在 d 参数中规定小数点右侧的最大位数。 | 8Byte | (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) |
DECIMAL(size,d) | 作为字符串存储的 DOUBLE 类型,允许固定的小数点。 | (size+2)Byte |
注意:这些数值类型拥有额外的选项 UNSIGNED。通常,整数可以是负数或正数。如果添加 UNSIGNED属性,那么范围将从 0 开始,而不是某个负数。
日期/时间类型:
数据类型 | 存储需求 | 描述 |
---|---|---|
DATE | 3Bytes | 日期。格式: YYYY-MM-DD 注释:支持的范围是从 ‘1000-01-01’ 到 ‘9999-12-31’ |
DATETIME | 8Bytes | 日期和时间的组合。格式: YYYY-MM-DD HH:MM:SS 注释:支持的范围是’1000-01-01 00:00:00’ 到 ‘9999-12- 31 23:59:59’ |
TIMESTAMP | 4Bytes | 时间戳。 TIMESTAMP 值使用 Unix 纪元(‘1970-01-01 00:00:00’ UTC) 至今的描述来存储。格式: YYYY-MM-DD HH:MM:SS 注释:支持的范围是从 ‘1970-01-01 00:00:01’ UTC 到 ‘2038-01-19 03:14:07’ UTC将时间转化为UTC进行存储,查询时又转化为当前时区 |
TIME | 3Bytes | 时间。格式: HH:MM:SS 注释:支持的范围是从 ‘-838:59:59’ 到 ‘838:59:59’ |
YEAR | 1Bytes | 2 位或 4 位格式的年。 注释: 4 位格式所允许的值: 1901 到 2155。 2 位格式所允许的值: 70 到69,表示从 1970 到 2069 |
常用数据类型:
#查看某数据库中的所有表
语法:SHOW TABLES[FROM 数据库名][LIKE wild];
mysql8.0 [chap03]>show tables from mysql;
#显示当前数据库中已有的数据表的信息【结构和创建信息】
1、语法:{DESCRIBE|DESC} 表名[列名];
mysql8.0 [chap03]>describe mysql.user;
mysql8.0 [chap03]>desc mysql.user;
2、语法:show columns from 表名称;
mysql8.0 [chap03]>show columns from mysql.user;
#查看数据表中各列的信息
语法:SHOW CREATE TABLE 表名\G
mysql8.0 [chap03]>show create table mysql.user\G
说明:\G表示向mysql服务器发送命令,垂直显示结果
#删除指定的表
语法:DROP TABLE [IF EXISTS] 表名;
mysql8.0 [chap03]>drop table t1;
mysql8.0 [chap03]>create table t1(id int,name char(30));
mysql8.0 [chap03]>desc t1;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | char(30) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
#修改列类型:ALTER TABLE 表名 MODIFY 列名 列类型;
mysql8.0 [chap03]>alter table t1 modify name varchar(30);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql8.0 [chap03]>desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | varchar(30) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
#增加列:ALTER TABLE 表名 ADD 列名 列类型;
mysql8.0 [chap03]>alter table t1 add bir date;
#删除列:ALTER TABLE 表名 DROP 列名;
mysql8.0 [chap03]>alter table t1 drop bir;
#修改列名:ALTER TABLE 表名 CHANGE 旧列名 新列名 列类型;
mysql8.0 [chap03]>alter table t1 change id user_id int;
#更改表名:
方式1:ALTER TABLE 表名 RENAME 新表名;
方式2:RENAME TABLE 表名 TO 新表名;
mysql8.0 [chap03]>alter table t1 rename t2;
mysql8.0 [chap03]>rename table t2 to t3;
mysql8.0 [chap03]>show tables;
+------------------+
| Tables_in_chap03 |
+------------------+
| t3 |
+------------------+
#复制一个表结构的实现方法有两种:
方法1:在create table语句的末尾添加like子句,可以将源表的表结构复制到新表中,语法:create table 新表名 like 源表
mysql8.0 [chap03]>create table t4 like t3;
方法2:在create table语句的末尾添加一个select语句,可以实现表结构的复制,甚至可以将源表的表记录拷贝到新表中。
语法:create table 新表名 select * from 源表
mysql8.0 [chap03]>create table t5 select * from t4;
方法3:如果已经存在一张结构一致的表,复制数据
语法:insert into 表名 select * from 原表;
约束是在表上强制执行的数据校验规则。约束主要用于保证数据库的完整性。当表中数据有相互依赖性时,可以保护相关的数据不被删除。
可以在创建表时规定约束(通过 CREATE TABLE 语句),或者在表创建之后通过 ALTER TABLE 语句规定约束。
根据约束数据列的限制,约束可分为:
根据约束的作用范围,约束可分为:
列级约束:只能作用在一个列上,跟在列的定义后面,语法:列定义 约束类型
表级约束:可以作用在多个列上,不与列一起,而是单独定义
语法:[CONSTRAINT 约束名] 约束类型(列名)
约束名的取名规则,推荐采用:表名_列名_约束类型
例如:alter table 表名 add constraint 约束名 约束类型(要约束的列名)
表级约束类型有四种:主键、外键、唯一、检查
根据约束起的作用,约束可分为:
NOT NULL 非空约束,规定某个字段不能为空
UNIQUE 唯一约束,规定某个字段在整个表中是唯一的
PRIMARY KEY 主键(非空且唯一)约束
FOREIGN KEY 外键约束
CHECK 检查约束
DEFAULT 默认值约束
AUTO_INCREMENT 主键自增加约束
表的约束示例:
1、非空约束(NOT NULL)
列级约束,只能使用列级约束语法定义。确保字段值不允许为空。
mysql8.0 [chap03]>create table t6(
-> id int,
-> name char(30) not null
-> );
注意:所有数据类型的值都可以是NULL,空字符串不等于NULL,0也不等于NULL。
#删除NOT NULL约束,alter table 表名 modify 列名 类型;
mysql8.0 [chap03]>alter table t6 modify name char(30);
mysql8.0 [chap03]>alter table t6 modify name char(30) not null;
2、唯一约束(UNIQUE)
mysql8.0 [chap03]>create table t7(
-> id int unique,
-> name char(30) not null
-> );
create table t8 (id int,name char(20),unique key uniq_name (id,name)); 多列组合设置唯一约束,只有一个索引
mysql8.0 [chap03]>desc t7;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int | YES | UNI | NULL | |
| name | char(30) | NO | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)t
#删除UNIQUE约束,alter table 表名 drop index 唯一约束名;
mysql8.0 [chap03]>alter table t7 drop index id;
#添加unique约束
mysql8.0 [chap03]>alter table t1 add unique key (name);或者
mysql8.0 [chap03]>alter table t7 add constraint uniqueName unique(id);
注:uniqueName自定义相当于索引名。
3、主键约束(PRIMARY KEY)
主键从功能上看相当于非空且唯一,一个表中只允许一个主键,主键是表中唯一确定一行数据的字段,主键字段可以是单字段或者是多字段的组合。
当建立主键约束时,MySQL为主键创建对应的索引。
1.格式
create table 表名(
列名1 数据类型,
列名2 数据类型,
constraint 主键约束的名字 primary key(列名1,列名2)
);
create table 表名(
列名1 数据类型,
列名2 数据类型,
primary key(列名1,列名2)
);
2.针对已经存在表,添加联合主键
格式:alter table 表名 add primary key(列名1,列名2);
格式:alter table 表名 add constraint 主键约束的名字 primary key(列名1,列名2);
3.删除主键约束格式:alter table 表名 drop primary key;
mysql8.0 [chap03]>mysql8.0 [chap03]>create table t8(
-> id int primary key,
-> name char(30) not null
-> );
Query OK, 0 rows affected (0.06 sec)
mysql8.0 [chap03]>desc t8;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| name | char(30) | NO | | NULL | |
+-------+----------+------+-----+---------+-------+
#自动增长:auto_increment :自动增长,为新的行产生唯一的标识,一个表只能有一个auto_increment,且该属性必须为主键的一部分。auto_increment的属性可以是任何整数类型。
mysql8.0 [chap03]>create table t_auto(id int primary key auto_increment);
mysql8.0 [chap03]> alter table t_auto modify id int auto_increment;
#删除PRIMARY KEY约束,alter table 表名 drop primary key;
mysql8.0 [chap03]>alter table t8 drop primary key;
注:primary key == not null unique
却别一张表只能定义一个主键,但一张表和可以多个字段定义多个非空唯一约束
4、外键约束(FOREIGN KEY)
外键是构建于一个表的两个字段或者两个表的两个字段之间的关系,外键确保了相关的两个字段的两个关系。
子(从)表外键列的值必须在主表参照列值的范围内,或者为空(也可以加非空约束,强制不允许为空)。
当主表的记录被子表参照时,主表记录不允许被删除。
外键参照的只能是主表主键或者唯一键,保证子表记录可以准确定位到被参照的记录。
一张表中可以有多个外建
外键的约束条件4:
删除数据时,先删除子表再删除主表
添加数据时先添加主表再添加子表
删除表时先删除子表再删除主表
创建表时先创建主表在创建子表
class表
cnum | cname |
---|---|
1 | 1班 |
2 | 2班 |
student表
snum | s_name | c_num |
---|---|---|
1 | xiao1 | 1 |
2 | xiao2 | 1 |
3 | da1 | 2 |
4 | da2 | 2 |
语法:FOREIGN KEY (外键列名)REFERENCES 主表(参照列)
>create table class (cnum int primary key auto_increment,cname varchar(10));
> insert into class values (1,'1班');
> insert into class(cname) values ('2班');
> create table student(snum int unique not null auto_increment,sname varchar(10) not null,c_num int,foreign key(c_num) references class(cnum));
> insert into student values (1,'xiao1',1);
Query OK, 1 row affected (0.01 sec)
> insert into student values (2,'xiao2',1);
Query OK, 1 row affected (0.01 sec)
> insert into student values (3,'da1',2);
Query OK, 1 row affected (0.01 sec)
> insert into student values (4,'da2',2);
Query OK, 1 row affected (0.01 sec)
> insert into student values (5,'da2',3);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint
fails (`db1`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`c_num`) REFERENCES `class` (`cnum`))
#删除FOREIGN KEY约束,alter table 表名 drop foreign key 约束名;
mysql8.0 [chap03]>show create table tb_employee\G
*************************** 1. row ***************************
Table: tb_employee
Create Table: CREATE TABLE `tb_employee` (
`employee_id` int NOT NULL,
`name` char(30) DEFAULT NULL,
`dept_id` int DEFAULT NULL,
PRIMARY KEY (`employee_id`),
KEY `dept_id` (`dept_id`),
CONSTRAINT `tb_employee_ibfk_1` FOREIGN KEY (`dept_id`) REFERENCES `tb_dept` (`dept_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
mysql8.0 [chap03]>alter table tb_employee drop foreign key tb_employee_ibfk_1;
5、检查约束(CHECK )
# 注意检查约束在8.0之前,MySQL默认但不会强制的遵循check约束(写不报错,但是不生效,需要通过触发器完成),8之后就开始正式支持这个约束了。
mysql8.0 [chap03]>create table t9(
-> id int,
-> age int check(age > 18),
-> gender char(1) check(gender in ('M','F'))
-> );
#删除检查约束
mysql8.0 [chap03]>show create table t9;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t9 | CREATE TABLE `t9` (
`id` int DEFAULT NULL,
`age` int DEFAULT NULL,
`gender` char(1) DEFAULT NULL,
CONSTRAINT `t9_chk_1` CHECK ((`age` > 18)),
CONSTRAINT `t9_chk_2` CHECK ((`gender` in (_utf8mb4'M',_utf8mb4'F')))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
mysql8.0 [chap03]>alter table t9 drop check t9_chk_2;
6、 默认值约束(DEFAULT)
可以使用default关键字设置每一个字段的默认值。
#设置默认值约束
mysql8.0 [chap03]>create table t10(
-> id int unique,
-> name char(30) not null,
-> gender char(1) default 'M',
-> primary key(id)
-> );
#删除默认值约束
mysql8.0 [chap03]>alter table t10 modify gender char;
User表,User主体有很多属性,比如证件(身份证、居住证、港澳通行证…)地区(河北、河南、北京…)等,然后表建好了,数据也填进去了,项目代码也敲几万行。但是有一天,客户说这个“身份证”表述不够官方,要改成“居民身份证”比较好,所以作为这个项目开发人员,你要把代码里和数据库中所有的“身份证”改成“居民身份证”,这工作量估计很让人抓狂。
但是如果采用下边的建表方式,是不是就不会出现这种问题呢,将证件新建一个属性表,将属性值和主体分离,主体表只保存属性的的代码。这就是一种数据字典。
现在,大家应该对数据字典概念有个基本的理解了,数据字典(Data dictionary)是一种用户可以访问的记录数据库和应用程序元数据的目录。主动数据字典是指在对数据库或应用程序结构进行修改时,其内容可以由数据库管理系统自动更新的数据字典。被动数据字典是指修改时必须手工更新其内容的数据字典。
由information_schema数据库负责维护:
tables-存放数据库里所有的数据表、以及每个表所在数据库。
schemata-存放数据库里所有的数据库信息
views-存放数据库里所有的视图信息。
columns-存放数据库里所有的列信息。
triggers-存放数据库里所有的触发器。
routines-存放数据库里所有存储过程和函数。
key_column_usage-存放数据库所有的主外键
table_constraints-存放各个表的约束。
statistics-存放了数据表的索引。
MySQL中的数据用各种不同的技术存储在文件(或者内存)中, 每种技术都使用不同的存储机制、 索引技巧、 锁定水平。这些不同的技术以及配套的相关功能在MySQL中被称作存储引擎(也称作表类型)。
数据库存储引擎是数据库底层软件组件,数据库管理系统使用数据引擎进行创建、查询、更新和删除数据操作。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎还可以获得特定的功能。
现在许多数据库管理系统都支持多种不同的存储引擎。MySQL 的核心就是存储引擎。
InnoDB 事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键。应用于对事务的完整性要求高,在并发条件下要求数据的一致性的情况。 MySQL 5.5.5 之后,InnoDB 作为默认存储引擎。
MyISAM 是基于 ISAM 的存储引擎,并对其进行扩展,是在 Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM 拥有较高的插入、查询速度,但不支持事务。应用于以读写操作为主, 很少更新 、 删除 , 并对事务的完整性、 并发性要求不高的情况。
MEMORY 存储引擎将表中的数据存储到内存中,为查询和引用其他数据提供快速访问。
MEMORY:表的数据存放在内存中,访问效率高 ,但一旦服务关闭,表中的数据全部丢失。
MERGE: 是一组MyISAM表的组合。 可以突破对单个MyISAM表大小的限制, 并提高访问效率。
默认情况下, 创建表不指定表的存储引擎, 则会使用配置文件my.cnf中 default-storage-engine=InnoDB指定的存储引擎。
#在创建表时, 可以指定表的存储引擎:
CREATE TABLE (...) ENGINE=InnoDB;
#完整的创建表的命令语法
CREATE TABLE 表名 (
列名 列类型 [primary key AUTO_INCREMENT] [DEFAULT 默认值][列约束]
...
[表约束]
) [ENGINE=存储引擎类型] [DEFAULT] CHARSET=字符集;
列类型: 该列的数据的存储类型
AUTO_INCREMENT: 自动增长,只能是数值类型的列
DEFAULT 默认值:设置该列的默认值
列约束:对列的一些限制
ENGINE: 表类型, 也叫表的存储引擎
CHARSET: 设置表的字符集
表的物理存储结构:
MyISAM(一种引擎)的表:
mysql8.0 [chap03]>create table test(id int)engine=myisam;
[root@node1 ~]# cd /var/lib/mysql/chap03/
[root@mysql8-0-30 chap03]# ll test*
#表结构元数据
-rw-r-----. 1 mysql mysql 1630 2月 7 01:21 test_414.sdi
# 数据信息文件,存储数据信息
-rw-r-----. 1 mysql mysql 0 2月 7 01:21 test.MYD
# 索引信息文件,index
-rw-r-----. 1 mysql mysql 1024 2月 7 01:21 test.MYI
InnoDB(默认的存储引擎)的表:
[root@node2 employess]# ls -l t4*
#innodb引擎开启了独立表空间产生的存放该表的数据和索引的文件
-rw-r----- 1 mysql mysql 98304 7月 16 20:32 t4.ibd
ttt