MySQL 数据定义语言 DDL

news2024/10/7 11:22:41

文章目录

  • 数据定义语言 DDL
    • 表的设计
    • 范式
      • 第一范式(1NF)
      • 第二范式(2NF)
      • 第三范式(3NF)
    • 创建表
    • 修改表
    • 删除表
    • 截断表


数据定义语言 DDL

在这里插入图片描述

前面我们学习的 DML 语言,主要实现对数据的增、删、改等基本操作。而数据定义语言(Data Definition Language,DDL)则是实现对数据结构、操作等的定义。 例如,对数据库、数据表、索引等的设计、创建、修改、删除等操作,都属于 DDL 范围。接下来,就让我们一起进入 DDL 的学习之旅。

表的设计

表是数据库中最重要的对象,是数据库的基本存储单元,由行(记录)和列(字段)组成。 表名和 Java 语言中的变量名一样,有自己的命名规则:

  1. 英文字母、数字和下划线 _ 组成,命名简洁明确,多个单词用下划线 _ 连接;
  2. 英文全部使用小写,禁止出现大写;
  3. 禁止使用数据库关键字,如:name,time ,datetime,password 等;
  4. 表名称不应该取得太长(一般不超过三个英文单词);
  5. 表的名称一般使用名词或者动宾短语;
  6. 使用英语名词时,用单数形式表示名称,而不用复数,例如,使用 employee 表示员工表,而不是 employees。

设计表时应遵循一个基本原则:只将实体的直接属性纳入。举例说明:已考虑公民表有姓名、年龄、联系方式、国籍四个字段,国籍对应国家,那么国家信息(如名称、代码、语言等)是否该放入这个表?

一种考虑是,直接在该表中增加国家信息的多个字段,该表中既有个人信息,也有国家信息。但这会产生一个问题,以中国为例,该表至少有 13 亿条记录,个人直接属性是不同的,但国家信息部分会重复 13 亿次,造成了存储空间的极大浪费。

第二种方法就是拆分,把个人信息和国家信息拆分成两个表。如此国家信息表中只需要一条记录就可以表示中国的信息。在此基础上,利用我们前学习的连接查询可同时得到个人信息和国家信息。

单表的字段设计,多表的关系设计,这些都需要数据库设计范式的指导。

范式

关系型数据库目前有 6 种范式,数据库设计好坏的判断标准就是看它满足了第几范式。通过企业项目对数据库的使用来看,一般情况下我们只要满足前三个范式即可,所以笔者也重点介绍前三范式。

第一范式(1NF)

指在关系模型中,数据库表的每一列都是不可分割的原子数据项。即实体中的某个属性有多个值时,必须拆分为多个属性。

学号姓名专业/学院课程名分数
1小张大数据专业/计算机学院HTML98
1小张大数据专业/计算机学院JAVA95
2小李大数据专业/计算机学院Python100
2小李大数据专业/计算机学院MySQL90
3小王金融管理专业/财经学院经济学85

在上表中,“专业/学院”这个字段包含了专业和学院两个值,根据 1NF 的要求,必须把“专业/学院”拆分为“专业”和“学院”两个字段。拆分后的表如下表所示:

学号姓名专业学院课程名分数
001小张大数据专业计算机学院HTML98
001小张大数据专业计算机学院JAVA95
002小李大数据专业计算机学院Python100
002小李大数据专业计算机学院MySQL90
003小王金融管理专业财经学院Linux85

此时该表符合了第一范式。

第二范式(2NF)

在 1NF 的基础上,2NF 要求表必须有主码,非码属性必须完全依赖于主码。要完全理解 2NF 的含义,需要先弄清楚几个概念:

  • 函数依赖:设有属性 A、B,如果通过 A 属性(或属性组)的值可以确定唯一 B 属性的值,则可以称为 B 依赖 A 或者 A 决定 B,用 “->” 来表示决定(依赖)关系,记作 A->B。例如,可以通过身份证号来确定学生姓名。
    函数依赖又分为三种:分别是完全函数依赖、部分函数依赖、传递函数依赖。

    • 完全函数依赖:如果 A 是一个属性组(由多个属性组成),则 B 属性值的确定需要依赖 A 属性组中的所有属性值。例如:把学号和课程名作为属性组,分数的确定就必须要同时知道学号和课程名才行。少了学号,不知道是谁的成绩;少了课程名,只知道谁的成绩而不知道是哪门课的成绩。所以该属性组的两个值必不可少,这就是完全函数依赖。
    • 部分函数依赖:如果 A 是一个属性组,则 B 属性值的确定只需要依赖 A 属性组中的部分属性值。例如:把学号和课程名作为属性组,姓名的确定只需要 A 中的学号即可,和课程名无关。这就是部分函数依赖。
    • 传递函数依赖:即依赖的传递关系,通过 A 可以确定 B,记作 A->B;通过 B 可以确定 C,记作 B->C;可得出 A->C;这就是传递依赖关系。
  • 候选码:如果表中,一个属性或属性组,被其它所有属性完全函数依赖,则称这个属性或属性组为该表的候选码,简称码。成绩表中有学号、课程名、分数三个属性,分数的确定完全依赖学号和课程名,所以学号和课程名组成的属性组就是该表的候选码。

  • 主属性码:主属性码也叫主码,在多个候选码中挑选一个做主码,也即是我们常说的主键。

  • 非主属性码:除主属性码以外,其余的叫做非主属性码。

理解了这些概念以后,再来判断上表是否符合 2NF 的标准。

步骤如下:

  1. 找出数据表中所有的候选码;
  2. 根据候选码,找出主属性码;
  3. 得到非主属性码;
  4. 查看非主属性码对主属性码是否完全依赖(不存在部分函数依赖)。

具体实现:

第一步:

  • 查看每一个单一属性,当它的值确定了,剩下的所有属性值是否都能确定。该表中单一属性都没法确定其它属性的值。如:以学号为主键,对应的课程名却出现了多个,所以学号不是候选码。
  • 查看所有两两属性的属性组,当属性组确认后,剩下的所有属性值是否都能确定。

依次类推,最后得到该表的候选码只有一个,即(学号,课程名)。

第二步:

因为候选码只有一个,所有主码也就确定了。

第三步:

非主属性码就是(姓名,专业,学院,分数)

第四步:

判定非主属性码是否部分函数依赖主码?

对于主码(学号,课程名)->姓名,只需要学号即可确定姓名,所以存在非主属性码姓名,对主码(学号,课程名)的部分函数依赖。此时我们可以判定之前的表不满足 2NF。

为了让之前的表满足 2NF,我们需要消除表中部分函数依赖,办法只有一个,那就是拆分表。将之前的表拆分为两个表。一个叫做选课表,包含的属性有学号、课程名、分数;另一个叫做学生信息表,包含的属性有学号、姓名、专业、学院,如下选课表和学生信息表所示。

选课表

学号课程名分数
001HTML98
001JAVA95
002Python100
002MySQL90
003Linux85

学生信息表

学号姓名专业学院
001小张大数据专业计算机学院
002小李大数据专业计算机学院
003小王金融管理专业财经学院

对于选课表,学号和课程名是主码,唯一的非主属性分数对主码完全函数依赖。所以该表符合 2NF;对于表 学生信息表,学号是主码,该码只有一个属性,所以不存在非主属性对码的部分函数依赖,符合 2NF。 达到 2NF 还会出现什么问题呢?请看第三范式。

第三范式(3NF)

在 2NF 的基础上,3NF 要求不存在传递依赖。也即是,如果存在非主属性码对于码存在传递函数依赖,则不符合 3NF。

如学生信息表,主码为学号,非主属性码为姓名、专业、学院。因为学号->专业,专业->学院,所以学生信息表存在传递函数依赖,不符合 3NF。为此我们需要把学生信息表拆分成两个表,如学生专业表与专业信息表。

学生专业表

学号姓名专业
001小张大数据专业
002小李大数据专业
003小王金融管理专业

专业信息表

专业学院
大数据专业计算机学院
金融管理专业财经学院

拆分以后,当再想删除某个专业的所有学生信息的时候,专业信息不会一起被删除。满足 3NF 后,我们所设计的表就具有较好的规范了,同时降低了数据冗余。

创建表

创建表,使用的 SQL 语句是 CREATE TABLE,其基本语法形式如下:

CREATE TABLE table
(colname1 type1, colname2 type2…colnamen typen)

其中,table 表示表名,colname1,colname2,…表示表的字段名,type1,type2,…是字段的数据类型。 创建表 6-7,其 SQL 语句如下:

create table student
(student_id int,
student_name varchar(20),
student_specialty varchar(20)
);

输出结果:
在这里插入图片描述

提醒:SQL 语句以 ;表示结束,上述例子虽然写了四行,但是仅表示一条语句;且每个字段与字段类型之间用空格隔开,字段与字段之间用 , 分隔,最后一个字段的类型后面可以不加 ,。

使用 show tables 命令列出所有表。如下所示:

show tables;

输出结果:
在这里插入图片描述

也可以使用 desc 命令查看某个表的结构,如下所示:

desc student;

输出结果:
在这里插入图片描述

我们主要关心 Field 和 Type 两列即可,后面的四列我们会在下一节 MySQL 约束控制中介绍。 细心的朋友可能已经发现,我们将 student 表中的 student_id 定义为 int 时,没有指定长度,而查看表结构的时候,int 的长度显示为 11。这是因为 int 默认长度为 11(也是其默认长度)。

修改表

如果我们需要对表结构进行更改,比如添加或者删除一个字段,或者重命名某个字段等等。在改动不大的前提下,可以在原表的基础上进行修改。

修改表使用的 SQL 语句是 ALTER TABLE,有 3 种形式,分别是修改字段、添加字段、删除字段。

其中修改字段分两种:

只改字段名而不改字段类型,其 SQL 语法如下:

ALTER TABLE table CHANGE oldcolname newcolname type;

不改字段名而只修改字段类型,其 SQL 语法如下:

ALTER TABLE table MODIFY colname newtype;

添加字段语法如下:

ALTER TABLE table ADD colname type;

删除字段语法如下:

ALTER TABLE table DROP colname;

以 student 表为例:

增加一个名为 age 的年龄字段,类型为 int,实现的 SQL 语句如下:

alter table student add age int;

输出结果:
在这里插入图片描述

使用 desc 命令查看表结构的变化:

desc student;

输出结果:

在这里插入图片描述

修改表字段,原属性都是以 student 为前缀。为保持命名风格的统一,现修改 age 字段为 student_ age,实现的 SQL 语句如下:

alter table student change age student_age int;

输出结果:
在这里插入图片描述

使用 desc 命令查看表结构的变化:

desc student;

输出结果:
在这里插入图片描述

change 只修改字段名,modify 修改的是字段的类型,其 SQL 语句如下:

alter table student modify student_age float;

输出结果:
在这里插入图片描述

使用 desc 命令查看表结构的变化:

desc student;

输出结果:
在这里插入图片描述

删除字段则比较简单,在 drop 后面跟上字段名即可,不用指出字段类型。现把添加的 student_age 字段给删除,其 SQL 语句如下:

alter table student drop student_age;

输出结果:
在这里插入图片描述

使用 desc 命令查看表结构的变化:

desc student;

输出结果:

在这里插入图片描述

删除表

在 MySQL 中,表的删除操作有三种,这里我们先说两种。分别是利用 DROP TABLE 语句实现表的删除,以及前面提过的 DELETE FROM table 。

两者的区别在于:

  • DROP TABLE 不仅仅删除表的内容、而且会删除表的结构并释放空间。通俗的讲就是,整个表没了,想操作这张表已不可能,只有重新去创建一个。
  • DELETE FROM table 删除的是表中的数据,就是清空表。系统需要一行一行的去删除,效率低下。

现有一张 student 表,表中数据如下结果所示:

select * from student;

输出结果:
在这里插入图片描述

使用 delete from student 对表进行删除操作,结果如下:

delete from student;

输出结果:
在这里插入图片描述

使用 show tables 命令,结果如下:

show tables;

输出结果:
在这里插入图片描述

结果显示 student 表还在,然后查看表中数据。

select * from student;

输出结果:
在这里插入图片描述

说明 delete from 语句确实只删除了数据。接下来使用 drop table 对表进行删除操作,其 SQL 语句如下:

drop table student;

输出结果:
在这里插入图片描述

使用 show tables 命令,结果如下:

show tables;

输出结果:
在这里插入图片描述

结果显示表已经删除,数据也丢失。

截断表

截断表的作用和 delete from 语句类似,删除表中所有的数据。截断表使用的语句是 TRUNCATE TABLE 。它和 delete from 区别在于,TRUNCATE TABLE 语句是数据定义语句,提交后不会产生回滚信息,所以它的速度更快。 其语法如下:

TRUNCATE TABLE table;

现有新建同样一张 student 表:

create table student
(student_id int,
student_name varchar(20),
student_specialty varchar(20)
);
insert into student
values
(1,'小章','大数据专业'),
(2,'小李','大数据专业'),
(3,'小蓝','计算机专业');

表中数据如下结果所示:

select * from student;

输出结果:
在这里插入图片描述

使用 TRUNCATE TABLE 后结果如下:

truncate table student;

输出结果:
在这里插入图片描述

查看表中数据,结果如下:

select * from student;

输出结果:
在这里插入图片描述

可以看出此时表仍然存在,和 delete from 实现的效果差不多,真正的差别只有当我们要清空的表数据量庞大的时候才能体现出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/608660.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

零基础入门网络安全必看的5本书籍(附书单pdf)

作为一个Java转行网络安全的过来人,我深知自学时的种种不易,同时也经常有粉丝朋友问我:刚入门应该怎么学、有哪些书籍推荐等问题,今天我就把我自己的学习书单分享给大家,希望对大家有帮助! 一、5本必读书籍…

JVM垃圾回收——对象进入老年代

目录 1、什么是大对象以及大对象对垃圾回收的影响 2、什么情况下对象会进入老年代 2.1 当创建对象的大小超过-XX:PretenureSizeThreshold的设定值 2.2 长期存活的对象将进入老年代 2.3 动态年龄判定 2.4 空间担保分配 什么是空间分配担保? 为什么要…

uploads靶场通关(1-11关)

Pass-01(JS校验) 看题目我们准备好我们的php脚本文件,命名为1.php 上传该php文件,发现上传失败 方法一:将浏览器的JavaScript禁用 然后就能上传了 方法二: 查看源码,发现只能上传以下形式的文…

【Docker】LXC所实现的隔离性、Linux Namespace等讲解

前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 📕作者简介:热…

域名解析异常有哪些办法?如何实现动态域名解析?

什么是域名解析? 域名解析就是把域名解析成一个ip地址,我们大多数人都喜欢记忆域名,但是机器只认识IP地址,只要这个IP地址对应相关域名,这就叫域名解析。 工作中常会遇到域名解析故障,比如访问站点对应的…

FPGA问答系列--Vivado Schematic中的实线和虚线有什么区别?

FPGA问答系列–Vivado Schematic中的实线和虚线有什么区别? 前言:本文章为FPGA问答系列,我们会定期整理FPGA交流群(包括其他FPGA博主的群)里面有价值的问题,并汇总成文章,如果问题多的话就每周…

ChatPPT一键制作PPT,效果拉满!

💧 C h a t P P T 一键制作 P P T ,效果拉满! \color{#FF1493}{ChatPPT一键制作PPT,效果拉满!} ChatPPT一键制作PPT,效果拉满!💧 🌷 仰望天空,妳我…

阿里云nginx配置https踩坑(配置完后访问显示无法访问此网站)

本人小前端一枚,最近在玩服务器部署自己的东西时踩了个坑!!! server {listen 443 ssl;server_name localhost;ssl_certificate 证书.com.pem;ssl_certificate_key 证书.com.key;#后台管理静态资源存放location / { #文件目…

2023-06-04 Unity ScriptableObject2——ScriptableObject 的应用

文章目录 一、配置数据二、复用数据三、多态特性的利用四、单例模式获取数据 一、配置数据 ​ ScriptableObject 数据文件非常适合用来做配置文件: 配置文件的数据在游戏发布之前定规则配置文件的数据在游戏运行时只会读出来使用,不会改变内容在 Unity…

MPS|如何学习电路设计?帮你快速上手

​电路设计是电子工程中的重要领域之一,涉及到电子元件的选择、电路的设计和分析、电路板的制作等多个方面。对于初学者来说,学习电路设计需要掌握一定的基础知识和技能,同时需要有耐心和实践经验。本文将从七个方面总结如何学习电路设计&…

Vue (9)

Vue (9) 文章目录 1. 消息订阅与发布1.1 总结1.2 修改 TodoList 案例 2. 为 TodoList 添加编辑功能3. $nextTick4. 过度与动画4.1 动画效果4.2 过度效果4.3 集成第三方动画4.4 总结4.5 修改 TodoList 案例 1. 消息订阅与发布 上文我们已经将全局事件总线学完了知道了全局事件总…

day6 -- 数据的分组和描述性统计

学习内容 描述性统计函数,包括平均值,最大/小值,行数,总和使用 GROUP BY子句和HAVING子句 对数据进行分组操作 描述性统计数函数 除了上面提到的聚合函数外,MySQL还提供了以下其他一些常用的聚合函数: – …

Python学习40:维吉尼亚密码——解密

凯撒密码的加密强度是很低的,只需简单地统计字频就可以破译。人们在单一凯撒密码的基础上扩展出多表密码,称为“维吉尼亚”密码。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪…

【环境搭建】一些奇奇怪怪的环境问题

【设备信息】我的设备是4070ti,支持cuda12.0,但是目前用的还是11.7 1)fatal error: cusparse.h: No such file or directory 因为cuda版本和改名的原因,这个在cuda版本中比较有效的解决办法是: sudo apt search libcusparse得到…

基于SpringBoot+Vue的自习室预订系统设计与实现

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…

C/C++开发,opencv读写图像函数详解

目录 一、cv::imread函数读取图像 1.1 imread函数 1.2 imread函数的参数解析 1.3 imread函数实践案例 1.4 编译及测试 二、cv::imwrite函数存储图像 2.1 cv::imwrite函数 2.2 imwrite函数参数解析 2.3 imwrite函数实践案例 2.4 编译及测试 一、cv::imread函数读取图像 1.1 im…

Lecture 5 Part of Speech Tagging

目录 POS application: Information Extraction 词性应用:信息提取 POS Open Class 开放类词性Problem of word classes: Ambiguity 词类问题:模糊性Tagsets 标记集Penn Treebank Tags:Derived Tags: 衍生标签Tagged Text Example 标记文本示例Reasons f…

Java 字符串基本操作

一、Java 字符串比较 1、equals用法 String类覆盖了Object类的equals()方法,并提供了自己的实现,它根据它们的内容比较两个字符串的相等性。 equals() 方法用于将字符串与指定的对象比较。 语法 public boolean equals(Object anObject)参数 anObje…

Dockerfile常用指令及其含义

编写dockerfile文件中常用指令: 指令说明FROM指明当前的镜像基于哪个镜像构建:LABEL标记镜像信息,添加元数据ARG定义构建镜像过程中使用的变量ENV指定环境变量VOLUME创建一个数据卷挂载点USER指定运行容器时的用户名或 UIDWORKDIR配置工作目录EXPOSE容器…

chatgpt赋能python:Python区分:为什么选择python?

Python区分:为什么选择python? Python是一种高级语言,一种功能强大且易于学习的编程语言。 它可用于各种领域,包括科学计算,Web开发和数据分析等。 Python的简单性和灵活性使其成为许多行业和开发者的首选编程语言。 …