[数据库/SQL] 浅谈DDL、DSL、DCL、DML、DQL
笔记哥 /
04-28 /
42点赞 /
0评论 /
370阅读
# 概念辨析:SQL、DQL、DML、DDL、DCL
- `SQL`(Structure Query Language, 结构化查询语言)语言是数据库的核心语言。
- `SQL`的发展是从1974年开始的,其发展过程如下:
>
> - 1974年 由Boyce和Chamberlin提出,当时称`SEQUEL`。
> - 1976年 `IBM`公司的Sanjase研究所在研制RDBMS SYSTEM R时改为`SQL`。
> - 1979年 `ORACLE`公司发表第一个基于SQL的商业化RDBMS产品。
> - 1982年 `IBM`公司出版第一个RDBMS语言`SQL/DS`。
> - 1985年 `IBM`公司出版第一个RDBMS语言`DB2`。
> - 1986年 美国国家标准化组织`ANSI`宣布`SQL`作为**数据库工业标准**。
>
>
- `SQL`是一个**标准的数据库语言**,是面向集合的描述性非过程化语言。
>
>
> 它功能强,效率高,简单易学易维护。
>
- 然而SQL语言由于以上**优点**,同时也出现了这样一个**问题**:
>
>
> 它是**非过程性语言**,即大多数语句都是**独立执行**的,与**上下文**无关,而**绝大部分应用**都是一个完整的过程,显然用SQL完全实现这些功能是很困难的。
>
# SQL语言的分类
- `SQL`语言共分为四大类:
>
> - 数据定义语言DDL
> - 数据控制语言DCL
> - 数据操纵语言DML
> - 数据查询语言DQL
>
>

## 数据定义语言DDL
- **数据定义语言**(Data Definition Language,DDL),**用于定义和管理 SQL 数据库中的所有对象的语言**,用来创建数据库中的各种对象:表、视图、索引、同义词、聚簇等
>
>
> 如:CREATE TABLE / VIEW / INDEX / SYN / CLUSTER| 表 视图 索引 同义词 簇。
>
> DDL操作是隐性提交的!不能rollback
>
```txt
CREATE - to create objects in the database 创建
ALTER - alters the structure of the database 修改
DROP - delete objects from the database 删除
TRUNCATE - remove all records from a table, including all spaces allocated for the records are removed TRUNCATE TABLE [Table Name]。
下面是对Truncate语句在MSSQLServer2000中用法和原理的说明:
Truncate table 表名 速度快,而且效率高
因为: TRUNCATE TABLE 在功能上与不带 WHERE 子句的 DELETE 语句相同:二者均删除表中的全部行。
但 TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少。
DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一项。
TRUNCATE TABLE 通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。
TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用 DELETE。
如果要删除表定义及其数据,请使用 DROP TABLE 语句。
对于由 FOREIGN KEY 约束引用的表,不能使用 TRUNCATE TABLE,而应使用不带 WHERE 子句的 DELETE 语句。由于 TRUNCATE TABLE 不记录在日志中,所以它不能激活触发器。
TRUNCATE TABLE 不能用于参与了索引视图的表。
COMMENT - add comments to the data dictionary 注释
GRANT - gives user’s access privileges to database 授权
REVOKE - withdraw access privileges given with the GRANT command 收回已经授予的权限
```
## 领域特定语言DSL
### DSL的定义?
- `DSL`(`Domain Specific Language`)是针对**某一领域**,**具有受限表达性**的一种**计算机程序设计语言**。
>
>
> 常用于**聚焦指定的领域或问题**,这就要求 DSL 具备强大的表现力,同时在使用起来要简单。
>
> 说到`DSL`,大家也会自然的想到**通用语言**(如`Java`、`C`等)。
>
### 为什么没有一种语言同时 兼具『简洁』和『业务表达』能力呢?
- 从**信息论**本质上来讨论这个问题,**每个语言的程序都可以抽象为一个字符串**,**每个字符串由有限数量的合法字符组成**。
>
>
> 它在**运行时**会实现某个功能,因而可以看作是一种**需求的信源编码**。
>
> **每种需求**可以映射到**一个或多个正确的程序**,但**一个程序肯定只对应到一种需求**,因而**程序包含的信息熵**不低于**需求的信息熵**。
>
> 而**程序**中不仅仅需要描述**需求的信息**,还需要包含: 可读性、辩识度;如果是**静态语言**还需要静态检查等**额外信息**。
>
- 这里也可以看出来,为什么DSL是**特定领域的语言**了。
### DSL分类
- 最常见的分类方法是按照DSL的**实现途径**来分类。
- 马丁·福勒曾将`DSL`分为**内部**和**外部**两大类,他的分类法得到了绝大多数业界人士的认可和沿袭。
>
>
> 内部与外部之分取决于`DSL`**是否将一种现存语言**作为**宿主语言**,在其上构建自身的实现。
>
#### 内部DSL := 内嵌式DSL
- 内部DSL,也称**内嵌式DSL**。因为它们的实现嵌入到宿主语言中,与之合为一体。
- 内部DSL将**一种现有编程语言**作为**宿主语言**,基于其设施建立专门面向特定领域的各种语义。
>
>
> 例如:Kotlin DSL、Groovy DSL等;
>
#### 外部DSL := 独立 DSL
- 外部DSL,也称**独立DSL**。
>
>
> 因为它们是从零开始建立起来的独立语言,而不基于任何现有宿主语言的设施建立。
>
> 外部DSL是从零开发的DSL,在词法分析、解析技术、解释、编译、代码生成等方面拥有独立的设施。
>
- 开发外部DSL近似于从零开始实现一种拥有独特语法和语义的全新语言。
>
>
> 构建工具make 、语法分析器生成工具YACC、词法分析工具LEX等都是常见的外部DSL。
>
> 例如:正则表达式、XML、SQL、JSON、 Markdown等;
>

### DSL示例
#### 内部DSL
- HTML: 通过自然语言编写
>
>
> 在`Groovy`中,通过DSL可以用易读的写法生成XML
>
```java
import groovy.xml.MarkupBuilder
def s = new StringWriter()
def xml = new MarkupBuilder(s)
xml.html{
head{
title("Hello")
script(ahref:'https://xxxx.com/vue.js')
}
body{
p("Excited")
}
}
println s.toString()
```
>
>
> 最后将生成
>
```csharp
Excited
```
>
>
> 这里相对于Java这样的动态语言,最为不同的就是xml.html这个并不存在的方法居然可以通过**编译**并**运行**
>
> 它内部重写了`invokeMethod`方法,并进行**闭包遍历**,少写了许多`POJO`对象,效率更高。
>
#### 外部DSL
- 以`plantUML`为例,**外部DSL**不受限于**宿主语言**的语法,对用户很友好,尤其是对于不懂宿主语言语法的用户。
- 但外部DSL的自定义语法需要有配套的语法分析器。
>
> - 常见的语法分析器有:YACC、ANTLR等。
>
>
>
>
> >
> > - [ANTLR - 博客园/千千寰宇](https://www.cnblogs.com/johnnyzen/p/18849096)
> >
> >
>
>

### DSL(领域特定语言) & DDD(领域驱动)
- `DDD`和`DSL`的融合有三点:
>
> - 面向领域;
> - 模型的组装方式;
> - 分层架构演进;
>
>
- `DSL` 可以看作是在**领域模型**之上的一层**外壳**,可以显著增强领域模型的能力。

- 它的价值主要有2个:
>
> - 提升了开发人员的生产力
> - 增进了开发人员与领域专家的沟通
>
>
>
>
> >
> >
> > **外部 DSL** 就是对领域模型的一种组装方式。
> >
>
>

### DSL不是银弹
- 前开篇也提到了,在信息量不变的情况下,代码行数越短,它的“潜规则”信息量就越多,那么如何排查?如何定位?如何扩展?成为一个好的DSL需要考量的点。
- 设计良好的DSL难点在于:
>
> - DSL只是一种声明式的编程语言,无法承载大量业务。
> - DSL语句与编译生成的“字节码”的过程是黑盒的,不但对内部工作不明朗,如果报错的话,不但堆栈行数无法与源码对应上,而且无法“断点”或者“日志”。
> - DSL对设计者要求高,需要会一个领域有通透的理解,设计时要克制『增加各种特性』,DSL还要文档齐全,支撑充分,甚至要开源以帮助使用者定位。
>
>
### 有哪些DSL工具
- 上节中提到,DSL分为内部和外部。
>
>
> 由于外部DSL需要自己编写分析器,所以笔者使用**内部DSL**实现。
>
- 从之前收集的大量资料中,调研到有两种比如轻量实现DSL的方式。
>
> - 第一种:使用`Groovy`脚本语言的元编程特性,天然支持DSL的下定义,而且兼容Java调用,生成的class更容易被JVM优化,执行性能上不会有太多损失。
>
>
>
> - 第二种:使用`Jetbrains MPS`,开发基于java base的内部DSL。支持快速修复、智能提示、语法检查等。
>
>
>
>
> >
> >
> > https://www.jetbrains.com/zh-cn/mps/
> >
>
>
- 第三种: ANTLR
>
>
>
> >
> > - [ANTLR - 博客园/千千寰宇](https://www.cnblogs.com/johnnyzen/p/18849096)
> >
> >
>
>
### 案例:Groovy实战DSL
>
>
> 参见: [一杆到底:DSL 领域特定语言 - Aliyun](https://developer.aliyun.com/article/885778)
>
### 案例:ANTLR 【TODO】
>
>
> 参见: [ANTLR - 博客园/千千寰宇](https://www.cnblogs.com/johnnyzen/p/18849096)
>
## 数据控制语言DCL
- 数据控制语言(Data Control Language statements, DCL),用来授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等。如:
>
> - 1. GRANT:授权。
> - 1. ROLLBACK [WORK] TO [SAVEPOINT]:回退到某一点。回滚---ROLLBACK回滚命令使数据库状态回到上次最后提交的状态。其格式为:SQL>ROLLBACK;
> - 1. COMMIT [WORK]:提交。在数据库的插入、删除和修改操作时,只有当事务在提交到数据库时才算完成。在事务提交前,只有操作数据库的这个人才能有权看到所做的事情,别人只有在最后提交完成后才可以看到。提交数据有三种类型:显式提交、隐式提交及自动提交。下面分别说明这三种类型。
>
>
- (1) 显式提交
用`COMMIT`命令直接完成的提交为显式提交。其格式为:`SQL>COMMIT`
- (2) 隐式提交
用SQL命令间接完成的提交为隐式提交。这些命令是:ALTER,AUDIT,COMMENT,CONNECT,CREATE,DISCONNECT,DROP,EXIT,GRANT,NOAUDIT,QUIT,REVOKE,RENAME。
- (3) 自动提交
若把`AUTOCOMMIT`设置为`ON`,则在插入、修改、删除语句执行后,系统将自动进行提交,这就是自动提交。
>
>
> 其格式为:`SQL> SET AUTOCOMMIT ON;`
>
```txt
COMMIT - save work done 提交
SAVEPOINT - identify a point in a transaction to which you can later roll back 保存点
ROLLBACK - restore database to original since the last COMMIT 回滚
SET TRANSACTION - Change transaction options like what rollback segment to use 设置当前事务的特性,它对后面的事务没有影响.
```
## 数据操纵语言DML
- 数据操纵语言(Data Manipulation Language, DML),**SQL中处理数据等操作**统称为**数据操纵语言**。
- 主要有三种形式:
1. 插入:INSERT
2. 更新:UPDATE
3. 删除:DELETE
```txt
SELECT - retrieve data from the a database 查询
INSERT - insert data into a table 添加
UPDATE - updates existing data within a table 更新
DELETE - deletes all records from a table, the space for the records remain 删除
CALL - call a PL/SQL or Java subprogram
EXPLAIN PLAN - explain access path to data Oracle RDBMS执行每一条SQL语句,都必须经过Oracle优化器的评估。
所以,了解优化器是如何选择(搜索)路径以及索引是如何被使用的,对优化SQL语句有很大的帮助。
Explain可以用来迅速方便地查出对于给定SQL语句中的查询数据是如何得到的即搜索路径(我们通常称为Access Path)。
从而使我们选择最优的查询方式达到最大的优化效果。
LOCK TABLE - control concurrency 锁,用于控制并发
```
## 数据查询语言DQL
- 数据查询语言DQL(Data Query Language)
> - 基本结构是由SELECT子句,FROM子句,WHERE子句组成的查询块:
> `SELECT <字段名表>FROM <表或视图名>WHERE <查询条件>`
本文来自投稿,不代表本站立场,如若转载,请注明出处:http//www.knowhub.vip/share/2/2940
- 热门的技术博文分享
- 1 . ESP实现Web服务器
- 2 . 从零到一:打造高效的金仓社区 API 集成到 MCP 服务方案
- 3 . 使用C#构建一个同时问多个LLM并总结的小工具
- 4 . .NET 原生驾驭 AI 新基建实战系列Milvus ── 大规模 AI 应用的向量数据库首选
- 5 . 在Avalonia/C#中使用依赖注入过程记录
- 6 . [设计模式/Java] 设计模式之工厂方法模式
- 7 . 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
- 8 . SQL 中的各种连接 JOIN 的区别总结!
- 9 . JavaScript 中防抖和节流的多种实现方式及应用场景
- 10 . SaltStack 远程命令执行中文乱码问题
- 11 . 推荐10个 DeepSeek 神级提示词,建议搜藏起来使用
- 12 . C#基础:枚举、数组、类型、函数等解析
- 13 . VMware平台的Ubuntu部署完全分布式Hadoop环境
- 14 . C# 多项目打包时如何将项目引用转为包依赖
- 15 . Chrome 135 版本开发者工具(DevTools)更新内容
- 16 . 从零创建npm依赖,只需执行一条命令
- 17 . 关于 Newtonsoft.Json 和 System.Text.Json 混用导致的的序列化不识别的问题
- 18 . 大模型微调实战之训练数据集准备的艺术与科学
- 19 . Windows快速安装MongoDB之Mongo实战
- 20 . 探索 C# 14 新功能:实用特性为编程带来便利