--- title: "06-表的管理" created: 2025-11-25 tags: - 项目筑基 --- # 表的管理 ## 数据表的创建 ### 数据类型: ![[image-b64014ea.png]] #### 整数数据类型 有4种整数数据类型:int、smallint、tinyint和bigint,用于存储不同范围的值。 ![[image-f1323a17.png]] #### 浮点数据类型 浮点数据用来存储系统所能提供的最大精度保留的实数数据 。 ![[image-311c9912.png]] #### 精确数值数据类型 精确数值数据类型用于存储有小数点且小数点后位数确定的实数 。 货币数据类型 除了decimal和numeric类型适用于货币数据的处理外 SQL Server还专门提供了两种货币数据类型:money和smallmoney。 ![[image-fb530328.png]] #### 字符数据类型 字符数据类型用于存储汉字、英文字母、数字符号和其他各种符号。 输入字符型数据时要用单引号(')将字符括起来。 字符型数据有: 定长字符型(char) 变长字符型(varchar) 文本型(text) char节省时间 varchar节省空间 #### Unicode 字符数据类型 SQL Server允许使用多国语言,采用Unicode标准字符集。为此SQL Server提供多字节的字符数据类型:nchar(n)、nvarchar(n)和ntext。 ![[image-9ed14c31.png]] #### 二进制数据类型 SQL Server二进制数据类型用于存储二进制数或字符串。 有3种有效二进制数据类型,即定长二进制类型binary 变长二进制类型varbinary 大块二进制类型image ![[image-8b80c577.png]] #### 日期和时间数据类型 用于存储日期和时间数据。 datetime、smalldatetime、datetime2、datetimeoffset、date和time。 #### 逻辑数据类型 亦称为位(bit)数据类型, 适用于判断真/假的场合,长度为一个字节,取值为1、0或NULL。 #### 其他数据类型 ![[image-cf219808.png]] ![[image-32ed0566.png]] #### mysql中常用数据类型 char(255) varchar 可变长的字符串(255) 比较智能 节省时间 根据给出数据长度动态分配空间 int(11) bigint 相当于long float double date 短日期类型 datetime 长日期类型 clob (Character Large OBject) 字符大对象 最多可存储4个G的字符串(文章、说明) blob(Binary Large OBject) 二进制大对象 专门用来存储图片、声音、视频等媒体流数据 往该类型字段上插入数据时 (图片、视频)需要使用IO流 跟在后面的是长度 不需要考虑字节 给出100 就是3个长度 给出一个汉字是一个长度 但好像sqlsever里不是这样 sqlsever中用的字节 汉字占两字节 这个没必要太深究 ### 创建表 (仅用T-SQL语句) #### 建前声明 先说明在哪个数据库中建表——USE 名字 GO ![[image-075d71a8.png]] ![[image-1cda3fad.png]] #### 创表 ![[image-58c72aa8.png]] ![[image-42a3e2a7.png]] 涉及内容 数据类型 数据长度 数据计算…… ![[image-1f06844c.png]] 如图,属性分别对应着列名 char、int…对应数据类型 null/not null对应允许null值 列名(属性名)不能设置重复的 NULL、NOT NULL可以省略不写 不写时默认为NULL 一般用到的char、float、int、money、date char需要设置长度 比如属性3中 插入超过两个字符的数据就会保错 Int等类型无需长度 属性9设置了将两个char类型相加(相当于字符连接 里面插入的数据不会进行计算 只会连接在后面) 属性10、11分别设置了将两个int和money类型相加(float也可以) 也就是说 当输入完属性5、6和属性7、8后无需手动填写属性10、11,换行后数据会自动填入。 这是AS的一个妙用。 #### 填写表数据 暂时使用 编辑前200行 填写的数据是逐行自动保存的 放心关闭 填写错了? 返回上一行修改 但是会标记感叹号 没关系 关闭重新打开编辑前200行即可 #### 完整性约束 保证数据的完整性 定义可输入表或表的单个列中的数据的限制条件 1. 实体完整性(Entity Integrity)、 2. 参照完整性(Referential Integrity)、 3. 用户定义的完整性(User-defined Integrity)。 主要看 空值/非空值约束(NULL/NOT NULL) 主键约束(PRIMARY KEY) 外键约束( FOREIGN KEY) 唯一性约束(UNIQUE) 检查约束(CHECK) 默认约束(DEFAULT) ##### 空值约束 CREATE TABLE 表名 (列名 类型(长度) 是否为空值, 列名 类型(长度) 是否为空值, …… 列名 类型(长度) 是否为空值 ) 规定好某属性是否允许为空值 未设置则默认为允许 ![[image-d5c435f4.png]] ![[image-f395a009.png]] ##### 主键约束 (也就是实体完整性约束) 如果为列主键 则代表该列中不能出现相同的数据 如果为表主键 则n个主键不能同时相同 主键不允许为空 设置一个主键 两种写法 设置多个主键 ![[image-b5dc675f.png]] ![[image-d7432e07.png]] ![[image-062ff4d1.png]] PRIMARY KEY(属性名,属性名…) 如表3 想设几个联合主键就往里加 直接在想设置主键的那行语句后面加primary key (SSMS就按住Ctrl单击想设的) 而后再逗号 与那行合成了一条语句 如表4 在最后另加一条语句 注意:当有多个主键时 PRIMARY KEY(属性名) 设置该属性为主键 (以两个为例) 两个数据有一个是一样的是允许的 注意两种方法的逗号位置 不要混淆。 但两个都一致后就无法添加了 (实体必须区分开来) 主键名字太长很难看 用CONSTRAINT ![[image-8bcbb171.png]] ![[image-29a330ce.png]] 如图主键名称变成了我们好理解的PK\_选课成绩 ##### 外键约束 也就是参照完整性 ![[image-19e9e06b.png]] 涉及到一个“级联操作” SQL Server提供了两种级联操作以保证数据完整 (1)级联删除确定当主键表中某行被删除时, 外键表中所有相关行将被删除。 (2)级联修改确定当主键表中某行的键值被修改时 外键表中所有相关行的该外键值也将被自动修改为新值。 说白了就是要改一起改 语法: 属性名 类型长度FOREIGN KEY REFERENCES 表名(属性名) 注意点: 要想定义为从表的外键 必须先是主表的主键(好像有误) 从表中想设为外键的属性名字最好与主表中的相同 方便理解 类型必须要是一致的 否则无法设置 外键可以为空 用外键的表认为是子表 被引用的为父表 先创父再创子 先删子再删父 被引用的好像不一定要是主键 但至少要具有唯一性约束(唯一才有价值) 实验一下外键约束的作用 插入的约束 创建复习表7 创建数据表8 引用数据表7中的“学院编号”为外键(一定要与主表中类型相同char类型) ![[image-ff5692be.png]] 在主表中主键添加三个内容 01 、02、 03 ![[image-cbea4d78.png]] 依次在从表中添加记录 当学院编号等于04时 无法插入——与外键约束冲突 为什么? 因为在主表的主键中 是没有04这条记录的 所以不能无中生有 ![[image-86e7d4f1.png]] 但是可以插入空数据(不插入) ![[image-0c272eb9.png]] ![[image-ee6292d2.png]] 总而言之 外键内的数据可以为空 但如果有 就一定要是定义范围内的内容 删除的约束 删除复习表7(主表中的一条记录) ![[image-09107d14.png]] ![[image-44603666.png]] 无法删除 因为表8(从表)中引用了03这个学院编号 反过来 如果在从表中删除引用过主表主键的数据呢 ![[image-3c1e68e0.png]] ![[image-101ea0ea.png]] 是可以删除成功的 删除或更新主键表中的数据(外键表中有该目标键的数据)时,会报错,不允许删除或更新,必须先把外键表中关联的数据删除之后才能删除主键表中的数据。 怎么改变这种情况? 我如果就是要删主表内的东西怎么办?——设置级联删除 那么想强化一下两个表之间的联系呢 比如说改了主表中的数据 想要从表内的一起被修改 ——设置级联更新 几个单词: foreign外国的(外键) references 提到(引用) update更新 cascade 级联 delete 删除 将某属性作为外键 引用 表名(属性名) 作为级联更新 FOREIGN KEY (某属性) REFERENCES 表名(某属性) ON UPDATE CASCADE, 将某属性作为外键 引用 表名(属性名) 作为级联删除 FOREIGN KEY (某属性) REFERENCES 课程(某属性) ON DELETE CASCADE (这语句是连同设置外键一起实现了的) ![[image-708a468b.png]] 实验一下功能 (这里多加了个逗号 但没报错?) 于表9(主表)中加01 02 03 三条记录 于表10(从表)中加引用了 01 02 03 的课程记录 ![[image-4ed9e435.png]] ![[image-eed6f577.png]] 尝试修改主表内容(这次没有保错) ![[image-d542dde6.png]] 把学院编号从01变成111 02变成222 03变成333 神奇的事情发生了 表10(从表)中的学院编号内容一起受到了修改 ![[image-9be8f6fa.png]] 删除主表中的记录 从表中一样会被删除 ![[image-37305d31.png]] ![[image-7e8f2974.png]] 修改从表 主表不会受到影响 修改主表 从表会同步更新 ![[image-f4ea4483.png]] ##### 唯一性约束 unique独一无二的 跟主键约束差不多 主键也强制执行唯一性,但主键不允许空值,唯一性约束指定的列可以有NULL属性,故主键约束强度大于唯一约束。 因此主键列不需再设定唯一性约束。 (1)设置一条属性为唯一性约束 ![[image-81d0863f.png]] 不能插入相同的数据 ![[image-4dbe12b4.png]] ![[image-aea8ea63.png]] 可以为空值 但不能有两个空值 反正就是不能有一样的 ![[image-3a0031de.png]] ![[image-d94ab49a.png]] (2)设置多条唯一性约束 实际情况常遇到 比如说 不同班可以有同名的人 同一个班不允许同名的 ![[image-7dd96bba.png]] 和联合主键一样 一个相同不要紧 但不能两个同时相同 区别在于 多了可以添加空值NULL ![[image-0156e759.png]] NOT NULL+UNIQUE=Primary ##### 检查约束 (用户自定义约束) 对输入列或整个表中的值设置检查条件,以限制输入值,保证数据库的数据完整性。 关键字 OR 、IN、AND、BETWEEN… AND、LIKE…… 填入的数据需为多者中其中一个 —— OR、IN ```sql /*写法1*/ CREATE TABLE 教师 (教师编号 char(10) PRIMARY KEY, 姓名 char(20) NOT NULL, 性别 char(2) CHECK(性别='男' OR 性别='女'), 出生日期 date, 职称 char(20), 学院编号 char(2) NOT NULL, 密码 char(20) ) /*写法2*/ CREATE TABLE 教师2 (教师编号 char(10) PRIMARY KEY, 姓名 char(20) NOT NULL, 性别 char(2) CHECK(性别 IN('男','女')), 出生日期 date, 职称 char(20), 学院编号 char(2) NOT NULL, 密码 char(20) ) ``` 填入数据需在一定范围内 —— AND、BETWEEN……AND ```sql /*写法1*/ CREATE TABLE 选课成绩 (学号 char(10), 课程编号 char(20) NOT NULL, 成绩 int CHECK(成绩 between 0 and 100), CONSTRAINT PK_选课成绩 PRIMARY KEY(学号,课程编号) ) /*写法2*/ CREATE TABLE 选课成绩2 (学号 char(10), 课程编号 char(20) NOT NULL, 成绩 int CHECK(成绩>=0 AND 成绩 <=100), CONSTRAINT PK_选课成绩2 PRIMARY KEY(学号,课程编号) ) ``` 对于输入一串需要限制范围的数 如电话号码——LIKE ```sql CREATE TABLE 学院 (学院编号 char(2) PRIMARY KEY, 学院名称 char(30) UNIQUE, 学院电话 char(12), 学院地址 char(50), CHECK(学院电话 LIKE '0[1-9][0-9][0-9]-[1-9][0-9][0-9][0-9][0-9][0-9][0-9]' OR 学院电话 LIKE '0[1-9][0-9]-[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]') ) ``` 限制输入的数与其他数据的关系 如时间上的早晚 ```sql CREATE TABLE 销售订单 (订单编号 char(10) PRIMARY KEY, 商品编号 char(10), 数量 float, 价格 float, 订货日期 date, 发货日期 date, 到货日期 date, CHECK(发货日期>订货日期 AND 到货日期>发货日期) ) ``` 这些约束设置之后 编辑前200行时就不能插入不符合的数据了 ##### 默认值约束 确保在没有为某列指定数据时,来指定列的值。默认值可以是常量,也可以是表达式,还可以为NULL值。 减少重复输入多次相同数据 可将某一数据不填时默认为 什么什么 ```sql CREATE TABLE 课程 (课程编号 char(8) PRIMARY KEY, 课程名称 varchar(50), 学时数 int, 学分数 float, 课程性质 char(10) CONSTRAINT DF_课程_课程性质 DEFAULT '必修', 课程介绍 text ) (CONSTRAINT可以理解为定义约束的名字 可以有 也可以没有) CREATE TABLE 课程1 (课程编号 char(8) PRIMARY KEY, 课程名称 varchar(50), 学时数 int, 学分数 float, 课程性质 char(10) DEFAULT '必修', 课程介绍 text ) ``` 将系统日期作为默认填入日期 使用getdate函数 ```sql CREATE TABLE 销售订单1 (订单编号 char(10) PRIMARY KEY, 商品编号 char(10), 数量 float, 价格 float, 订货日期 date DEFAULT getdate(), 发货日期 date, 到货日期 date, CHECK(发货日期>订货日期 AND 到货日期>发货日期) ) ``` 默认值约束设置后 当某元组值没填就回车时 就会自动填上所设置的内容(跟自动补NULL一个原理) 常用于填充比较常用的数据 简化插入操作 getdate函数实用型也比较强 ## 数据表的修改(结构) 同样 需要ALTER TABLE 名字 打句招呼 sp\_help 表名 查询表的信息 ### 列的修改 #### 修改列 类型大小 ALTER TABLE 表名 ALTER COLUMN 已有列名 varchar(30)【要更改成什么】 将课程编号的char(50)改成char(30) ![[image-a4d278a8.png]] ![[image-f1a67288.png]] 只能修改非主键的类型和长度 ![[image-068d34b5.png]] #### 增加列 ADD 属性名 类型(长度) ![[image-22db3202.png]] 增加求和列(无需类型长度) ![[image-4db93a02.png]] #### 删除列 可以同时删除多个 ![[image-af27a110.png]] ![[image-d6fbcaaf.png]] #### 修改列名 ![[image-aa7b860b.png]] 把学号改成学生编号 EXEC sp\_rename'表名.原列名','想修改成的列名' 注意:表名和原列名之间是点号‘.’,不是逗号‘,’ ![[image-19d259d8.png]] ![[image-1312c923.png]] 这条指令是可以修改主键列的列名的 不会同修改类型长度那样报错 ### 约束的修改 准确来说应该是增减约束 不能对已创立的约束直接修改 如果可以随意修改 不正是破坏了完整性约束吗 要修改 只能把原来的约束删掉 再重新添加一个 #### 添加空值约束 虽然是只改空值约束 但是char(30)也要一起打上去 因为这些属性列是一一对应的 ![[image-283cb3e9.png]] ![[image-702add02.png]] #### 添加主键约束 必须先设为非空才能添加主键 ADD PRIMARY KEY(属性名) ![[image-47d143e0.png]] ![[image-80b23b3e.png]] ![[image-815ad064.png]] #### 添加外键约束 同创建时一个道理 被引用的一定要是主表的主键 然后类型长度要一致 名字最好一致 ![[image-9b807585.png]] ![[image-3661ae7d.png]] 还可以添加级联删除级联更新 ![[image-4baf2fe9.png]] #### 添加唯一性约束 ADD UNIQUE (属性名) ![[image-eb531817.png]] ![[image-230024df.png]] #### 添加检查约束 ADD CHECK () 关键字 OR 、IN、AND、BETWEEN… AND、LIKE…… 都可以用 举个邮箱的例子 涉及到两个通配符的知识 在数据库中 下划线‘\_’代表一个字符 百分号‘%’代表多个字符 ![[image-e452a1ff.png]] ![[image-79f68106.png]] #### 添加默认约束 ADD DEFAULT’想限定的默认值’ FOR 属性 创建表时 默认约束只能做列约束不能做表约束 修改则两者都可 for列名的写法只能用在修改表中 也必须用 ![[image-5d51678d.png]] ![[image-1b8f6eef.png]] 以上都没有使用CONSTRAINT 去将约束命名(constraint并非必需 只是方便理解 方便操作) #### 删除约束 因为前面没有使用CONSTRAINT去命名 所以现在删除时就比较麻烦 所以还是推荐养成习惯使用CONSTRAINT去命名约束 一方便自己理解 而方便后续修改 ![[image-339119d2.png]] (需要找到约束名 拷贝过来) ![[image-e9c9fe0b.png]] 如果设置了约束名称 ![[image-4223a86b.png]] 可见 约束名字不再冗长 ![[image-59e2bef0.png]] 进行删除操作时也更简单 无需去寻找名字 ![[image-63d5ab3d.png]] ![[image-9d61d7f1.png]] #### 修改约束名字 EXEC sp\_rename'原约束名字','新约束名字' ![[image-86bc9d5b.png]] ![[image-87c3ebf5.png]] ### 删除数据表 删除单个表 ![[image-7670cfa4.png]] 不能删除被引用中的表(被引用了作为外键 但没设置级联删除) ![[image-0556c49b.png]] 删除多个表 ![[image-c83e7114.png]] 删除完其他表后 作为主表的表3就不再被约束着了 ![[image-5026fd72.png]] 全部删除完毕 ![[image-123a5337.png]] 如果该表存在就删除不存在不删除 drop table if exists 表名 --- ⬅️ [[05-三范式|05-三范式]] 🏠 [[00-数据库|00-数据库]] ➡️ [[07-数据插入(增)|07-数据插入(增)]]