第5章 -2 数据表管理

认识数据表

在数据库设计过程中,最重要的是表结构设计,好的表结构设计,对应着较高的效率和安全性。创建表的核心是定义表结构及设置表和列的属性,创建表以前,首先要确定表名和表的属性,表所包含的列名、列的数据类型、长度、是否为空、键、默认值等,这些属性构成表结构。

数据表名

完整的数据表名称应该由数据库名和表名两部分组成,即“数据库名.表名”。

  • 在当前数据库中操作数据表时,表名之前的数据库名限定可以省略。
  • 在处理属于两个不同数据库中的数据表时,需要用完整的数据表名。

属性列名

表可以拥有多个属性列,各个属性列分别用来存储不同性质的数据,属性列名同样必须符合MySQL的命名规则。

定义表就是指定义表的结构。在定义表之前首先需要注意:
(1)表名:在同一个数据库中,每一个表都应该有一个唯一的名称。
(2)列名:每个表由若干个列组成,在同一个表中每个列的名字应该是唯一的。
(3)列的数据类型:表中的每个列都要定义一个数据类型。
(4)列的数据约束:列中是否主键、外键、默认值、允许空、自增列等约束。

表中的数据

例:

学号姓名性别出生日期专业总学分
191001刘清泉1998-06-21计算机52
191002张慧玲1999-11-07计算机50
191003冯涛1999-08-12计算机52
196001董明霞1999-05-02通信48

数据行:又称元组或记录,是现实世界中一个物理或逻辑实体的数据描述形式。
在这里插入图片描述
MySQL支持用多种方法在单个或多个列上创建约束,可以在创建表的同时创建约束,也可以在已有的表上创建约束。(约束详见第七章)
给约束定义的名称,称之为约束名。约束名可以由用户自己指定,也可由系统指定。

表间关联

在关系数据库中,一个数据库系统一般都包含多个表,表间也会存在联系。表间联系通过外键(外码)来实现,体现了关系之间的参照完整性。

一、数据类型

MySQL提供多种数据类型(对数据存储方式的一种约定),它能够规定数据的操作方式和存储所占空间的大小,主要根据实际需求(数据值的内容、大小、精度)来选择合适的数据类型。

数值型

MySQL数值型数据包括整数和小数。tinyint、smallint、mediumint、int、bigint,浮点小数类型float和double,定点(实数)小数类型decimal。

整数类型

数据类型字节数无符号数的取值范围有符号数的取值范围
tinyint1B0~255-128~127
smallint2B0~65535-32768~32767
mediumint3B0~16777215-8388608~8388607
int或integer4B0~4294967295-2147483648~2147483647
bigint8B0~18446744073709551615-9223372036854775808~9223372036854775807

实数数据类型(定点数)

数据类型字节数负数的取值范围非负数的取值范围
dec(m,d)、decimal(m,d)、numeric(m,d)M+2-1.7976931E+308~-2.2250738E-3080和2.2250738E-308~1.7976931E+308
  • 实数类型decimal,numeric用于存储整数或小数,保存的为确切精度的值。dec、numeric是decimal的别称。
  • 用(m, d)来定义小数,其中m称为精度,表示总共的位数;d称为标度,表示小数的位数。 其中m和d的取值范围是:≤m≤65,0≤d≤m and 0≤d≤30。
    decimal(12,4)代表变量可以存放12位数字,小数点后可以存放4位小数。

浮点数类型

浮点类型有两种:单精度浮点类型float和双精度浮点类型double,为近似存储(不推荐使用)
用(m, d)来定义小数,其中m表示总共的位数;d表示小数的位数。
其中m和d的取值范围是:m(1~ 255),d(1~30)

数据类型字节数负数的取值范围非负数的取值范围
float(m,d)4B-3.402823466E+38~-1.175494351E-380和1.175494351E-38~3.402823466E+38
double(m,d)8B-1.7976931E+308~-2.2250738E-3080和2.2250738E-308~1.7976931E+308

注:在创建表时,数字类型的选择应遵循以下原则:

  1. 在能够容纳所有数据的前提下,尽可能选择最小的可用类型,数据占用内存少,数据处理也更简单。例如年龄,正常的值在0到120之间,则可以使用tinyint。
  2. 在需要表示的精度要求比较高的时候,比如货币、用于科学计算用的数据等,优先选择定点数类型decimal。
  3. 不论定点类型还是浮点类型,如果用户指定的精度值超过系统定义的精度范围,则会进行四舍五入。
  4. 因为浮点数存在误差,也尽量避免两个数值相近的浮点数进行大小比较。在设计数据库时,很少使用其作为列的数据类型。

字符串类型

字符串类型取值范围说明
char(n)0~255个字符固定长度字符串
varchar(n)0~65535个字符可变长度字符串
tinytext0~255个字符可变长度短文本
text0~65535个字符可变长度长文本

char和varchar类型:

  • char(m)存储固定长度字符串,m表示字符个数,取值范围0~255,输入的字符串长度不足m时,右侧用空格填满,当查询到char的值时,尾部的空格被删除。
  • varchar(m)存储可变长度的字符串,m表示最大的字符串长度,取值范围0~65535,varchar的最大实际长度由最长字段的大小和使用的字符集确定。
    例如:varchar(50)定义一个最长为50的字符串,如果输入的字符串只有20个字符,那么实际存储的字符串的长度为21,20个字符+一个字符串结束符。
  • varchar在值存储和查询时尾部的空格仍保留

日期时间类型

日期时间类型字节数范围格式用途
date41000-01-01~9999-12-31YYYY-MM-DD日期值
time3-838:59:59~838:59:59HH:MM:SS时间值
year11901~2155YYYY年份值
datetime81000-01-01 00:00:00~9999-12-31 23:59:59YYYY-MM-DD HH:MM:SS混合日期和时间值
timestamp41970-01-01 00:00:00~2038-01-19 03:14:07YYYYMMDD HHMMSS时间戳(日期和时间)
  • 形式上,日期类型的表示方法与字符串的表示方法相同,使用单引号括起来;
  • 本质上,日期类型的数据是一个数值类型,可以参与简单的加、减运算;
  • date类型的字段可用函数current_date()或now()插入计算机系统的当前日
  • 每种类型都有取值范围,当插入不合法的值时,系统会将“0”插入该字段

二进制类型

  • binary
    binary和varbinary用于保存二进制字符串,它保存的是字节而不是字符,所以它们没有字符集,排序和比较按字节进行比较。
  • blob
    blob是一个二进制大对象,可以容纳可变数量的数据,可以存储数据量很大的二进制数据,如图片、音频、视频等二进制数据。

其它数据类型

(1) 枚举类型—特殊的字符串类型
字段名 enum(‘值1’,’值2’,…,’值n’)

  • “ 字段名”指将要定义的字段名称;“ 值n“指的是枚举列表中的第n个值,枚举列表中最多可以有65535个值,列表中的每个值的尾部空格自动被删除。
  • enum类型的字段在取值时,只能在指定的枚举列表中取,而且只能取一个值。
  • 如果enum类型的字段声明为允许null,null则为该字段的有效值,也是默认值;否则默认值为枚举列表中的第1个值。

(2) 集合类型—特殊的字符串类型
字段名 set(‘值1’,‘值2’,…,‘值n’)

  • set类型也属于字符串类型,在创建表的时候,通过列举方式(一个个的值列出来)为字段显式指定集合列表。
  • 与enum类型不同的是:enum类型的字段只能在指定的枚举列表中选择一个值;而set类型的字段可以从定义的列表中选择多个值。
  • 如果插入set字段中的值有重复,则MySQL自动删除多余的重复值。

二、数据表建立

创建数据表的过程是规定数据列的属性的过程,同时也是实施数据完整性(实体完整性、参照完整性和用户定义完整性)约束的过程。

CREATE TABLE 数据表名 (
    列名1 数据类型 [约束条件] [默认值],
    列名2 数据类型 [约束条件] [默认值],
    ...
    [表级别约束条件]
);

每列定义是可以使用以下参数:

列名 数据类型 [ not null |null][default 默认值][auto increment] [unique[key]] [[primary] key][comment 注释名称][reference 外键][index 索名][charset 字符集][collate 校验规则]
其中:
not null ,非空约束,作用:规定某个字段的内容不能空。
default ,默认值约束,作用:定义字段中的默认值属性。
auto_increment, 自增约束,每个表最多只能有一个,作用:自动增加数值,属性列数据类型必须为整型数据类型,初始值为1,每增加一条记录自动加1unique, 唯一约束,作用:规定某个字段中的值,不可以重复,每个值都是唯一的。
primary key ,主键约束,作用:非空约束 + 唯一约束。
foreign key, 外键约束,作用:主表中的列与从表中的列建立联系。
check, 检查约束,作用:检查数值的范围。
  • 根据约束的作用范围,约束可分为:
    • 列级约束: 只能作用在一个列上,定义在列的定义后面;
    • 表级约束: 可以作用在多个列上,不与列一起定义,定义在所有列的最后面。
  • 有些约束既可以创建为列级约束,也可以创建为表级约束。
名称位置支持的约束类型是否可以另起约束名
列级约束列的后面所有约束都支持,但外键没有效果不可以
表级约束所有列的最后面默认约束和非空约束不支持,其他都支持可以(但主键没有效果)

例如:

--1
CREATE TABLE orders (
    id INT PRIMARY KEY,
    customer_id INT NOT NULL,
    order_date DATE,
    amount DECIMAL(10,2),
    FOREIGN KEY (customer_id) REFERENCES customers(id)
);
--2
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(20) NOT NULL UNIQUE,
    password VARCHAR(50) NOT NULL,
    email VARCHAR(50),
    phone VARCHAR(20),
    INDEX(username),
    INDEX(email),
    INDEX(phone),
    COMMENT '用户表'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

三、数据表的修改

alter table 列名
{
   [add 新列名 数据类型 [列级完整性约束] [first|after 已存在字段名]]
   --增加新的属性列、约束
   --增加属性列分三种情况,第一列、在指定列之后、最后一列(默认)
   |[modify 列名1 新数据类型 [列级完整性约束条件][first|after 列名2]
   --修改属性列的数据类型或完整性约束
   |[change 旧列名 新列名 新数据类型]
   --修改属性列的名称或数据类型
   --change也可以只修改数据类型,实现modify的功能
   --方法是:新字段名和旧字段名同名。
   --即使不修改字段的数据类型,也不能省略新数据类型,可以将新类型设置成和原来一样。
   |[drop 列名|完整性约束名]
   --删除属性列或完整性约束
   |[rename [to]新表名]
   --对表重新命名
   |[engine=更新后的存储引擎名]
   --修改表的存储引擎
};

例如:

--1. 添加新列:
第一列alter table books add id int first;
在指定列(例如author列)之后alter table books add type varchar(100) after author;
默认在最后一列alter table books add press varchar(50);
--2.添加外键约束
   ALTER TABLE sc add foreign key(sno) references student(sno)on delete cascade on update cascade;
--3. 修改列的数据类型:
   ALTER TABLE table_name MODIFY column_name VARCHAR(50);
--4. 修改列的数据类型并指定位置:
   ALTER TABLE table_name MODIFY column_name VARCHAR(50) AFTER existing_column;
--5. 修改列名和数据类型:
   ALTER TABLE table_name CHANGE old_column_name new_column_name INT;
--6. 删除列:
   ALTER TABLE table_name DROP column_name;
   alter table sc drop foreign key sc_ibfk_1;--删除外键
--7. 重命名表:
   ALTER TABLE table_name RENAME TO new_table_name;
--8. 修改存储引擎:
   ALTER TABLE table_name ENGINE = InnoDB;

外键约束格式:

[constraint [constraint_name]] 
foreign key [index_name](column[,…n]) references ref_talbe(ref_col[,…n])
	[on delete {restrict | cascade | set null | no action | set default}]
	[on update {restrict | cascade | set null | no action | set default}]
  • ON DELETE和ON UPDATE选项是通过使用级联引用完整性约束,定义当用户试图删除或更新现有外键指向的键时,数据库引擎执行的操作;
  • RESTRICT表示拒绝对父表进行删除或更新操作。
  • CASCADE表示如在父表中删除或更新了一行,则将在引用表中删除或更新相应的行。即级联删除或级联更新。
  • SET NULL表示如果删除或更新了父表中的相应行,则会将构成外键的所有值设置为 NULL。若要执行此约束,外键列必须可为空值。
  • NO ACTION与RESTRICT的作用相同,它是标准的SQL关键字。
  • SET DEFAULT表示如果删除或更新了父表中的相应行,则会将构成外键的所有值设置为它们的默认值。

四、数据的插入、修改与删除

数据插入

  • 在mySQL中通过insert语句插入新的数据,使用insert语句可以同时为表的所有属性插入数据,也可以为表的指定属性插入数据。
  • insert语句可以同时插入多行元组。
  • 如果设置了外键约束,表间已经建立了关联,在录入数据时应该先录入主表的记录,然后再录入从表的记录。

数据插入,可以使用以下语句:

insert 
into 表名 [(列名列表)] 
--列名:用来指定要向其中插入数据的列的名称。
values (取值列表1) [,(取值列表2),, (取值列表n)]
--①不指定列名:必须为每个列都插入数据,且值的顺序必须与表定义的列的顺序一致。
--②指定列名:只需要为指定列插入数据,列名顺序自定义,数据与列名一一对应。

注:

  • 取值列表中的数据值应该与列名列表中的属性列一一对应,并且数据类型也相同,不止一条数据时,用英文逗号隔开。
  • 必须为表中所有定义为not null的列提供取值。
  • 如果表中存在自增列,则系统可以自动维护自增列的值,不需要向自增列中插入值。
  • 主键所在列的值不允许重复,也不允许出现空值

数据修改

数据修改,可以使用以下语句:

update 表名 
set 列名1=1, 列名2=2,, 列名n=值n 
[where 条件表达式];

例如:

update sc
set grade=87
where sno=04001and cno=002;
--将学号为04001,课程号为002的选课记录中的成绩修改为87。
update books 
set unitprice=unitprice*0.9; 
--修改books表中的unitprice值为调低为9折以后的价格。

数据删除

  • 从数据表中删除数据一般使用DELETE语句,它允许用WHERE子句指定删除条件。
  • 使用SQL语句删除数据可以分为两种情况:删除所有数据和删除指定数据。
  • 删除主外键关系的主键表中的数据时,可能影响外键表的对应数据:级联删除、不允许删除……
  • 使用TRUNCATE语句时,只需提供要清空数据的表名即可。执行该语句后,表中的所有数据将被删除,但表结构和定义将保持不变。

数据删除,可以使用以下语句:

--1
   DELETE 
   FROM 表名 
   [WHERE condition];
--如果不加where关键字,那么将删除整个表
--加上where关键字将只删除符合条件的数据行

--2
   TRUNCATE [TABLE] 表名;
--Truncate语句用于删除表中所有行,不带where条件
--TRUNCATE语句无法回滚操作
--一旦执行了TRUNCATE语句,数据将无法恢复
  • truncate 是整体删除所有记录,速度更快,delete是逐条删除记录,速度较慢,truncate 和 delete 都不删除表结构;

  • truncate table 语句清空表记录后会重新设置自增型字段的计数起始值为1;使用 delete 语句删除记录后自增字段的值并没有设置起始值,而是依次递增。

  • truncate 语句的操作对象只能是数据表,不能是视图;而 delete 可以对表和视图进行记录的删除操作

  • 当表被 truncate后,这个表和索引所占用的空间会恢复到初始大小,释放存储空间; delete 操作不会减少表或索引所占用的空间,不释放存储空间。

例如:

--在students表中插入一条id为101,姓名为Tom,年龄为20,性别为男的新记录
   INSERT 
   INTO students (id, name, age, gender) 
   VALUES (101, 'Tom', 20, 'Male');
--将students表中所有年龄小于18岁的学生的性别改为“男”
   UPDATE students 
   SET gender = 'Male' 
   WHERE age < 18;
--将students表中年龄大于22岁的所有学生的记录删除
   DELETE 
   FROM students 
   WHERE age > 22;

   delete from sc;
--删除sc表中的所有数据
--等价于
   truncate sc;

五、数据表复制与删除

数据表复制

数据表由表结构和内容两部分构成,在进行复制时,可以分别复制,也可以同时复制。

  • 只复制表结构
  • 同时复制表结构和内容
  • 只复制表内容
   -- 只复制表结构
   CREATE TABLE 表名 [if not exists]LIKE 旧表名;CREATE TABLE 表名 [if not exists] as 
   select 列名的列表 
   from 旧表名 
   where 1=2
   --WHERE 1=2 这个条件语句永远不会为真,因为 1 总是等于 1 而不是 2
   --因此,这个 WHERE 子句实际上会过滤掉所有的行
   --结果返回一个空的结果集
   
   --复制表结构和内容
   CREATE TABLE 表名 [if not exists] as 
   select 列名的列表 
   from 旧表名 
   [where 条件];
   
   -- 复制数据
   --同结构
   INSERT INTO 表名(字段列表) 
   SELECT * 
   FROM 旧表名;
   --不同结构
   INSERT INTO 表名(字段列表) 
   SELECT 字段列表 
   FROM 旧表名
   [where 条件];

例如:
将学生表s的表结构复制到student表中,student表中只复制学号、姓名和学院属性列。

create table student  as
select sno, sname, scollege from s where 1=2;
--如果不加where 1=2,则将数据和表结构一起复制,上面只复制了表结构
insert into student(sno,sname,scollege)
select sno,sname,scollege from s;

数据表删除

  • 删除数据表是指将表的定义(表结构)和表中的数据全部删除,并释放被删除表所占用的存储空间,且不能恢复。
  • 在删除表之前最好对表进行备份,以免造成无法挽回的后果。
   DROP TABLE [if not exists] 表名1[,表名2,···];

DROP TABLE语句将完全删除表及其数据,并且无法恢复。

truncate 、delete、drop的区别:

删除内容释放空间不删除定义(结构)
truncate table
delete×
drop×
  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值