-
主备环境可以支持主备从和一主多备两种模式。主备从模式下,备机需要重做日志,可以升主,而从备只能接收日志,不可以升主。而在一主多备模式下,所有的备机都需要重做日志,都可以升主。主备从主要用于大数据分析类型的系统,能够节省一定的存储资源。而一主多备提供更高的容灾能力,更加适合于大批量事务处理的OLTP系统。主备之间可以通过switchover进行角色切换,主机故障后可以通过failover对备机进行升主。初始化安装或者备份恢复等场景中,需要根据主机重建备机的数据,此时需要build功能,将主机的数据和WAL日志发送到备机。主机故障后重新以备机的角色加入时,也需要build功能将其数据和日志与新主拉齐。另外,在在线扩容的场景中,需要通过build来同步元数据到新节点上的实例。Build包含全量build和增量build,全量build要全部依赖主机数据进行重建,拷贝的数据量比较大,耗时比较长,而增量build只拷贝差异文件,拷贝的数据量比较小,耗时比较短。一般情况下,优先选择增量build来进行故障恢复,如果增量build失败,再继续执行全量build,直至故障恢复。为了实现所有实例的高可用容灾能力,除了以上对DN设置主备多个副本,还提供了其他一些主备容灾能力,比如CN(互为备份)、GTM(一主多备)、CM Sever(一主多备)以及ETCD(一主多备)等,使得实例故障后可以尽可能快地恢复,不中断业务,将因为硬件、软件和人为造成的故障对业务的影响降到最低,以保证业务的连续性。
-
业务倒是不中断,在openGauss日志里面发现大量的连接数据库端口的error,想请问一下怎么回事呢
-
一、前言数据去重在数据库中是比较常见的操作。复杂的业务场景、多业务线的数据来源等等,都会带来重复数据的存储。本文以GaussDB数据库为实验平台,将为大家详细讲解如何去重。二、数据去重应用场景数据库管理(含备份):在数据库中进行数据去重可以避免数据重复存储、备份,提高数据库的存储效率、降低备份的存储成本。数据集成:在数据集成的过程中,需要合并多个数据源的数据,去重可以避免重复的数据对合并结果的影响。数据分析(或挖掘):在进行数据分析或数据挖掘时,去重可以避免重复的数据对分析或挖掘结果的干扰,提高分析的准确性。电商平台:在电商平台上进行商品去重可以避免重复上架相同的商品,提高平台的用户体验。金融风控:在金融风控领域,去重可以避免重复的数据对风控模型的影响,提高风控的准确性。三、数据去重案例(GaussDB)实战业务场景 + GaussDB数据库1、示例场景描述以保险行业的客户信息除重为例,为防止坐席重复联系客户(容易造成客户投诉),需要将客户进行唯一身份识别。存在以下两种情况,需要将其识别成一个人(唯一),这时候就需要进行数据去重的动作。情况一:同一个客户有不同的来源渠道:客户即购买了寿险、又购买了产险(两个不同的来源系统);情况二:同一个客户多次回流:客户在同一个渠道多次购买(续保或者购买同一险种的不同产品)。2、定义重复数据通过“姓名+证件类型+证件号”将其识别为一个人,即只要这三个字段重复,就认为这些数据行为重复数据。 (当然还有更复杂的场景,例如,“姓名+证件类型+证件号+手机号+车牌号”等,本次不做详细介绍)。3、制定去重规则1)多选一 随机:根据去重规则,随机保留一条数据。优先级:根据去重规则 + 业务逻辑,保留优先需要的一条数据。例如优先保留“是否有房、是否有车”。2)多合一将重复数据合并成一条数据,合并规则根据业务逻辑确定。4、创建测试数据(GaussDB)客户信息字段主要包含“姓名、性别、出生年月日、证件类型、证件号、来源、是否有车、是否有房、婚姻状态、手机号、……”等信息。--创建客户信息表CREATE TABLE customer(name VARCHAR(20),sex INT,birthday VARCHAR(10),ID_type INT,ID_number VARCHAR(20),source VARCHAR(10),IS_car INT,IS_house INT,marital_status INT,tel_number VARCHAR(15));--插入测试数据INSERT INTO customer VALUES('张三','1','1988-01-01','1','61010019880101****','寿险','1','1','1','');INSERT INTO customer VALUES('张三','1','1988-01-01','1','61010019880101****','车险','1','0','1','');INSERT INTO customer VALUES('张三','1','1988-01-01','1','61010019880101****','','','','','186****0701');INSERT INTO customer VALUES('李四','1','1989-01-02','1','61010019890102****','寿险','1','1','1','');INSERT INTO customer VALUES('李四','1','1989-01-02','1','61010019890102****','车险','1','0','1','');INSERT INTO customer VALUES('李四','1','1989-01-02','1','61010019890102****','','','','','186****0702');--查看结果SELECT * FROM customer;Tip: 部分为INT类型的字段值取字典表的值,此处省。5、编写去重方法(GaussDB)以下示例中不包含过多的数据清洗、数据脱敏、业务逻辑等的处理,这些步骤均建议进行“前置”处理。本次示例重点描述去重的过程。1)随机保留:根据业务逻辑,随机保留一条记录。SELECT *FROM (SELECT *,ROW_NUMBER() OVER (PARTITION BY name,id_type,id_number ) as row_numFROM customer)WHERE row_num = 1;说明:ROW_NUMBER(): 从第一行开始,依次为每一行分配一个唯一且连续的编号。PARTITION BY col1[, col2...]: 指定分区的列,例如去重的键“姓名、证件类型、证件号码”。WHERE row_num = 1:取ROW_NUMBER()生成的编号1。2)按优先级保留:根据业务逻辑,优先保留有手机号的一条记录,如果有多条记录含有手机号或有没有手机号,则在此基础上随机保留。--保留含有手机号的记录行SELECT t.*FROM (SELECT *,ROW_NUMBER() OVER (PARTITION BY name,id_type,id_number ORDER BY tel_number ASC) as row_numFROM customer) tWHERE t.row_num = 1;说明:ROW_NUMBER(): 从第一行开始,依次为每一行分配一个唯一且连续的号码。PARTITION BY col1[, col2...]: 指定分区的列,例如去重的键“姓名、证件类型、证件号码”。ORDER BY col [asc|desc]: 指定排序的列。升序( ASC )排列指只保留第一行,而降序排列( DESC )则指保留最后一行。WHERE row_num = 1:取ROW_NUMBER()生成的编号1。3)合并保留:根据业务逻辑,合并完整性高、准确性高的字段信息。例如优先将含有手机号的记录行进行补齐,需要补齐的字段有“是否有车、是否有房、婚姻状况”,其取值是来源为“车险”的对应记录。--合并保留SELECT t1.name,t1.sex,t1.birthday,t1.id_type,t1.id_number,t1.source,t2.is_car,t2.is_house,t2.marital_status,t1.tel_numberFROM(SELECT t.*FROM (SELECT *,ROW_NUMBER() OVER (PARTITION BY name,id_type,id_number ORDER BY tel_number ASC) as row_numFROM customer) tWHERE t.row_num = 1) t1LEFT JOIN(SELECT *FROM customerWHERE source ='车险' and is_car IS NOT NULL AND is_house IS NOT NULL AND marital_status IS NOT NULL) t2ON t1.name =t2.nameand t1.id_type=t2.id_typeand t1.id_number=t2.id_number说明:t1 表是优先保留含有手机的记录行(去重),并作为主表,t2表是需要补齐的字段来源表。两张表通过“姓名+证件类型+证件号码”进行关联,然后合并需要的信息。6、附:全字段去重在数据库应用时,例如,重复误操作、数据翻倍等原因造成的全字段重复,此时也要进行去重。 那除了前面介绍的3种方式外,大家还可以使用关键字DISTINCT、UNION 进行去重,但需要注意其数据量及SQL 性能。 (大家自行测试)1) DISTINCT (假设全部有如下三个字段)2) UNION(假设全部有如下三个字段)四、数据去重效率提升建议最好的去重其实是在数据源头就进行“拦截”。当然了, 因业务流转也不可能完全避免,但是我们可以提高去重的效率:选择合适的去重算法根据数据集的特点和规模,选择适合的去重算法,可以大大提高去重效率。优化数据存储结构采用合适的数据存储结构,如哈希表、B+树等,可以加快数据的查找和比较速度,从而提高去重效率。并行化处理采用并行化处理的方式,将数据集分成多个子集,分别进行去重处理,最后合并结果,可以大大加快去重速度。使用索引加速查找对数据集中的关键字段建立索引,可以加速查找和比较速度,从而提高去重效率。前置过滤采用前置过滤的方式,先对数据集进行一些简单的筛选和处理,如去除空值、去除无效字符等,可以减少比较次数,从而提高去重效率。去重结果缓存(临时表)对去重结果进行缓存,可以避免重复计算,从而提高去重效率。不建议重写(备份)涉及一些分区表,等不建议直接将去重后的结果集重写到生产表,创建临时换成,或进行备份后操作。五、总结数据去重涉及到的面非常广,包括重复数据的发现、去重规则的定义、去重的方法与效率、去重的困难与挑战等等。但是,去重原则只有一个,那就是以业务为导向。根据业务需求去定义重复数据、制定去重规则和方案。在GaussDB数据库的使用过程,我们同样会遇到去重的场景。本文从应用背景、案例、去重方案等方面给大家做了介绍,欢迎测试、交流。——结束
-
videoGaussDB数据库提供的两地三中心异地容灾解决方案,可以实现数据库故障后快速恢复,能够保证极端灾难情况下数据的安全性和可用性,今天酷哥就带大家了解一下~
-
videoGaussDB数据库的透明数据加密技术,对数据库中存储的数据进行加密,以保护敏感信息免受未经授权的访问,从而保护数据。今天酷哥带大家了解一下~
-
videoGaussDB数据库支持数据分区。今天酷哥带大家了解一下GaussDB数据库的分区表,了解什么是数据库分区?分区有什么作用及优点?
-
一、前言层次递归查询是一种常见的SQL查询方式,特别是在一些层次化的数据存储结构中经常用到。本文主要以GaussDB数据库为实验平台,为大家讲解其使用方法。二、GuassDB数据库层次递归查询概念层次化结构可以理解为树状数据结构,由节点构成。举个简单的例子,如下图所示,由子节点向上查询根节点,或者由根节点遍历所有子节点:递归查询是指查询中需要多次调用自身的查询方式。在递归查询中,查询会反复地递归进入到一个子查询中,直到查询得到满足条件的结果或遍历完整个查询范围。递归查询在数据库领域中有着重要的应用。方便数据处理,简化开发代码。在GaussDB数据库中,递归查询可以通过使用 “select…start with…connect by…prior…” 和“WITH RECURSIVE”语法来实现。三、GaussDB数据库层次递归查询实验示例1、创建实验表--创建实验表CREATE TABLE area(a_code VARCHAR(10),a_name VARCHAR(10),p_a_code VARCHAR(10),a_level INT);--插入测试数据INSERT INTO area VALUES('610000','陕西省','0','1');INSERT INTO area VALUES('610100','西安市','610000','2');INSERT INTO area VALUES('610101','市辖区','610100','3');INSERT INTO area VALUES('610102','新城区','610100','3');INSERT INTO area VALUES('610103','碑林区','610100','3');INSERT INTO area VALUES('610104','莲湖区','610100','3');INSERT INTO area VALUES('610111','灞桥区','610100','3');INSERT INTO area VALUES('610112','未央区','610100','3');INSERT INTO area VALUES('610113','雁塔区','610100','3');INSERT INTO area VALUES('610114','阎良区','610100','3');INSERT INTO area VALUES('610115','临潼区','610100','3');INSERT INTO area VALUES('610116','长安区','610100','3');INSERT INTO area VALUES('610122','蓝田县','610100','3');INSERT INTO area VALUES('610124','周至县','610100','3');INSERT INTO area VALUES('610125','鄠邑区','610100','3');INSERT INTO area VALUES('610126','高陵区','610100','3');--查看初始化结果SELECT * FROM area;2、sys_connect_by_path(col, separator)描述:返回从根节点到当前行的连接路径。参数:col为在路径中显示的列名,支持类型为CHAR/VARCHAR/NVARCHAR2/TEXT的列,参数separator为路径节点之间的分隔符。返回值类型:text示例:--返回从根节点到当前行的连接路径SELECT *, sys_connect_by_path(a_name, '-') FROM area start with a_code ='610000' connect by prior a_code = p_a_code;3、connect_by_root(col)描述:返回当前行的根节点值。参数:col为输出列的名称。返回值类型:即为所指定列col的数据类型。示例:--返回当前行的根节点值。SELECT *, connect_by_root(a_name) FROM area start with a_code ='610000' connect by prior a_code = p_a_code;4、WITH RECURSIVE使用WITH RECURSIVE 关键字,:--使用WITH RECURSIVEWITH RECURSIVE t_area AS (SELECT a_level,a_code,p_a_code,a_name, a_name ::varchar(50) AS path FROM area WHERE p_a_code = '0'UNION ALLSELECT t2.a_level+1,t1.a_code,t1.p_a_code, t1.a_name,CONCAT(t2.path, ',', t1.a_name) ::varchar(50) AS path FROM area t1 JOIN t_area t2 ON t1.p_a_code=t2.a_code) SELECT * FROM t_area;示例说明:这个查询使用了递归表达式来遍历省级行政区域关系。表达式使用了两个 SELECT 语句:第一个 SELECT 语句选取了所有父级代码为0的行政区域信息,并将它们添加到临时表 t_area 中。它们的层级选取初始化的a_level级,并且它们的路径被设置为它们的行政区名a_name。这个 SELECT 语句是递归查询的起点。第二个 SELECT 语句连接了 area表和t_area表。它选取了area表中所有具有父级行政区,并连接到t_area表中已经存在的行政区。对于每个连接的行,它们的层级是父级的层级加1,并且它们的路径是父级的路径加上逗号和它们自己的行政区。查询结果返回t_area表中所有的行政区信息。(“::varchar(50)” 是创建实验表时的字符长度不够,需要重新定义,二是两个SELECT 语句使用 UNION ALL 连接,需要保持类型长度一致)。四、递归查询的优缺点1、优点递归查询能够简化应用程序代码,方便对数据结构的处理。在一些复杂的查询场景中,递归查询能够更快地得到结果。适用于各种类型的树形结构。2、缺点递归查询有时可能会产生很多次递归调用,导致性能下降。算法通常比其他方法更复杂,编写比较困难。不适合处理大型数据集。五、总结递归查询是一种非常实用的查询方法,在处理分层数据、树形数据等复杂查询场景中非常广泛。但是,在使用递归查询时需要注意一些问题:必须合理控制递归深度,防止过度递归。最好不要在递归查询中执行复杂的计算和组合操作,避免占用过多资源。避免在递归查询中使用ORDER BY操作,这会大大降低性能。在使用递归查询时,应该谨慎处理好死循环问题。同样的, 在使用GaussDB等数据库时,只要正确合理的应用递归查询,就可以更好地提高查询效率和应用性能。——结束
-
GaussDB处理并发的策略是什么?是锁行还是锁表,还是排队单线程执行
-
GaussDB最大支持多少个并发
-
GaussDB(for MySQL)跟直接用 MySQL 有什么区别吗?性能上两者差多少
-
GaussDB for mysql 能否支持将数据全量迁移至本地的mysql? 用什么工具?
-
GaussDB数据库的备份与恢复1.逻辑备份-gs_dumpgs_dump是一款用于导出数据库相关信息的工具,支持导出完整一致的数据库对象(数据库、模式、表、视图等)数据,同时不影响用户对数据库的正常访问。备份sql语句gs_dump是openGauss用于导出数据库相关信息的工具,用户可以自定义导出一个数据库或其中的对象(模式、表、视图等)。支持导出的数据库可以是默认数据库postgres,也可以是自定义数据库。(1)gs_dump工具由操作系统用户omm执行。(2)gs_dump工具在进行数据导出时,其他用户可以访问openGauss数据库(读或写)。(3)gs_dump工具支持导出完整一致的数据。例如,T1时刻启动gs_dump导出A数据库,那么导出数据结果将会是T1时刻A数据库的数据状态,T1时刻之后对A数据库的修改不会被导出(4)gs_dump支持将数据库信息导出至纯文本格式的SQL脚本文件或其他归档文件中。纯文本格式的SQL脚本文件:包含将数据库恢复为其保存时的状态所需的SQL语句。通过gsql运行该 SQL脚本文件,可以恢复数据库。即使在其他主机和其他数据库产品上,只要对SQL脚本文件稍作修改,也可以用来重建数据库。归档格式文件:包含将数据库恢复为其保存时的状态所需的数据,可以是tar格式、目录归档格式或自定义归档格式,详见下页表格。该导出结果必须与gs_restore配合使用来恢复数据库,gs_restore工具在导入时,系统允许用户选择需要导入的内容,甚至可以在导入之前对等待导入的内容进行排序。2.逻辑备份恢复数据库gsql -p 30100 db_hr -r -f /home/omm/XXX.sql3.物理备份(分布式集群验证)集中式单节点不支持该工具。GaussRoach.py工具是GaussDB(for openGauss)提供的用于备份和恢复的实用工具。可对整个数据库中的数据、WAL归档日志和运行日志进行备份。GaussRoach.py工具是一款数据库高可用性以及容灾恢复策略的备份管理工具。使用该工具可以备份恢复数据库;不仅可以备份到物理磁盘,也可以备份到OBS、NBU和EISOO。数据库级备份包含数据库静态配置文件(cluster_static_config),数据库动态配置文件(cluster_dynamic_config),数据节点DN(Datanode)及其备实例。备份需在集群主节点执行前提:集群级备份前,需要执行如下命令开启集群归档模式脚本路径:XXX/data/cluster/tools/script/GaussRoach.py开启归档命令:python3 GaussRoach.py -t config --archive=true -p开启归档:(1):全量备份{python3 GaussRoach.py -t backup --master-port 7000 --media-destination /home/omm/media --media-type DISK --compression-type 2 --compression-level 5 --metadata-destination /home/omm/meta}-t:Roach接口支持多种功能。指定该参数为backup,表示调用备份功能。-media-type:-备份所需的介质类型。NBUDisk(磁盘)EISOOOBSNAS–compression-type:压缩类型1:zlib2:lz4默认:–compression-type 2–compression-level压缩级别。0代表快速或无压缩。9代表慢速或最大压缩。说明值越小,压缩越快。值越大,压缩越好。表级备份不支持压缩。默认:–compression-level 5–media- destination:指定介质的目的备份路径。Disk(磁盘):NBU:样例策略EISOO:roachOBS:不生效NAS:挂载的NAS共享盘路径说明:使用备份数据库到EISOO时,确保已放入正确版本的libgaussdbmml.so使用备份数据库到NAS时,确保数据库实例上所有节点的指定路径挂载的是同一个NAS共享盘对于磁盘:–media-destination /home/cam/backup对于NBU:–media-destination Samplepolicy对于EISOO:roach对于NAS:–media-destination /home/cam/backup–metadata-destination:元数据文件位置。–metadata-destination /home/username对于数据库级备份,必须提供介质类型、目标介质和主代理端口,否则Roach工具会报错。当前版本不支持表级备份功能,包括单表备份和多表逻辑备份。数据库级备份前,请执行如下命令检查数据库运行状态,cluster_state为Normal时表示数据库正常运行,可以备份数据库。全量物理备份成功:备份类型需要根据传入的变量进行判断增量备份(需要在全量备份的基础上来做) 磁盘备份:去全量备份的磁盘目录看下全量备份的名称后填写{python3 GaussRoach.py -t backup --master-port 7000 --media-destination /home/omm/media --media-type DISK --compression-type 2 --compression-level 5 --metadata-destination /home/omm/meta --prior-backup-key 20221125_102746 --validate-prior-backups force}备份成功:查看物理全量备份集:{ python3 GaussRoach.py -t show --related-backup-keys --metadata-destination /home/omm/meta/ --backup-key 20221125_102746}查看物理增量备份集:{python3 GaussRoach.py -t show --related-backup-keys --metadata-destination /home/omm/meta/ --backup-key 20221125_104547}查看所有备份集(该命令无法确定备份是否有效){python3 GaussRoach.py -t show --all-backups --metadata-destination /home/omm/meta}停止物理备份:Roach也兼容使用python3 GaussRoach.py –t stop –F命令停止备份,有-F和无-F参数的执行结果相同。如果有一个全量备份和一个增量备份同时执行,那么stop操作会一起停止这两个备份任务。命令示例{python3 $GPHOME/script/GaussRoach.py -t stop}使用物理备份集恢复数据库:1.查看备份状态:{python3 GaussRoach.py -t show --all-backups --metadata-destination /home/omm/meta}2.执行恢复脚本:{python3 GaussRoach.py -t restore --clean --master-port 7000 --media-destination /home/omm/media --media-type DISK --backup-key 20221125_102746 --metadata-destination /home/omm/meta}查看集群状态:执行恢复脚本成功后,必须执行命令启动集群,否则集群无法启动{python3 GaussRoach.py -t start}问题记录:物理备份(Roach)失败[GAUSS-53403] :Parsing the configuration file.**[GAUSS-53403]** : Cluster balance check failedbackup cannot continue when the cluster is not balanceRoach operation backup failed.正在分析配置文件。[GAUSS-53403]:群集平衡检查失败当群集不平衡时,备份无法继续漫游操作备份失败。查看集群状态:balanced显示为NO,当前集群不平衡,不平衡原因可能是发生过切换或者其他原因导致。balanced:平衡状态。显示是否有数据库实例发生过主备切换而导致主机负载不均衡。Yes:表示数据库处于负载均衡状态。No:表示数据库未处于负载均衡状态。执行命令恢复数据库初始状态(目前为测试环境,生产不使用此命令){gs_om -t switch --reset}变为yes就可以进行备份了。作者:张欣
-
一、前言在构建数据仓库或做数据分析时,需要对原始数据的结构进行一定的处理,有时涉及到“行转列”,有时涉及到“列转行”,那么这两个转换的方式具体是什么,有什么差异,怎么实现,今天我们将以GaussDB数据库为例,给大家做一下讲解。二、简述1、行转列概念即将多行一列数据转为一行多列显示。通常转化后将某一列分类后的值作为新的列名,将此值对应的多行数据显示成一行。2、列转行概念即将一行多列数据转成多行一列显示。通常将转化后的列名为某一行中某一列的值,来识别原先对应的数据。三、GaussDB数据库的行列转换实验示例用一张学生成绩来举例:从老师的角度,在录入成绩时,每科老师都会单独录入每个学生的本科成绩。而从学生的角度,学生只关心自己各科的成绩分别是多少。所以如果把老师录入数据作为原始表,那么学生查看自己的成绩时就要用到行转列,如果让学生上报自己各科的成绩,然后老师去查对应学科的学生考试成绩时,那就是列转行了。1、行转列示例1)创建实验表(行存表)--创建实验表(行存表)CREATE TABLE grade(name VARCHAR(10),course VARCHAR(10),score INT);--初始化测试数据INSERT INTO grade VALUES ('张三','数学',80);INSERT INTO grade VALUES ('张三','英语',88);INSERT INTO grade VALUES ('张三','语文',95);INSERT INTO grade VALUES ('李四','数学',88);INSERT INTO grade VALUES ('李四','英语',70);INSERT INTO grade VALUES ('李四','语文',93);--查看结果SELECT * FROM grade ORDER BY course;2)静态行转列使用sum、case when的方式:--静态行转列SELECT name,sum(case when course = '数学' then score else 0 end) AS "数学",sum(case when course = '英语' then score else 0 end) AS 英语,sum(case when course = '语文' then score else 0 end) AS 语文FROM gradeGROUP BY name;3)行转列(结果值:拼接式)使用listagg within group:--行转列(结果值:拼接式)SELECT name, LISTAGG(score,',') WITHIN GROUP (ORDER BY course) FROM grade GROUP BY name;4)动态行转列(拼接SQL式)通过“listagg + 创建FUNCTION + VIEW”的方式实现--动态行转列(SQL拼接式)SELECT listagg(concat('SUM(CASE WHEN course = ''', course, ''' THEN score ELSE 0 END) AS "', course,'"'),',') WITHIN GROUP(ORDER BY 1) AS concat_text FROM (SELECT DISTINCT course FROM grade);--concat_text的结果:SUM(CASE WHEN course = '数学' THEN score ELSE 0 END) AS "数学",SUM(CASE WHEN course = '英语' THEN score ELSE 0 END) AS "英语",SUM(CASE WHEN course = '语文' THEN score ELSE 0 END) AS "语文"--创建一个函数。CREATE OR REPLACE FUNCTION fun_test()RETURNS VOIDLANGUAGE SQLAS $$ DECLAREs_sql text;rec record;BEGINs_sql := 'SELECT listagg(CONCAT(''SUM(CASE WHEN course = '''''', course, '''''' THEN score ELSE 0 END) AS "'', course, ''"'' ),'','' ) WITHIN GROUP(ORDER BY 1) AS concat_text FROM (SELECT DISTINCT course FROM grade);';EXECUTE s_sql INTO rec;s_sql := 'DROP VIEW IF EXISTS v_score; CREATE VIEW v_score AS SELECT name, ' || rec.concat_text || ' FROM grade GROUP BY name;';EXECUTE s_sql;END $$;--调用CALL fun_test();--查看执行结果select * from v_score;Tip:请注意SQL拼写时的单引号、双引号。2、列转行示例1)创建实验表(复用前面的测试数据)--创建实验表(复用前面的测试数据)CREATE TABLE grade1 ASSELECT name,sum(case when course = '数学' then score else 0 end) AS "数学",sum(case when course = '英语' then score else 0 end) AS 英语,sum(case when course = '语文' then score else 0 end) AS 语文FROM gradeGROUP BY name;--查看结果SELECT * FROM grade1;2)使用union all,将各科目(数学、英语、语文)整合为一列--使用union all,将各科目(数学、英语、语文)整合为一列SELECT * FROM(SELECT name, '数学' AS course, 数学 AS score FROM grade1union allSELECT name, '英语' AS course, 英语 AS score FROM grade1union allSELECT name, '语文' AS course, 语文 AS score FROM grade1)order by name;四、小结行列互转在一些数据库使用场景中经常用到,比如数据分析、数仓建设等。但不同的数据库软件有着不同处理方式,但是行列换的基本思路是一致的。本文主要是以GaussDB数据为平台,为大家做了简单的讲述 ,欢迎测试。——结束
-
一、前言在数据库中,SQL作为一种常用的数据库编程语言,扮演着至关重要的角色。SQL不仅可以用于创建、修改和查询数据库,还可以通过DROP、DELETE和TRUNCATE等语句来删除数据。这些语句是SQL语言中的最常用的命令,且它们有着不同的含义和使用场景。本文以GaussDB数据库为平台,将详细介绍SQL中DROP、TRUNCATE和DELETE等语句的含义、使用场景以及注意事项,帮助读者更好地理解和掌握这些常用的数据库操作命令。二、GaussDB的 DROP & TRUNCATE & DELETE 简述1、简述DROP语句可以删除整个表,包括表结构和数据;TRUNCATE语句则可以快速地删除表中的所有数据,但不删除表结构。DELETE语句可以删除表中的数据,不包括表结构;2、命令比对大类DROPTRUNCATEDELETESQL类型DDLDDLDML删除内容删除表的所有数据,包括表结构、索引和权限等删除表中所有数据,或指定分区的数据删除表的全部或部分(+条件)数据执行速度速度最快速度中等速度最慢Tip:在GaussDB数据库中,DROP是用于定义或修改数据库中的对象的命令之一。对象主要包括:库、模式、表空间、表、索引、视图、存储过程、函数、加密秘钥等,本次只针对其对表的操作。三、GaussDB的DROP TABLE命令及示例1、功能描述DROP TABLE的功能是用来删除已存在的Table。2、语法DROP TABLE [IF EXISTS] [db_name.]table_name;说明:SQL中加[IF EXISTS] ,可以防止因表不存在而导致执行报错。参数:db_name:Database名称。如果未指定,将选择当前database。table_name:需要删除的Table名称。3、示例以下示例演示DROP命令的使用,依次执行如下SQL语句:--删除整个表courseDROP TABLE IF EXISTS course--创建course表CREATE TABLE course(cid VARCHAR(10),cname VARCHAR(10),teid VARCHAR(10));--初始化数据INSERT INTO course VALUES('01' , '语文' , '02');INSERT INTO course VALUES('02' , '数学' , '01');INSERT INTO course VALUES('03' , '英语' , '03');--3条记录SELECT count(1) FROM course;--删除整个表DROP TABLE IF EXISTS course--查看结果,表不存在(表结构及数据不存在)SELECT count(1) FROM course;1)DROP TABLE,提示表不存在2)创建并初始化一张实验表3)DROP TABLE 执行成功4)查看执行结果四、GaussDB的TRUNCATE命令及示例1、功能描述从表或表分区中移除所有数据,TRUNCATE快速地从表中删除所有行。它和在目标表上进行无条件的DELETE有同样的效果,但由于TRUNCATE不做表扫描,因而快得多, 且使用的系统和事务日志资源少。在大表上操作效果更明显。TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。2、语法TRUNCATE [TABLE] table_name;或ALTER TABLE [IF EXISTS] table_name TRUNCATE PARTITION { partition_name | FOR ( partition_value [, ...] ) }参数:table_name:需要删除数据的Table名称。partition_name:需要删除的分区表的分区名称。partition_value:需要删除的分区表的分区值。3、示例1以下示例演示TRUNCATE命令的使用:--创建course表DROP TABLE IF EXISTS course;CREATE TABLE course(cid VARCHAR(10),cname VARCHAR(10),teid VARCHAR(10));--初始化数据INSERT INTO course VALUES('01' , '语文' , '02');INSERT INTO course VALUES('02' , '数学' , '01');INSERT INTO course VALUES('03' , '英语' , '03');--3条记录SELECT count(1) FROM course;--清空表TRUNCATE TABLE course;--或TRUNCATE course;--0条记录SELECT count(1) FROM course;1)创建实验表并初始化数据2)TRUNCATE TABLE执行成功3)查看执行结果4、示例2以下示例演示TRUNCATE命令的删除分区表数据--创建列表分区(LIST)DROP TABLE IF EXISTS orders;CREATE TABLE orders (id INT PRIMARY KEY,customer_id INT,order_date DATE,product_id INT,quantity INT) PARTITION BY LIST (customer_id) (PARTITION p1 VALUES (100),PARTITION p2 VALUES (200),PARTITION p3 VALUES (300),PARTITION p4 VALUES (400),PARTITION p5 VALUES (500));--插入测试数据INSERT INTO orders(id,customer_id,order_date,product_id,quantity)VALUES(1001,100,date'20230822',1,10);INSERT INTO orders(id,customer_id,order_date,product_id,quantity)VALUES(1002,100,date'20230822',2,20);INSERT INTO orders(id,customer_id,order_date,product_id,quantity)VALUES(1003,100,date'20230822',3,30);INSERT INTO orders(id,customer_id,order_date,product_id,quantity)VALUES(1004,200,date'20230822',4,40);--查看分区p1、p2的数据SELECT * FROM orders WHERE customer_id IN (100,200);--或--根据分区名称查询SELECT * FROM orders PARTITION(p2);--清空分区p1。ALTER TABLE orders TRUNCATE PARTITION p1;--或者--清空分区p2=200。ALTER TABLE orders TRUNCATE PARTITION for (200);--查看分区p1、p2的数据SELECT * FROM orders WHERE customer_id IN (100,200);1)创建实验表并初始化2)根据分区进行删数据五、GaussDB的DELETE命令及示例1、功能描述从指定的表里删除满足WHERE子句的行。如果WHERE子句不存在,将删除表中所有行,结果只保留表结构。2、注意事项不支持DELETE语句中使用LIMIT。应使用WHERE条件明确需要更新的目标行。不支持在单条SQL语句中,对多个表进行删除。DELETE语句中必须有WHERE子句,避免全表扫描。DELETE语句中禁止不应使用ORDER BY、GROUP BY子句,避免不必要的排序。如果需要清空一张表,建议使用TRUNCATE,而不是DELETE。TRUNCATE会创建新的物理文件,并在事务结束时将原文件物理删除,清空磁盘空间。而DELETE会将表中数据进行标记,直到VACCUUM FULL阶段才会真正清理磁盘空间。DELETE有主键或索引的表,WHERE条件应结合主键或索引,提高执行效率。DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一项。如果想保留标识计数值,请改用 DELETE3、语法DELETE FROM table_name [WHERE condition];参数:table_name:需要删除数据的Table名称。condition:用于判断哪些行需要被删除。4、示例复用前面的实验表:1)删除orders表中customer_id <200的所有数据:DELETE FROM orders WHERE customer_id <200;六、应用场景需要根据一定的业务条件删除数据时、且数据量、性能可控的情况下,可以考虑使用 DELETE。需要删除大批量数据时,同时要求速度快,效率高并且无需撤销时,可以使用 TRUNCATE。在企业级开发中,实际上都是进行逻辑删除(将数据进行“删除标识”处理)、而并不进行物理上的删除。在实际生产环境中,一般情况下删除业务处理(过渡表)中的数据。在实际企业开发、维护过程中,不管使用 DELETE、TRUNCATE还是DROP命令前,都要考虑数据的备份。七、小结在GaussDB等数据库中,DROP、TRUNCATE和DELETE均是常用的删除数据的命令。但在实际业务使用中,需要根据不同的需求进行准确的选择,但无论选择那种删数方式,都需要考虑数据安全性——重要的事情说三遍:备份!备份!备份!——结束。
-
一、前言SQL(结构化查询语言)是一种用于管理关系型数据库的标准语言。它允许用户通过使用SQL语言来操作数据库中的数据。而在SQL中,UNION是一个非常强大的功能,它可以将多个SELECT语句的结果合并成一个结果集。本文将以GaussDB数据库为例,介绍一下UNION 操作符的使用。二、GaussDB UNION/UNION ALL1、GaussDB UNION 操作符GaussDB UNION 操作符用于合并两个或多个 SELECT 语句的结果集。请注意,UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。2、语法定义1)UNION语法SELECT column1,column2,……FROM table1[WHERE condition]UNIONSELECT column1,column2,……FROM table2[WHERE condition]2)UNION ALL 语法SELECT column1,column2,……FROM table1[WHERE condition]UNION ALLSELECT column1,column2,……FROM table2[WHERE condition]说明:UNION在合并两个或多个集合时会执行去重操作,而UNION ALL则直接将两个或者多个结果集合并,不执行去重。 另外,执行去重会消耗大量的时间,因此,在一些实际应用场景中,如果通过业务逻辑已确认了两个集合不存在重重复数据时,可直接用UNION ALL 替代UNION,以便提升性能。三、GaussDB实验示例并初始化本文以GaussDB数据库为实验平台,1、创建实验表1)学生信息表student(ID、姓名、性别、城市)--创建学生信息表CREATE table student(sId VARCHAR(10) NOT NULL,sname VARCHAR(10) NOT NULL,ssex VARCHAR(10) NOT NULl,scity VARCHAR(10) NOT NULl);--初识化实验数据INSERT INTO student VALUES('s01' , '赵雷' , '男', 'XIAN');INSERT INTO student VALUES('s02' , '钱电' , '男', 'YUNNAN');INSERT INTO student VALUES('s03' , '孙风' , '男', 'NIXIA');INSERT INTO student VALUES('s04' , '李云' , '男', 'XIZANG');INSERT INTO student VALUES('s05' , '周梅' , '女', 'XINJIANG');INSERT INTO student VALUES('s06' , '吴兰' , '女', 'CHENGDU');INSERT INTO student VALUES('s07' , '郑竹' , '女', 'XIAN');INSERT INTO student VALUES('s08' , '张三' , '女', 'CHENGDU');--查看结果集SELECT * FROM student;2)教师信息表teacher(ID、姓名、性别、城市)--创建教师信息表CREATE table teacher(teid VARCHAR(10) NOT NULL,tname VARCHAR(10) NOT NULL,tsex VARCHAR(10) NOT NULL,tcity VARCHAR(10) NOT NULL);--初始化实验数据INSERT INTO teacher VALUES('t01' , '张磊', '男', 'XIAN');INSERT INTO teacher VALUES('t02' , '李强', '男', 'BEIJING');INSERT INTO teacher VALUES('t03' , '王刚', '男', 'XINJIANG');--查看结果集SELECT * FROM teacher;2、合并且除重(UNION)--获取学生和教师所属的城市,并按城市名称首字母升序排序。SELECT t.cityFROM (SELECT scity AS cityFROM studentUNIONSELECT tcity AS cityFROM teacher) tORDER BY t.city ASC;结果集如下截图,且城市数据不存在重复:3、合并不除重(UNION ALL)--获取所有学生和教师所属的城市,并按城市名称首字母升序排序。SELECT t.cityFROM (SELECT scity AS cityFROM studentUNION ALLSELECT tcity AS cityFROM teacher) tORDER BY t.city ASC;结果集如下截图,罗列了所有城市数据:4、合并带有WHERE子句SQL结果集(UNION ALL)--获取来自'XIAN'的学生和教师的所有信息,并按学生和教师的编号升序排序。SELECT t.*FROM(SELECT Sid AS id,Sname AS name,Ssex AS sex,Scity AS cityFROM student WHERE Scity='XIAN'UNION ALLSELECT Tid AS id,Tname AS name,Tsex AS sex,Tcity AS cityFROM teacher WHERE Tcity='XIAN') tORDER BY t.id ASC;结果集如下截图,罗列了'XIAN'的学生和教师的所有信息:5、业务逻辑除重后合并(UNION ALL)在一些业务场景下,比如上游系统提供的两张表或者多张表之间互相不会存重复数据,且自身也不存在重复数据,则为了提升合并时SQL性能、减少SQL执行时间,则选择UNION ALL操作符。四、GaussDB UNION常见错误1、“each UNION query must have the same number of columns”解决思路:根据提示查看两个表的表结构,看字段数量是否一支。2、“UNION types timestamp without time zone and text cannot be matched”解决思路:根据提示查看两个表的表结构,看字段类型是否一致。五、小结在实际业务场景中,无论选择GaussDB数据库,还是其他关系型数据库,在使用UNION和UNION ALL 时,都需要注意以下几点:左右两侧的SQL字段数量和字段类型需要保持一致;业务需求是否需要考虑数据除重(合并前除重还是合并时除重);根据表中数据量的大小,需要对SQL的执行效率进行评估,从而考虑是否需要选择临时表进行过渡后再合并;需要考虑SQL编写的复杂度,不能为了写SQL而写SQL,需要结合业务需求进行选择。——结束
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签