[TOC]
05:mysql之表结构管理
今日工作任务路线图
flowchart LR subgraph BottomRow[表结构管理] direction LR A[表管理] --> B[表格字段数据类型] --> C[表头基本约束] end classDef highlight stroke:#f00,stroke-width:2px; class E highlight;一、工作场景
小李在一家小型互联网公司担任数据库管理员。最近公司业务拓展,员工数量大幅增加,原本的数据库表结构逐渐难以满足需求。
在员工表中,原先的“职位”字段过于笼统,无法精准区分不同岗位。部门表也没有记录各部门的成立时间,不利于做部门发展分析。薪资表中奖金计算方式单一,不能适应新的绩效制度。
小李意识到要对表结构进行优化。他先和各部门沟通,了解实际业务需求,再设计新的表结构,在员工表细化“职位”,部门表添加“成立时间”,薪资表调整奖金规则。最后在测试环境验证新结构,确保准确稳定后应用到正式环境。
二、为啥要学表结构管理
学习 MySQL 表结构管理非常有必要。想象下你在一家公司工作,公司有员工表、部门表和薪资表。如果表结构管理不好,问题就会接踵而至。
要是员工表没有合理设置字段,可能会导致员工信息记录不全,影响人事管理。部门表结构混乱,就很难清晰掌握各部门的情况。薪资表如果设计不佳,计算薪资时容易出错,引发员工不满。
学会表结构管理,能让这些表合理存储数据,查询和修改数据更高效,避免数据冗余和错误。可以准确统计各部门员工数量、快速算出员工薪资,让公司运营更顺畅,所以学好它对处理数据很有帮助。
三、表管理
当前任务环节
flowchart LR subgraph BottomRow[表结构管理] direction LR A[表管理] --> B[表格字段数据类型] --> C[表头基本约束] end classDef highlight stroke:#f00,stroke-width:2px; class A highlight;3.1 建库练习
库名命名规则:
仅可以使用数字、字母、下划线、不能纯数字
区分字母大小写,
具有唯一性
不可使用MySQL命令或特殊字符
命令操作如下所示:
//库名区分字母大小写mysql> create【克瑞特】 database【得塔-贝斯】 gamedb ;-- mysql> create database gamedb;Query OK, 1 row affected (0.14 sec)
mysql> create【克瑞特】 database【得塔-贝斯】 GAMEDB ;-- mysql> create database GAMEDB;Query OK, 1 row affected (0.08 sec)
mysql> create【克瑞特】 database【得塔-贝斯】 GAMEDB ;-- mysql> create database GAMEDB;ERROR 1007 (HY000): Can't create【克瑞特】 database【得塔-贝斯】 'GAMEDB'; database【得塔-贝斯】 exists【伊贼谁斯】' //重名报错
//加if not【nuō 特】 exists【伊贼谁斯】 命令避免重名报错mysql> create【克瑞特】 database【得塔-贝斯】 if not【nuō 特】 exists【伊贼谁斯】 gamedb ;-- mysql> create database if not exists gamedb;Query OK, 1 row affected, 1 warning (0.03 sec) //正常
mysql> show【瘦】 databases【得塔-贝斯】; //查看创建的库-- mysql> show databases;+--------------------+| Database |+--------------------+| GAMEDB || gamedb || information_schema || mysql || performance_schema || sys || moershi |+--------------------+7 rows in set (0.00 sec)
mysql> drop【卓-普】 database【得塔-贝斯】 gamedb; //删除库-- mysql> drop database gamedb;Query OK, 0 rows affected (0.11 sec)
mysql> drop【卓-普】 database【得塔-贝斯】 gamedb; // 删除没有的库报错-- mysql> drop database gamedb;ERROR 1008 (HY000): Can’t drop【卓-普】 database【得塔-贝斯】 ‘gamedb’; database【得塔-贝斯】 doesn’t exist
//加if exists【伊贼谁斯】 删除没有的库,也不报错mysql> drop【卓-普】 database【得塔-贝斯】 if exists【伊贼谁斯】 gamedb;-- mysql> drop database if exists gamedb;Query OK, 0 rows affected, 1 warning (0.00 sec)3.2 建表练习
命令操作如下所示:
mysql> create【克瑞特】 database【得塔-贝斯】 studb【斯丢db】; //建库-- mysql> create database studb;Query OK, 1 row affected (0.11 sec)
mysql> create【克瑞特】 table【忒-部】 studb【斯丢db】.stu( //建表 -> name char【查尔】(10), -> class【克拉斯】 char【查尔】(9), -> gender【间德尔】 char【查尔】(4), -> age int【因特】 -> );-- mysql> create table studb.stu(-- -> name char(10),-- -> class char(9),-- -> gender char(4),-- -> age int);Query OK, 0 rows affected (1.17 sec)
mysql> desc studb【斯丢db】.stu; //查看表头-- mysql> desc studb.stu;+--------+----------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+----------+------+-----+---------+-------+| name | char(10) | YES | | NULL | || class | char(9) | YES | | NULL | || gender | char(4) | YES | | NULL | || age | int | YES | | NULL | |+--------+----------+------+-----+---------+-------+4 rows in set (0.00 sec)3.3 修改表练习
命令操作如下所示:
修改表名
mysql> show【瘦】 tables【忒-部s】; //查看表-- mysql> show tables;+-----------------+| Tables_in_studb |+-----------------+| stu |+-----------------+1 row in set (0.00 sec)
mysql> alter【奥-特】 table【忒-部】 studb【斯丢db】.stu rename【瑞-内姆】 studb【斯丢db】.stuinfo【斯丢因否】; //修改表名 rename【瑞-内姆】-- mysql> alter table studb.stu rename studb.stuinfo;Query OK, 0 rows affected (0.28 sec)
mysql> use studb【斯丢db】; //进入库-- mysql> use studb;Reading table【忒-部】 information for completion of table【忒-部】 and column namesYou can turn off this feature to get a quicker startup with -ADatabase changed
mysql> show【瘦】 tables【忒-部s】; //查看表-- mysql> show tables;+-----------------+| Tables_in_studb |+-----------------+| stuinfo |+-----------------+1 row in set (0.00 sec)删除表头
mysql> desc studb【斯丢db】.stu; //查看表头-- mysql> desc studb.stu;+--------+----------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+----------+------+-----+---------+-------+| name | char(10) | YES | | NULL | || class | char(9) | YES | | NULL | || gender | char(4) | YES | | NULL | || age | int | YES | | NULL | |+--------+----------+------+-----+---------+-------+4 rows in set (0.00 sec)
mysql> alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 drop【卓-普】 age ; //删除age表头 drop【卓-普】-- mysql> alter table studb.stuinfo drop age;Query OK, 0 rows affected (0.52 sec)Records: 0 Duplicates: 0 Warnings: 0
mysql> desc stuinfo【斯丢因否】; //查看表头-- mysql> desc stuinfo;+--------+----------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+----------+------+-----+---------+-------+| name | char(10) | YES | | NULL | || class | char(9) | YES | | NULL | || gender | char(4) | YES | | NULL | |+--------+----------+------+-----+---------+-------+3 rows in set (0.00 sec)添加表头
//添加表头,默认添加在末尾addmysql> alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 add mail【miào e】 char【查尔】(30) ;-- mysql> alter table studb.stuinfo add mail char(30);Query OK, 0 rows affected (0.24 sec)Records: 0 Duplicates: 0 Warnings: 0
//查看表头mysql> desc studb【斯丢db】.stuinfo【斯丢因否】;-- mysql> desc studb.stuinfo;+--------+----------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+----------+------+-----+---------+-------+| name | char(10) | YES | | NULL | || class | char(9) | YES | | NULL | || gender | char(4) | YES | | NULL | || mail | char(30) | YES | | NULL | |+--------+----------+------+-----+---------+-------+4 rows in set (0.00 sec)
//first【佛斯特】 把表头添加首位//after【啊夫特】 添加在指定表头名的下方mysql> alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 add number【能波】 char【查尔】(9) first【佛斯特】 , add school【斯故】 char【查尔】(10) after【啊夫特】 name;-- mysql> alter table studb.stuinfo add number char(9) first,add school char(10) after name;Query OK, 0 rows affected (0.48 sec)Records: 0 Duplicates: 0 Warnings: 0
//查看表结构mysql> desc studb【斯丢db】.stuinfo【斯丢因否】; //查看表头-- mysql> desc studb.stuinfo;+--------+----------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+----------+------+-----+---------+-------+| number | char(9) | YES | | NULL | || name | char(10) | YES | | NULL | || school | char(10) | YES | | NULL | || class | char(9) | YES | | NULL | || gender | char(4) | YES | | NULL | || mail | char(30) | YES | | NULL | |+--------+----------+------+-----+---------+-------+6 rows in set (0.00 sec)修改表头数据类型
//修改表头数据类型modify【莫迪fái】mysql> alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 modify【莫迪fái】 mail【miào e】 varchar【瓦儿-查儿】(50);-- mysql> alter table studb.stuinfo modify mail varchar(50);Query OK, 0 rows affected (1.17 sec)Records: 0 Duplicates: 0 Warnings: 0
mysql> desc studb【斯丢db】.stuinfo【斯丢因否】;-- mysql> desc studb.stuinfo;+--------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+-------------+------+-----+---------+-------+| number | char(9) | YES | | NULL | || name | char(10) | YES | | NULL | || school | char(10) | YES | | NULL | || class | char(9) | YES | | NULL | || gender | char(4) | YES | | NULL | || mail | varchar(50) | YES | | NULL | |+--------+-------------+------+-----+---------+-------+6 rows in set (0.01 sec)修改表头名
//修改表头名class【克拉斯】mysql> alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 change【趁(chèn)吉】 class【克拉斯】 班级 char【查尔】(9) ;-- mysql> alter table studb.stuinfo change class 班级 char(9);Query OK, 0 rows affected (0.12 sec)Records: 0 Duplicates: 0 Warnings: 0
//查看表头mysql> desc studb【斯丢db】.stuinfo【斯丢因否】;-- mysql> desc studb.stuinfo;+--------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+-------------+------+-----+---------+-------+| number | char(9) | YES | | NULL | || name | char(10) | YES | | NULL | || school | char(10) | YES | | NULL | || 班级 | char(9) | YES | | NULL | || gender | char(4) | YES | | NULL | || mail | varchar(50) | YES | | NULL | |+--------+-------------+------+-----+---------+-------+6 rows in set (0.00 sec)删除多个表头
//一起删除多个表头mysql> alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 drop【卓-普】 school【斯故】 , drop【卓-普】 班级 ,drop【卓-普】 mail【miào e】 ;-- mysql> alter table studb.stuinfo drop school,drop 班级,drop mail;Query OK, 0 rows affected (0.73 sec)Records: 0 Duplicates: 0 Warnings: 0
//查看表头mysql> desc studb【斯丢db】.stuinfo【斯丢因否】;-- mysql> desc studb.stuinfo;+--------+----------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+----------+------+-----+---------+-------+| number | char(9) | YES | | NULL | || name | char(10) | YES | | NULL | || gender | char(4) | YES | | NULL | |+--------+----------+------+-----+---------+-------+3 rows in set (0.00 sec)修改表头的位置
mysql>//使用modify【莫迪fái】 修改表头的位置mysql> alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 modify【莫迪fái】 gender【间德尔】 char【查尔】(4) after【啊夫特】 number【能波】;-- mysql> alter table studb.stuinfo modify gender char(4) after number;Query OK, 0 rows affected (0.77 sec)Records: 0 Duplicates: 0 Warnings: 0
//查看表头mysql> desc studb【斯丢db】.stuinfo【斯丢因否】;-- mysql> desc studb.stuinfo;+--------+----------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+----------+------+-----+---------+-------+| number | char(9) | YES | | NULL | || gender | char(4) | YES | | NULL | || name | char(10) | YES | | NULL | |+--------+----------+------+-----+---------+-------+3 rows in set (0.00 sec)
//再修改回原来位置mysql> alter【奥-特】 table【忒-部】 studb【斯丢db】.stuinfo【斯丢因否】 modify【莫迪fái】 gender【间德尔】 char【查尔】(4) after【啊夫特】 name;-- mysql> alter table studb.stuinfo modify gender char(4) after name;Query OK, 0 rows affected (0.50 sec)Records: 0 Duplicates: 0 Warnings: 0
//查看表头mysql> desc studb【斯丢db】.stuinfo【斯丢因否】;-- mysql> desc studb.stuinfo;+--------+----------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+----------+------+-----+---------+-------+| number | char(9) | YES | | NULL | || name | char(10) | YES | | NULL | || gender | char(4) | YES | | NULL | |+--------+----------+------+-----+---------+-------+3 rows in set (0.01 sec)3.4 复制表
拷贝已有的表 和系统命令 cp 的功能一样
复制表
-- create table 表名 select * from 表名//复制moershi库salary【晒了瑞】表到 studb【斯丢db】库 表名不变mysql> create【克瑞特】 table【忒-部】 studb【斯丢db】.salary【晒了瑞】 select【涩莱克特】 * from【弗乱】 moershi.salary【晒了瑞】;-- mysql> create table studb.salary select * from moershi.salary;Query OK, 8055 rows affected (2.66 sec)Records: 8055 Duplicates: 0 Warnings: 0
//查看表头,源表的key【kì】 不会被复制mysql> desc studb【斯丢db】.salary【晒了瑞】;-- mysql> desc studb.salary;+-------------+------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------------+------+------+-----+---------+-------+| id | int | NO | | 0 | || date | date | YES | | NULL | || employee_id | int | YES | | NULL | || basic | int | YES | | NULL | || bonus | int | YES | | NULL | |+-------------+------+------+-----+---------+-------+5 rows in set (0.00 sec)
//查看表行数mysql> select【涩莱克特】 count【kàn特】(*) from【弗乱】 studb【斯丢db】.salary【晒了瑞】;-- mysql> select count(*) from studb.salary;+----------+| count(*) |+----------+| 8055 |+----------+1 row in set (0.00 sec)复制表头
//仅仅复制表头like【赖特mysql> create【克瑞特】 table【忒-部】 studb【斯丢db】.salary2【晒了瑞2】 like【赖特】 moershi.salary【晒了瑞】;-- mysql> create table studb.salary2 like moershi.salary;Query OK, 0 rows affected (0.95 sec)
//查看表头mysql> desc studb【斯丢db】.salary2【晒了瑞2】;-- mysql> desc studb.salary2;+-------------+------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+-------------+------+------+-----+---------+----------------+| id | int | NO | PRI | NULL | auto_increment || date | date | YES | | NULL | || employee_id | int | YES | MUL | NULL | || basic | int | YES | | NULL | || bonus | int | YES | | NULL | |+-------------+------+------+-----+---------+----------------+5 rows in set (0.00 sec)
//查看表行数mysql> select【涩莱克特】 count【kàn特】(*) from【弗乱】 studb【斯丢db】.salary2【晒了瑞2】;-- mysql> select count(*) from studb.salary2;+----------+| count(*) |+----------+| 0 |+----------+1 row in set (0.00 sec)mysql>四、表的字段数据类型
数值类型:INT存储整数,DECIMAL存储精确小数 字符类型:CHAR适合固定长度,VARCHAR适合可变长度 日期时间:DATE存储日期,TIME存储时间 枚举类型:ENUM存储预定义值列表
当前任务环节
flowchart LR subgraph BottomRow[表结构管理] direction LR A[表管理] --> B[表格字段数据类型] --> C[表头基本约束] end classDef highlight stroke:#f00,stroke-width:2px; class B highlight;常用数据类型:数值类型、字符类型、日期时间类型、枚举类型,每种类型都有对应的命令表示、有具体的存储范围。
- 比如存储: 身高、体重、工资、奖金,适合使用数值类型。
- 比如存储: 姓名、家庭地址、收货地址,适合使用字符类型。char
- 比如存储: 生日、出生年份、入职时间、下班时间、注册时间,适合使用日期时间。date(日期) time(时间) datetime(时间日期) yeaer(年份)
- 比如存储: 爱好、性别、社保医院,适合使用枚举类型。
4.1 练习字符类型的使用
命令操作如下所示:
//建表mysql> create【克瑞特】 table【忒-部】 studb【斯丢db】.t2(name char【查尔】(3) , address【额拽斯】 varchar【瓦儿-查儿】(5) );-- mysql> create table studb.t2(name char(3),adderss varchar(5));Query OK, 0 rows affected (0.30 sec)
//查看表头mysql> desc studb【斯丢db】.t2;-- mysql> desc studb.t2;+---------+------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+---------+------------+------+-----+---------+-------+| name | char(3) | YES | | NULL | || address | varchar(5) | YES | | NULL | |+---------+------------+------+-----+---------+-------+2 rows in set (0.00 sec)
//插入记录mysql> insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 ("a","a"); //正常-- mysql> insert into studb.t2 values("a","a");Query OK, 1 row affected (0.05 sec)
mysql> insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 ("ab","ab"); //正常-- mysql> insert into studb.t2 values ("ab","ab");Query OK, 1 row affected (0.08 sec)
mysql> insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 ("abc","abc");//正常-- mysql> insert into studb.t2 values ("abc","abc");Query OK, 1 row affected (0.04 sec)
mysql> insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 ("abcd","abcd"); //超出字符个数报错-- mysql> insert into studb.t2 values ("abcd","abcd");ERROR 1406 (22001): Data too long for column 'name' at row 1mysql8 建表默认支持中文字符集
//查看字符集mysql> show【瘦】 create【克瑞特】 table【忒-部】 studb【斯丢db】.t2 \G-- mysql> show create table studb.t2 \G*************************** 1. row *************************** Table: t2Create Table: CREATE TABLE `t2` ( `name` char【查尔】(3) DEFAULT NULL【nào】, `address【额拽斯】` varchar【瓦儿-查儿】(5) DEFAULT NULL【nào】) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci1 row in set (0.00 sec)
说明 :ENGINE=InnoDB 定义存储引擎(存储引擎课程里讲)DEFAULT CHARSET=定义表使用的字符集
//插入记录mysql> insert【因涩特】 into【因兔】 studb【斯丢db】.t2 values【挖柳斯】 ("张翠山","武当山");-- mysql> insert into studb.t2 values("张翠山","武当山");Query OK, 1 row affected (0.07 sec)
//查看表记录mysql> SELECT【涩莱克特】 * FROM【弗乱】 studb【斯丢db】.t2;-- mysql> select * from studb.t2;+-----------+-----------+| name | address |+-----------+-----------+| a | a || ab | ab || abc | abc || 张翠山 | 武当山 |+-----------+-----------+4 rows in set (0.00 sec)4.2 练习数值类型的使用
命令操作如下所示:
//建表mysql> create【克瑞特】 table【忒-部】 studb【斯丢db】.t1(name char【查尔】(10) , level【列沃】 tinyint【泰尼因特】 unsigned【安赛因德】 , money【孟妮】 double【答步】 );-- mysql> create table studb.t1(name char(10),level tinyint unsigned , money double );Query OK, 0 rows affected (0.72 sec)
//查看表头mysql> desc studb【斯丢db】.t1;-- mysql> desc studb.t1;+-------+------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------+------------------+------+-----+---------+-------+| name | char(10) | YES | | NULL | || level | tinyint unsigned | YES | | NULL | || money | double | YES | | NULL | |+-------+------------------+------+-----+---------+-------+3 rows in set (0.00 sec)
//插入数据mysql> insert【因涩特】 into【因兔】 studb【斯丢db】.t1 values【挖柳斯】("法师",80,88);-- mysql> insert into studb.t1 values("法师",80,88);Query OK, 1 row affected (0.04 sec)
//超出范围报错 tinyint unsigned 最大255 可以是小数,四舍五入取整mysql> insert【因涩特】 into【因兔】 studb【斯丢db】.t1 values【挖柳斯】("战士",301,1.292);-- mysql> insert into studb.t1 values("战士",301,1.292);ERROR 1264 (22003): Out of range value for column 'level【列沃】' at row 1 -- 失败是因为值301超出了TINYINT UNSIGNED的数据范围(0-255)
mysql> insert【因涩特】 into【因兔】 studb【斯丢db】.t1 values【挖柳斯】("猎人",255,1.292);-- mysql> insert into studb.t1 values("猎人",255,1.292);Query OK, 1 row affected (0.06 sec)
//整数类型 不存储小数位mysql> insert【因涩特】 into【因兔】 studb【斯丢db】.t1 values【挖柳斯】 ("英雄",1.292,6.78);-- mysql> insert into studb.t1 values("英雄",1.292,6.78);Query OK, 1 row affected (0.07 sec)
//查看表记录mysql> select【涩莱克特】 * from【弗乱】 studb【斯丢db】.t1 ;-- mysql> select * from studb.t1;+--------+-------+-------+| name | level | money |+--------+-------+-------+| 法师 | 80 | 88 || 猎人 | 255 | 1.292 || 英雄 | 1 | 6.78 |+--------+-------+-------+3 rows in set (0.00 sec)4.3 枚举类型
//建表mysql> create【克瑞特】 table【忒-部】 studb【斯丢db】.t8( -> 姓名 char【查尔】(10), -> 性别 enum【伊牛姆】("男","女","保密"), -> 爱好 set【赛特】("帅哥","金钱","吃","睡") -> );-- mysql> create table studb.t8(-- -> 姓名 char(10),-- -> 性别 enum("男","女","保密"),-- -> 爱好 set("帅哥","金钱","吃","睡"));Query OK, 0 rows affected (0.29 sec)
//查看表头mysql> desc studb【斯丢db】.t8 ;-- mysql> desc studb.t8;+--------+------------------------------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+------------------------------------+------+-----+---------+-------+| 姓名 | char(10) | YES | | NULL | || 性别 | enum('男','女','保密') | YES | | NULL | || 爱好 | set('帅哥','金钱','吃','睡') | YES | | NULL | |+--------+------------------------------------+------+-----+---------+-------+3 rows in set (0.01 sec)
//插入记录超出范围报错mysql> insert【因涩特】 into【因兔】 studb【斯丢db】.t8 values【挖柳斯】 ("小包总","男人","帅哥,睡,金钱");-- mysql> insert into studb.t8 values ("小包总","男人","帅哥,睡,金钱");ERROR 1265 (01000): Data truncated for column '性别' at row 1 -- 值"男人"不在ENUM类型的预定义值列表中(只有'男','女','保密')
mysql> insert【因涩特】 into【因兔】 studb【斯丢db】.t8 values【挖柳斯】 ("小包总","男","美女,睡,金钱");-- mysql> insert into studb.t8 values ("小包总","男","美女,睡,金钱");ERROR 1265 (01000): Data truncated for column '爱好' at row 1 --"爱好"字段只包含'帅哥','金钱','吃','睡'四个值,不包含"美女"这个值
//在范围内插入成功mysql> insert【因涩特】 into【因兔】 studb【斯丢db】.t8 values【挖柳斯】 ("丫丫","女","帅哥,吃");-- mysql> insert into studb.t8 values("丫丫","女","帅哥,吃");Query OK, 1 row affected (0.09 sec)
mysql> select【涩莱克特】 * from【弗乱】 studb【斯丢db】.t8;-- mysql> select * from studb.t8;+--------+--------+------------+| 姓名 | 性别 | 爱好 |+--------+--------+------------+| 丫丫 | 女 | 帅哥,吃 |+--------+--------+------------+1 row in set (0.00 sec)4.4 练习日期时间类型的使用
命令操作如下所示:
//建表mysql> create【克瑞特】 table【忒-部】 studb【斯丢db】.t6( -> 姓名 char【查尔】(10), -> 生日 date , -> 出生年份 year【耶尔】, -> 家庭聚会 datetime , -> 聚会地点 varchar【瓦儿-查儿】(15), -> 上班时间 time -> );-- mysql> create table studb.t6(-- -> 姓名 char(10),-- -> 生日 date,-- -> 出生年份 year,-- -> 家庭聚会 datetime,-- -> 聚会地点 varchar(15),-- -> 上班时间 time);Query OK, 0 rows affected (0.25 sec)
//查看表头mysql> desc studb【斯丢db】.t6 ;-- mysql> desc studb.t6;+--------------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------------+-------------+------+-----+---------+-------+| 姓名 | char(10) | YES | | NULL | || 生日 | date | YES | | NULL | || 出生年份 | year | YES | | NULL | || 家庭聚会 | datetime | YES | | NULL | || 聚会地点 | varchar(15) | YES | | NULL | || 上班时间 | time | YES | | NULL | |+--------------+-------------+------+-----+---------+-------+6 rows in set (0.00 sec)
//插入表头mysql> insert【因涩特】 into【因兔】 studb【斯丢db】.t6 -> values【挖柳斯】 ("翠花",20211120,1990,20220101183000,"天坛校区",090000);-- mysql> insert into studb.t6-- -> values ("翠花",20211120,1990,20220101183000,"天坛校区",090000);Query OK, 1 row affected (0.05 sec)
//查看表记录mysql> select【涩莱克特】 * from【弗乱】 studb【斯丢db】.t6;-- mysql> select * from studb.t6;+--------+------------+--------------+---------------------+--------------+--------------+| 姓名 | 生日 | 出生年份 | 家庭聚会 | 聚会地点 | 上班时间 |+--------+------------+--------------+---------------------+--------------+--------------+| 翠花 | 2021-11-20 | 1990 | 2022-01-01 18:30:00 | 天坛校区 | 09:00:00 |+--------+------------+--------------+---------------------+--------------+--------------+1 row in set (0.00 sec)五、表头基本约束
当前任务环节
flowchart LR subgraph BottomRow[表结构管理] direction LR A[表管理] --> B[表格字段数据类型] --> C[表头基本约束] end classDef highlight stroke:#f00,stroke-width:2px; class C highlight;约束是一种限制,设置在表头上,用来控制表头的赋值,包括以下几种:
- NOT【nuō 特】 NULL【nò】 :非空,用于保证该字段的值不能为空。
- DEFAULT【迪-佛特】:默认值,用于保证该字段有默认值。
- UNIQUE【U尼克】:唯一索引,用于保证该字段的值具有唯一性,可以为空。
- primary【普赖莫瑞】 KEY【kì】:主键,用于保证该字段的值具有唯一性并且非空。
- FOREIGN【佛润】 KEY【kì】:外键,用于限制两个表的关系,用于保证该字段的值必须来自于主表的关联列的值,在从表添加外键约束,用于引用主表中某些的值。
5.1 表头不允许赋空值
//建表时给表头设置默认和不允许赋null【nào】值mysql> create【克瑞特】 database【得塔-贝斯】 if not【nuō 特】 exists【伊贼谁斯】 db1;-- mysql> create database if not exists db1;Query OK, 1 row affected (0.07 sec)
//建表mysql> create【克瑞特】 table【忒-部】 db1.t31( -> name char【查尔】(10) not【nuō 特】 null【nào】 , -> class【克拉斯】 char【查尔】(7) default【迪-佛特】 "nsd", -> likes【赖特s】 set【赛特】("money【孟妮】","game","film","music") not【nuō 特】 null【nào】 default【迪-佛特】 "film,music" );-- mysql> create table db1.t31(-- -> name char(10) not null,-- -> class char(7) default "nsd",-- -> likes set("money","game","film","music") not null default "film,music" );Query OK, 0 rows affected (0.43 sec)
//查看表头mysql> desc db1.t31;-- mysql> desc db1.t31;+-------+------------------------------------+------+-----+------------+-------+| Field | Type | Null | Key | Default | Extra |+-------+------------------------------------+------+-----+------------+-------+| name | char(10) | NO | | NULL | || class | char(7) | YES | | nsd | || likes | set('money','game','film','music') | NO | | film,music | |+-------+------------------------------------+------+-----+------------+-------+3 rows in set (0.01 sec)
//验证默认值和不允许为nullmysql> insert【因涩特】 into【因兔】 db1.t31 values【挖柳斯】 (null, null , null);-- mysql> insert into db1.t31 values(null, null , null);ERROR 1048 (23000): Column 'name' cannot be null //表头name赋null值 报错
//表头likes【赖特s】赋null值 报错mysql> insert【因涩特】 into【因兔】 db1.t31 values【挖柳斯】 ("bob", null , null);-- mysql> insert into db1.t31 values("bob", null , null);ERROR 1048 (23000): Column 'likes' cannot be null
//符合约束不报错mysql> insert【因涩特】 into【因兔】 db1.t31 values【挖柳斯】 ("bob",null,"money【孟妮】,game,film");-- mysql> insert into db1.t31 values("bob",null,"money,game,film");Query OK, 1 row affected (0.06 sec)
//不赋值的表头使用默认值赋值mysql> insert【因涩特】 into【因兔】 db1.t31(name) values【挖柳斯】("jim");-- mysql> insert into db1.t31(name) values("jim");-- Query OK, 1 row affected (0.01 sec)
//根据需要自定义表头的值mysql> insert【因涩特】 into【因兔】 db1.t31 values【挖柳斯】 ("lucy","nsd2108","game,film");-- mysql> insert into db1.t31 values("lucy","nsd2108","game,film");-- Query OK, 1 row affected (0.14 sec)
//查看表记录mysql> select【涩莱克特】 * from【弗乱】 db1.t31;-- mysql> select * from db1.t31;+------+---------+-----------------+| name | class | likes |+------+---------+-----------------+| bob | NULL | money,game,film || jim | nsd | film,music || lucy | nsd2108 | game,film |+------+---------+-----------------+3 rows in set (0.00 sec)5.2 表头加唯一索引练习
唯一索引 (unique【U尼克】)
约束的方式:表头值唯一 , 但可以赋null 值
//建表create【克瑞特】 table【忒-部】 db1.t32 (姓名 char【查尔】(10) , 护照 char【查尔】(18) unique【U尼克】 );-- mysql> create table db1.t32 (姓名 char(10) , 护照 char(18) unique);
//查看表头 唯一索引标志UNImysql> desc db1.t32 ;-- mysql> desc db1.t32;+--------+----------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+----------+------+-----+---------+-------+| 姓名 | char(10) | YES | | NULL | || 护照 | char(18) | YES | UNI | NULL | |+--------+----------+------+-----+---------+-------+2 rows in set (0.00 sec)
//赋null值 可以mysql> insert【因涩特】 into【因兔】 db1.t32 values【挖柳斯】("bob",null);-- mysql> insert into db1.t32 values("bob",null);Query OK, 1 row affected (0.07 sec)
//表头值重复不可以mysql> insert【因涩特】 into【因兔】 db1.t32 values【挖柳斯】("tom","666888");-- mysql> insert into db1.t32 values("tom","666888");Query OK, 1 row affected (0.08 sec)
mysql> insert【因涩特】 into【因兔】 db1.t32 values【挖柳斯】("jim","666888");-- mysql> insert into db1.t32 values("jim","666888");ERROR 1062 (23000): Duplicate entry '666888' for key【kì】 't32.护照'
//不重复 可以mysql> insert【因涩特】 into【因兔】 db1.t32 values【挖柳斯】("jim","766888");-- mysql> insert into db1.t32 values("jim","766888");Query OK, 1 row affected (0.05 sec)
//查看表记录mysql> select【涩莱克特】 * from【弗乱】 DB1.t32;-- mysql> select * from db1.t32;+------+--------+| 姓名 | 护照 |+------+--------+| bob | NULL || tom | 666888 || jim | 766888 |+------+--------+3 rows in set (0.00 sec)2 bob nsd2107 bj
3 bob nsd2107 bj
4 bob nsd2107 bj
1)建表
mysql> create【克瑞特】 table【忒-部】 db1.t38 ( -> 行号 int【因特】 primary【普赖莫瑞】 key【kì】 auto_increment【奥特欧_因克瑞门特】 , -> 姓名 char【查尔】(10) , -> 班级 char【查尔】(7) , -> 住址 char【查尔】(10) -> );-- mysql> create table db1.t38(-- -> 行号 int primary key auto_increment,-- -> 姓名 char(10),-- -> 班级 char(7),-- -> 住址 char(10));Query OK, 0 rows affected (0.76 sec)
//查看表头mysql> desc db1.t38 ;-- mysql> desc db1.t38;+--------+----------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+--------+----------+------+-----+---------+----------------+| 行号 | int | NO | PRI | NULL | auto_increment || 姓名 | char(10) | YES | | NULL | || 班级 | char(7) | YES | | NULL | || 住址 | char(10) | YES | | NULL | |+--------+----------+------+-----+---------+----------------+4 rows in set (0.00 sec)
//插入表记录 不给自增长表头赋值mysql> insert【因涩特】 into【因兔】 db1.t38(姓名,班级,住址) values【挖柳斯】("bob","nsd2107","bj");-- mysql> insert into db1.t38(姓名,班级,住址) values("bob","nsd2107","bj");Query OK, 1 row affected (0.05 sec)
mysql> insert【因涩特】 into【因兔】 db1.t38(姓名,班级,住址) values【挖柳斯】("bob","nsd2107","bj");-- mysql> insert into db1.t38(姓名,班级,住址) values("bob","nsd2107","bj");Query OK, 1 row affected (0.04 sec)
mysql> insert【因涩特】 into【因兔】 db1.t38(姓名,班级,住址) values【挖柳斯】("tom","nsd2107","bj");-- mysql> insert into db1.t38(姓名,班级,住址) values("tom","nsd2107","bj");Query OK, 1 row affected (0.05 sec)
//查看表记录mysql> select【涩莱克特】 * from【弗乱】 db1.t38;-- mysql> select * from db1.t38;+--------+--------+---------+--------+| 行号 | 姓名 | 班级 | 住址 |+--------+--------+---------+--------+| 1 | bob | nsd2107 | bj || 2 | bob | nsd2107 | bj || 3 | tom | nsd2107 | bj |+--------+--------+---------+--------+3 rows in set (0.00 sec)六、作业
1 选择题
- 在 MySQL 中创建表时,用于定义字段为字符类型且长度为 20 的是以下哪种写法?A A. CHAR(20) B. TEXT(20) C. INT(20) D. FLOAT(20)
讲解:CHAR是固定长度的字符类型,TEXT是可变长度文本类型不能指定长度,INT是整数类型,FLOAT是浮点数类型。- 若要修改表名为
students的表,将其中age字段的数据类型从INT改为SMALLINT,应使用以下哪条语句? B A. UPDATE TABLE students CHANGE age age SMALLINT; B. ALTER TABLE students MODIFY age SMALLINT; C. MODIFY TABLE students ALTER age SMALLINT; D. CHANGE TABLE students UPDATE age SMALLINT;
讲解:使用ALTER TABLE + MODIFY来修改字段数据类型,CHANGE用于修改字段名。- 以下哪种方法可以复制表
orders的结构和数据到新表orders_copy?A A. CREATE TABLE orders_copy AS SELECT * FROM orders; B. COPY TABLE orders TO orders_copy; C. INSERT INTO orders_copy SELECT * FROM orders; D. CLONE TABLE orders orders_copy;
讲解:这是最常用的复制表方法,会同时复制表结构和数据。- 以下适合存储邮件地址的字段类型是?C A. DATE B. DECIMAL C. VARCHAR D. TINYINT
讲解:邮件地址是可变长度字符串,VARCHAR最适合。DATE是日期,DECIMAL是小数,TINYINT是整数。- 要在创建表
products时,确保product_name字段的值不为空,应使用以下哪种约束? B A. UNIQUE B. NOT NULL C. CHECK D. DEFAULT
讲解:NOT NULL约束确保字段必须有值,不能为空。2 简答题
-
简述在 MySQL 中创建表时,如何选择合适的字段类型,请举例说明。 答: 存储: 身高、体重、工资、奖金,适合使用数值类型。如:tinyint unsigned、long、int 存储: 姓名、家庭地址、收货地址,适合使用字符类型。如:char、varchar 存储: 生日、出生年份、入职时间、下班时间、注册时间,适合使用日期时间。date、time、datetime、year 存储: 爱好、性别、社保医院,适合使用枚举类型。如:enum、set
-
说明使用
ALTER TABLE语句修改表结构时,修改字段名和修改字段数据类型的操作有什么不同。 答: 1. 修改字段数据类型: 语法:alter table 数据库.表 modify 字段名 新数据类型; 2. 修改字段名: 语法:alter table 数据库.表 change 旧字段名 新字段名 数据类型; -
复制表有哪几种常见方式,它们各自的优缺点是什么? 答: 1. 复制表结构(不复制数据) 语法:CREATE TABLE 新表名 LIKE 旧表名; 优点:快速,只复制结构 缺点:不包含数据 2. 复制表结构和数据: 语法:CREATE TABLE 新表名 AS SELECT * FROM 旧表名; 优点:同时复制结构和数据 缺点:不复制索引和约束
-
解释表的基本约束
NOT NULL和DEFAULT的作用,并举例说明如何在创建表时使用。 答: NOT NULL: 作用: 不允许字段为空、字段必须有值 举例: create table 数据库.表 (字段名 数据类型 not null); DEFAULT: 作用: 设置字段的默认值、当不赋值时使用 举例: create table 数据库.表 (字段名 数据类型 default 默认值);
3 操作题
- 创建一个名为
books的表,包含字段book_title(字符串类型,长度不超过 100)、publish_year(年份类型)、price(小数类型,保留两位小数)。
mysql> create table if not exists studb.books ( -> id int auto_increment primary key, -> book_title varchar(100), -> publish_year year, -> price decimal(10,2) -> );Query OK, 0 rows affected (0.94 sec)
mysql> desc studb.books;+--------------+---------------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+--------------+---------------+------+-----+---------+----------------+| id | int | NO | PRI | NULL | auto_increment || book_title | varchar(100) | YES | | NULL | || publish_year | year | YES | | NULL | || price | decimal(10,2) | YES | | NULL | |+--------------+---------------+------+-----+---------+----------------+4 rows in set (0.00 sec)
mysql>- 在
books表中添加一个新字段author,类型为字符串,长度不超过 50。
mysql>mysql> alter table studb.books add author varchar(50);Query OK, 0 rows affected (2.88 sec)Records: 0 Duplicates: 0 Warnings: 0
mysql> desc studb.books;+--------------+---------------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+--------------+---------------+------+-----+---------+----------------+| id | int | NO | PRI | NULL | auto_increment || book_title | varchar(100) | YES | | NULL | || publish_year | year | YES | | NULL | || price | decimal(10,2) | YES | | NULL | || author | varchar(50) | YES | | NULL | |+--------------+---------------+------+-----+---------+----------------+5 rows in set (0.00 sec)- 复制
books表的结构和数据到一个新表books_archive。
mysql> create table studb.books_archive select * from studb.books;Query OK, 0 rows affected (1.29 sec)Records: 0 Duplicates: 0 Warnings: 0
mysql> show tables;+-----------------+| Tables_in_studb |+-----------------+| books || books_archive || salary || salary2 || stuinfo || t1 || t2 || t6 || t8 |+-----------------+9 rows in set (0.00 sec)
mysql> desc books_archive;+--------------+---------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------------+---------------+------+-----+---------+-------+| id | int | NO | | 0 | || book_title | varchar(100) | YES | | NULL | || publish_year | year | YES | | NULL | || price | decimal(10,2) | YES | | NULL | || author | varchar(50) | YES | | NULL | |+--------------+---------------+------+-----+---------+-------+5 rows in set (0.00 sec)- 修改
books表中price字段的默认值为 0。
mysql> alter table books modify price decimal(10,2) default 0;Query OK, 0 rows affected (0.23 sec)Records: 0 Duplicates: 0 Warnings: 0
mysql> desc books;+--------------+---------------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+--------------+---------------+------+-----+---------+----------------+| id | int | NO | PRI | NULL | auto_increment || book_title | varchar(100) | YES | | NULL | || publish_year | year | YES | | NULL | || price | decimal(10,2) | YES | | 0.00 | || author | varchar(50) | YES | | NULL | |+--------------+---------------+------+-----+---------+----------------+5 rows in set (0.00 sec)
mysql>- 将
books表中的book_title字段设置为不允许为空。
mysql> alter table books modify book_title varchar(100) not null;Query OK, 0 rows affected (2.19 sec)Records: 0 Duplicates: 0 Warnings: 0
mysql> desc books;+--------------+---------------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+--------------+---------------+------+-----+---------+----------------+| id | int | NO | PRI | NULL | auto_increment || book_title | varchar(100) | NO | | NULL | || publish_year | year | YES | | NULL | || price | decimal(10,2) | YES | | 0.00 | || author | varchar(50) | YES | | NULL | |+--------------+---------------+------+-----+---------+----------------+5 rows in set (0.00 sec)