• [技术解读] openGauss 5.0.0企业版一主一备安装部署
     本篇投稿作者:赵锋背景 最近项目在使用openGauss数据库,当初选择时综合考虑华为大厂背景、国产开源、免费使用,以及我也拥有openGauss的HCIA证书,对openGauss较为熟悉,所以选择openGauss。两年前初次部署选的是2.1.0版本,目前社区已经出了5.1.0版本,作为项目使用也得替换为LTS版本,所以此次进行5.0.0企业版的安装。且通过一主一备的部署方式增加数据的可靠性。#印象深刻的实战经历 题外话:关于openGauss的版本号 openGauss版本号采用点分位命名规则(X.Y.Z)模式,其中X.0.0表示LTS版本,X.Y.0表示preview版本,Z表示补丁版本。 LTS版本发布间隔周期1年,社区提供3年维护支持。preview版本发布间隔周期1年,社区提供0.5年维护支持。  一、环境准备 1. 华为云购买两台ECS 如图:一主一备部署需要准备两台服务器分别作为主机和备机,操作系统仍然用openEuler 20.03 LTS,CPU选择的制式是X86。说明:内存最少需要16G。  Tips:官网要求最小内存32G,考虑到卡里余额,我只买了4核16G的机器,也可以安装成功。  1.1查看openEuler版本,操作系统版本及CPU的制式是基础 [root@ecs-caa2 ~]# cat /etc/openEuler-release  openEuler release 20.03(LTS)   1.2查看CPU模式  lscpu  Architecture:       x86_64  CPU op-mode(s):        32-bit, 64-bit 注意:X86的CPU,下载安装包的时候记得要下载X86的。如果下了arm架构的会有其他莫名其妙的报错。相信不会有人犯这样的错误除了我。  1.3操作系统环境准备 设置字符集参数(主备机都要执行) vi/etc/profile export LANG=en_US.UTF-8 source/etc/profile 修改Python版本(主备机都要执行) cd /usr/bin mv python python.bak ln -s python3 /usr/bin/python python -V 下载安装包(创建目录和修改目录权限需要主备机都执行,下载和解压安装包只需要在主机执行) 创建目录:mkdir/opc/software/openGauss/ 下载安装包 x86:wgethttps://opengauss.obs.cn-south-1.myhuaweicloud.com/5.0.0/x86_openEuler/openGauss-5.0.0-openEuler-64bit-all.tar.gz 解压安装包 tar -zxvf openGauss-5.0.0-openEuler-64bit-all.tar.gztar zxvf openGauss-5.0.0-openEuler-64bit-om.tar.gz 修改目录权限:chmod 755 -R /opt/software chmod 755 -R /opt/software/openGauss/script/ 修改yum源:(主备机都要执行) cd /etc/yum.repos.dNAME="openEuler" 上传文件:openEulerOS.repo到该目录下。 执行命令:yum clean all 执行命令:yum makecache (执行命令的服务器需要有外网访问的权限)安装依赖包:(主备机都要执行) 1.Expect:  yum install expect 2.其他  yum install -y bzip2 bzip2-devel curl libaio libaio-devel readline-devel    yum install libaio* -y 关防火墙(主备机都要执行) vim /etc/selinux/config SELINUX=disabled 重启系统:reboot 检查:systemctl status firewalld 若仍然是active(running)状态,则执行下面两个命令: systemctl disable firewalld.service systemctl stop firewalld.service 再次检查:systemctl status firewalld  1)关共享内存 (主备机都要执行) swapoff -a 2)关闭RemoveIPC(主备机都要执行),修改“RemoveIPC”值为“no”。  vi /etc/systemd/logind.conf 3)检查hostname与/etc/hostname是否一致(主备机都要执行) Hostname  cat /etc/hosts cat /etc/hostname 注意hostname文件中不能有其他内容,之前包含了注释的localhost导致报错如下: [FAILURE] bogon: [GAUSS-51248] : The hostname(bogon) may be not same with hostname(/etc/hostname) Command: "pssh -s -H bogon 'cat /etc/hostname'". Error: bogon #localhost.localdomain [FAILURE] bogon2: [GAUSS-51248] : The hostname(bogon) may be not same with hostname(/etc/hostname) Command: "pssh -s -H bogon 'cat /etc/hostname'". Error: Bogon 红框中的内容删除掉后执行预安装成功。 注意除了下载安装包以外,其余关于环境的准备,需要在主备两台机器都进行操作。  2. 集群配置XML文件准备: 最主要的工作量就在准备XML文件了(我实验的路径是按照默认,具体项目可根据实际情况调整文件路径)。  2.1集群参数配置: <?xml version="1.0" encoding="utf-8"?><ROOT> <CLUSTER> <PARAM name="clusterName" value="opengauss" /> <PARAM name="nodeNames" value="db1,db2"/> <PARAM name="gaussdbAppPath" value="/opt/huawei/install/app" /> <PARAM name="gaussdbLogPath" value="/var/log/omm" /> <PARAM name="tmpMppdbPath" value="/opt/huawei/tmp"/> <PARAM name="gaussdbToolPath" value="/opt/huawei/install/om" /> <PARAM name="corePath" value="/opt/huawei/corefile"/> <PARAM name="backIp1s" value="192.168.197.18,192.168.197.19"/> </CLUSTER>2.2主机参数配置: <DEVICE sn="db1"> <PARAM name="name" value="db1"/> <PARAM name="azName" value="AZ1"/> <PARAM name="azPriority" value="1"/> <PARAM name="backIp1" value="192.168.197.18"/> <PARAM name="sshIp1" value="192.168.197.19"/> <!-- dn --> <PARAM name="dataNum" value="1"/> <PARAM name="dataPortBase" value="15400"/><!--这个参数很关键,和单机版有明显区别,其中红色字体的为需要增加的内容,配置备机的数据目录--> <PARAM name="dataNode1" value="/opt/huawei/install/data/dn,db2,/opt/huawei/install/data/dn"/> <PARAM name="dataNode1_syncNum" value="0"/></DEVICE>2.3备机参数配置: <DEVICE sn="bogon2"> <PARAM name="name" value="db2"/> <PARAM name="azName" value="AZ1"/> <PARAM name="azPriority" value="1"/> <PARAM name="backIp1" value="192.168.197.19"/> <PARAM name="sshIp1" value="192.168.197.19"/> <!-- dn --> </DEVICE><!--和单机版相比,不用配置备机的dbnode信息,如果配置了,则安装完成后,备机也会处于主机状态-->配置完后的xml文件放在openGauss/xmlfile文件夹下面。[root@bogon xmlfile]# ls /opt/software/openGauss/xmlfile/cluster_config.xml需要赋予xmlfile文件夹权限:chmod 755 -R /opt/software/openGauss/xmlfile/NAME="openEuler"二、预安装 1. 执行preinstall命令: ./script/gs_preinstall -U omm -G dbgrp -X /opt/software/openGauss/xmlfile/cluster_config.xml Preinstall过程中会需要几次提示和输入几次密码,按照提示输入响应密码并妥善记录。 2. 提示输入omm用户的密码:3. 再次输入omm用户的密码:    Preinstall成功结束后会有如下提示:    4. 一些安装过程由于粗心遇到的小问题,根据提示修改后重新执行即可。  如果xml文件名或者文件夹错误,则会报错如下:     如果xml文件里面的hostname和实际的hostname不一致,则会报错如下:    三、安装 1. 安装命令需要用omm用户执行,先切换至omm; su omm gs_install -X /opt/software/openGauss/xmlfile/cluster_config.xml  2. 如果没有赋予xmlfile文件夹的权限,则会报错: [GAUSS-50236]:the /opt/software/openGauss/xmlfile/cluster_config.xml does not existor the permission on the upper-layer directory is insufficient.3. 赋予权限: chmod 755 -R /opt/software/openGauss/xmlfile/ chmod 755 -R /opt/software/openGauss/script赋予权限时要用root用户,赋予后重新切换为omm用户进行安装。  4. 安装过程需要输入数据库密码,输入并妥善记录。   5. 安装完成后会有如下提示:   四、启动和集群状态检查 1. 启动:gs_om -t restart 2. 集群状态检查:gs_om -t status --detail   五、主备切换 1. 登录备机,查看集群状态 gs_om -t status --detail 2. 备机升主,更新配置文件 gs_ctl switchover -D /opt/huawei/install/data/dn  3. 重新查看集群状态,发现主备机已经互相切换。   六、一些其他操作 修改端口号:由于2.0默认端口号是26000,我安装完成后把端口号又改为了26000。修改postgresql.conf文件和pg_hba.conf文件的部分配置,以便可以远程连接数据库,注意修改完后需重启集群才生效。  七、本文作者 本文内容来自于数据库领域资深技术专家赵锋老师,OpenHarmony WEB3 TSG成员。先后就职于大唐电信、华为和软通动力,拥有多年项目开发,设计和优化运维经验。在数据库领域摸爬滚打多年,经历过Oracle,DB2和SQL Server的时代,国产数据库崛起后,对华为GaussDB系列数据库进行了深入学习和研究,获得华为GaussDB HICA、GaussDB HCIP、GaussDB HICA SI以及openGauss HCIA证书。致力于国产开源数据库在业务项目中的实践和应用。 
  • [技术解读] openGauss通过VIP实现的故障转移
    本篇投稿作者:IT邦德前言本文详细阐述了openGauss通过CM管理,实现的VIP故障转移全过程。欢迎小伙伴一起探讨。1.前言❝随着目前信创产业的发展,应项目的需求,通过高可用的方式实现数据库的故障转移。于是花了点时间研究,通过CM管理,实现了VIP故障转移全过程,在经历了这次故障转移之后,我觉得有必要分享我在此过程中获得的见解2.CM管理两节2.1 何为CM❝CM(Cluster Manager)是一款数据库管理模块。支持自定义资源监控,提供了数据库主备的状态监控、网络通信故障监控、文件系统故障监控、故障自动主备切换等能力。提供了丰富的数据库管理能力,如节点、实例级的启停,数据库实例状态查询、主备切换、日志管理等。提供了通过REST接口远程查询和接收集群状态的能力。❞2.2 CM的特点 高可用:CM易用性提升   支持一键式关闭CM集群服务;  支持和内核的安装部署解耦;  支持按事件调用用户自定义脚本;  支持CM组件单独升级,增强数据库集群可靠性;  CM根据配置信息,支持用户自定义组件的监控和管   需要注意的是,一主一备模式下,CM只支持基本的安装,启停,检测能力,其他功能不支持。                                                                           高可用:CM支持VIP管理  通过VIP可以直接找到主机,连接重连更准更快(毫秒级别);  支持主机故障,CM选出新主时,VIP漂移到新的主上;  当出现双主时,依然可以通过VIP访问到唯一一个主机,降低了双主丢数据的风险。 2.3 XML配置文件<?xml version="1.0" encoding="UTF-8"?><ROOT> <!-- openGauss整体信息 --> <CLUSTER> <!-- 数据库名称 --> <PARAM name="clusterName" value="opengauss" /> <!-- 数据库节点名称(hostname) --> <PARAM name="nodeNames" value="opengauss51m,opengauss51b" /> <!-- 数据库安装目录,与数据库所需其它路径相互独立,没有包含关系--> <PARAM name="gaussdbAppPath" value="/openGauss/app" /> <!-- 日志目录--> <PARAM name="gaussdbLogPath" value="/openGauss/log/omm" /> <!-- 临时文件目录--> <PARAM name="tmpMppdbPath" value="/openGauss/tmp"/> <!-- 数据库工具目录--> <PARAM name="gaussdbToolPath" value="/openGauss/om" /> <!-- 数据库core文件目录--> <PARAM name="corePath" value="/openGauss/corefile"/> <!-- 节点IP,与数据库节点名称列表一一对应 --> <PARAM name="backIp1s" value="192.168.6.11,192.168.6.12"/> </CLUSTER> <!-- 每台服务器上的节点部署信息 --> <DEVICELIST> <!-- 节点1上的部署信息 --> <DEVICE sn="opengauss51m"> <!-- 节点1的主机名称 --> <PARAM name="name" value="opengauss51m"/> <!-- 节点1所在的AZ及AZ优先级 --> <PARAM name="azName" value="AZ1"/> <PARAM name="azPriority" value="1"/> <!-- 节点1的IP,如果服务器只有一个网卡可用,将backIP1和sshIP1配置成同一个IP --> <PARAM name="backIp1" value="192.168.6.11"/> <PARAM name="sshIp1" value="192.168.6.11"/> <!-- cm主 --> <PARAM name="cmsNum" value="1"/> <PARAM name="cmDir" value="/openGauss/cm"/> <PARAM name="cmServerPortBase" value="15300"/> <PARAM name="cmServerListenIp1" value="192.168.6.11,192.168.6.12"/> <PARAM name="cmServerHaIp1" value="192.168.6.11,192.168.6.12"/> <!-- cmServerlevel目前只支持1 --> <PARAM name="cmServerlevel" value="1"/> <!-- cms主及所有备的hostname --> <PARAM name="cmServerRelation" value="opengauss51m,opengauss51b"/> <!--dn--> <PARAM name="dataNum" value="1"/> <PARAM name="dataPortBase" value="15400"/> <PARAM name="dataNode1" value="/openGauss/data/dn,opengauss51b,/openGauss/data/dn"/> <PARAM name="dataNode1_syncNum" value="0"/> </DEVICE> <!-- 节点2上的节点部署信息,其中"name"的值配置为主机名称 --> <DEVICE sn="opengauss51b"> <!-- 节点2的主机名称 --> <PARAM name="name" value="opengauss51b"/> <!-- 节点2所在的AZ及AZ优先级 --> <PARAM name="azName" value="AZ1"/> <PARAM name="azPriority" value="1"/> <!-- 节点2的IP,如果服务器只有一个网卡可用,将backIP1和sshIP1配置成同一个IP --> <PARAM name="backIp1" value="192.168.6.12"/> <PARAM name="sshIp1" value="192.168.6.12"/> <!-- cm --> <PARAM name="cmDir" value="/openGauss/cm"/> <PARAM name="cmServerPortStandby" value="15300"/> </DEVICE> </DEVICELIST></ROOT>​3.集群VIP管理3.1 增加sudo权限给omm用户增加sudo权限,所有节点都执行echo "omm ALL=(ALL) NOPASSWD:ALL">>/etc/sudoersecho "Cmnd_Alias COMMAND_FLAG = /usr/sbin/ifconfig" >> /etc/sudoers​3.2 添加VIPifconfig ens33:15400 192.168.6.14 netmask 255.255.255.0 up ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.6.11 netmask 255.255.255.0 broadcast 192.168.6.255 inet6 fe80::a281:1dad:5f3f:1be8 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:56:78:64 txqueuelen 1000 (Ethernet) RX packets 70129 bytes 10190915 (9.7 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 445322 bytes 1129835756 (1.0 GiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0ens33:15400: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.6.14 netmask 255.255.255.0 broadcast 192.168.6.255 ether 00:0c:29:56:78:64 txqueuelen 1000 (Ethernet给集群添加VIP资源 VIP作为openGauss的资源管理cm_ctl res --add --res_name="VIP_az1" --res_attr="resources_type=VIP,float_ip=192.168.6.14"将每个实例加到资源中cm_ctl res --edit --res_name="VIP_az1" --add_inst="node_id=1,res_instance_id=6001" --inst_attr=base_ip=192.168.6.11cm_ctl res --edit --res_name="VIP_az1" --add_inst="node_id=2,res_instance_id=6002" --inst_attr=base_ip=192.168.6.12[omm@opengauss51m ~]$ cm_ctl res --checkcm_ctl: resource config is valid.执行check完成后,在cmdataPath/cm_agent/目录下会生成一个自定义资源配置文件cm_resource.json,检查完成没有错误后,需要手动scp将该文件分发到其他节点3.3 配置参数配置/openGauss/data/dn/pg_hba.conf在数据库pg_hba.conf文件中以sha256方式添加floatIphost all all 192.168.6.14/32 sha256 --cm集群故障自动切换配置前提条件,通过三方网管实现cd /openGauss/cm/cm_servervi cm_server.conf third_party_gateway_ip = 192.168.6.8cms_enable_failover_on2nodes = true cms_network_isolation_timeout = 20 3.4 重启集群[omm@opengauss51m ~]$ gs_om -t stopStopping cluster.=========================================Successfully stopped cluster.=========================================End stop cluster.[omm@opengauss51m ~]$ gs_om -t startStarting cluster.======================================================================Successfully started primary instance. Wait for standby instance.======================================================================.Successfully started cluster.======================================================================cluster_state : Normalredistributing : Nonode_count : 2Datanode State primary : 1 standby : 1 secondary : 0 cascade_standby : 0 building : 0 abnormal : 0 down : 0Successfully started cluster. 查询VIP在哪个节点[omm@opengauss51m ~]$ cm_ctl show[ Network Connect State ]Network timeout: 6sCurrent CMServer time: 2023-11-18 21:03:20Network stat('Y' means connected, otherwise 'N'):| \ | Y || Y | \ |[ Node Disk HB State ]Node disk hb timeout: 200sCurrent CMServer time: 2023-11-18 21:03:21Node disk hb stat('Y' means connected, otherwise 'N'):| N | N |[ FloatIp Network State ]node instance base_ip float_ip_name float_ip -----------------------------------------------------------------1 opengauss51m 6001 192.168.6.11 VIP_az1 192.168.6.14 4.测试故障转移##本次实验,我们直接对主库关机,验证高可用[omm@opengauss51b ~]$ gs_om -t status --detail[ CMServer State ]node node_ip instance state--------------------------------------------------------------------1 opengauss51m 192.168.6.11 1 /openGauss/cm/cm_server Down2 opengauss51b 192.168.6.12 2 /openGauss/cm/cm_server Primary[ Cluster State ]cluster_state : Degradedredistributing : Nobalanced : Nocurrent_az : AZ_ALL[ Datanode State ]node node_ip instance state -------------------------------------------------------------------------1 opengauss51m 192.168.6.11 6001 /openGauss/data/dn P Down Unknown2 opengauss51b 192.168.6.12 6002 /openGauss/data/dn S Primary Normal ##备库变为主库,VIP也飘逸过来了 [omm@opengauss51b ~]$ cm_ctl show[ Network Connect State ]Network timeout: 6sCurrent CMServer time: 2023-11-18 22:41:44Network stat('Y' means connected, otherwise 'N'):| \ | Y || Y | \ |[ Node Disk HB State ]Node disk hb timeout: 200sCurrent CMServer time: 2023-11-18 22:41:45Node disk hb stat('Y' means connected, otherwise 'N'):| N | N |[ FloatIp Network State ]node instance base_ip float_ip_name float_ip -----------------------------------------------------------------2 opengauss51b 6002 192.168.6.12 VIP_az1 192.168.6.14 ##然后我们启动主库,恢复集群 --启动集群[omm@opengauss51m ~]$ gs_om -t start[omm@opengauss51b ~]$ gs_om -t status --detail[ CMServer State ]node node_ip instance state--------------------------------------------------------------------1 opengauss51m 192.168.6.11 1 /openGauss/cm/cm_server Standby2 opengauss51b 192.168.6.12 2 /openGauss/cm/cm_server Primary[ Cluster State ]cluster_state : Normalredistributing : Nobalanced : Nocurrent_az : AZ_ALL[ Datanode State ]node node_ip instance state -------------------------------------------------------------------------1 opengauss51m 192.168.6.11 6001 /openGauss/data/dn P Standby Normal2 opengauss51b 192.168.6.12 6002 /openGauss/data/dn S Primary Normal作者:IT邦德中国DBA联盟(ACDU)成员,10余年DBA工作经验 擅长主流数据Oracle、MySQL、PG、openGauss运维 备份恢复,安装迁移,性能优化、故障应急处理等。可提供技术业务: 1.DB故障处理/疑难杂症远程支援 2.Mysql/PG/Oracle/openGauss 数据库部署及数仓搭建。
  • [技术干货] openGauss资源池化架构简介
    1. openGauss资源池化架构简介资源池化架构的来源Shared-Nothing>Shared-Everything适应云原生架构、新型硬件存储池化、内存池化、计算池化,技术趋势高性能、横/纵向扩展高可用读写节点和只读节点共享一份底层存储读写节点和只读节点之间通过TCP或RDMA协议使用DMS组件共享Shared Buffer Pool中的热数据页读写节点和只读节点通过DSS API和DSS Server的协同访问底层共享存储中的持久化的数据openGauss资源池化DMS简介负责数据库内核资源,主要包括页面和锁,在单写集群各实例间的协调共享,同时结合Remaster和Recovery机制支撑故障场景下资源一致性保证和集群快速恢复>DCS - Distributed Cache Service分布式页面缓存服务负责跨节点缓存页面的协调管理,各节点缓存的页面通过高速、低时延的内部网络进行跨节点传输,写节点对页面的修改操作能够不通过持久化到磁盘而被其它读节点获取,实现各节点缓存页面的实时共享南向调用DSSAPI访问存储,横向与其他节点通信协调传输页面DLS - Distributed Lock Service集群实例锁协调服务,实现全局数据结构的读写同步DRM - Dynamic Reform Management实例迁入迁出管理,北向对接CM,负责DRC资源恢复和重平衡、页面恢复DRC-Distributed Resource Catalog分布式资源目录,存储页面/锁资源DCS中的实例角色Owner:持有页面当前最新版本Master: 维护页面DRORequester:请求页面Copylnst:副本持有者 (Shared Copy)DCS中的页面类型Current Page - 当前页面(最新页面)page已经加载到内存,Owner持有S锁,后续其它实例向master请求该page的S锁。Master将requester标记为converting,同时通知owner发送page。owner发送page给requester。requester接收到page后,向master发送claim请求后,继续后续page操作。Master处理claim请求,将requester标记为owner清除convertingopenGauss资源池化DSS简介通过共享存储和共享内存,DSS跨节点管理文件,目录,卷和卷组及其元数据DSS向客户端提供读取和修改元数据的能力;客户端(通常是DBinstance)实质上将每个卷裸设备)作为一整个文件直接读写因此,DSS的读写性能理论上和裸设备相当,但文件管理成本比裸设备低很多使用共享内存存放元数据是为了节省总体的内存开销openGauss资源池化E2E访问数据流程执行流程:第一次读取页面时,集群中无节点有页面,从磁盘读取主/备机读时,集群中其他节点有页面,通过mes消息请求页面,页面owner通过mes线程接收请求,走回调函数获取本实例页面,发送给requester在本章节中,了解openGauss资源池化架构的起源以及主要原理,资源池化内两个关键组件DMS、DSS的概念、功能和原理。以及openGauss在传统架构上进行了哪些模块的修改,来对接DMS/DSS,支持资源池化能力。
  • [技术干货] openGauss传统主备架构
    openGauss传统主备架构openGauss资源池化架构openGauss资源池化双中心整体架构Dorado存储同步复制1.主LUN接收生产主机写请求,记录这个/O对应数据块的差异日志值为“有差异”2.同时把写请求的数据写入主LUN和从LUN,写从LUN时需要利用配置好的链路将数据发送到灾备站点。3.判断写主LUN和写从LUN的执行结果,如果都成功,则将差异日志改为“无差异”,否则保留“有差异”,在下一次启动同步时重新拷贝这一个数据块。4.主LUN返回生产主机写请求完成双集群核心原理1.分别拉起主备集群,集群init时主节点创建ctlinfo文件,初始化文件内容,并fsync到xlog盘中,为后续的同步和刷新做好准备;2.主集群主节点和备集群首备进行全量build,建立主集群主节点和备集群首备的libpq通道,用来互通消息。主集群的xlog日志,ctlinfo文件,数据全部build到备集群,备集群正常回放;3.主备集群xlog盘建立物理同步复制关系备集群只读权限;4.主集群主节点周期性发送keepalive消息备集群回复最新刷盘位置;5.备集群进入流复制模式,不断地读取cltinfo中的insertHead,并以此来指示xlog刷盘的位置,startup线程不断地读取xlog日志来回放
  • [用户实践] openGauss免费沙箱环境,给你一个学习、测试和搞事情的环境。
    想要学习openGauss找不到环境实践?想要试用openGauss,测试下语法和兼容性等?想要测试和复现一些问题又不想自己搭环境?我懂,就是懒不想搭环境!推荐大家使用O3社区上线的沙箱,https://cn.o3community.huawei.com/o3/1663500457860972546/detail?activeIndex=4&subIndex=1&o3src=https%3A%2F%2Fcn.o3.huawei.com%2Fstmo3%2Ftraining%2Flab-online-detail-shixizhi%3FlabType%3D3%26labId%3D5639%26domainCode%3DFORUM_221126028当前我们做了个单机的实验环境(ARM+openEuler 22.03 LTS+openGauss5.0.0),用户可以在上面预约使用,一次预约可以使用3小时,结束后释放并且复原环境。后续看需求陆续也把集群也上线>_<
  • [技术干货] 基于JDBC驱动的openGauss应用程序开发
    基于JDBC驱动的openGauss应用程序开发JDBC驱动openGauss驱动简介2. openGauss驱动原理基础介绍openGauss-jdb在是TCP/IP 协议之上实现了一套基于消息的通信协议。主要包括以下内容:建立和取消连接的消息流通信协议中使用的消息格式和类型处理请求的消息流Copy 子协议批量插入子协议openGauss 是多线程架构,守护线程 Postmaster 为每个连接分配一个后台线程 (backend)台线程的分配是在协议处理之前进行的,每个后台进程自行负责协议的处理。在 openGauss 源码或者文档中,通常认为“backend 和server 是等价的,表示服务端,同样frontend'和client 是等价的,表示客户端(应用程序)。认证协议介绍openGauss-idbc通信协议包括两个阶段: startup和normal。startup阶段主要完成客户端与数据库认证连接,正常则连接成功进入normal阶段。normal阶段客户端完成SQL命令的请求和数据库的响应。startup是非通用消息,会将协议版本号和客户端连接的用户名、数据库和GUC参数发送给数据库,而normal阶段则使用通用的消息格式:normal阶段有两种“子协议”来发送请求,分别是simple query和extended query。使用simplequery时,客户端直接发送请求,数据库立即处理并返回结果;而extended query会将请求过程分为若千个步骤,以加快数据库的处理速度。查询过程协议copy协议为了高效导入/导出数据,openGauss支持copy命令,copy命令会使数据库的连接处于不同的数据处理模式下copy子协议对应三种模式:copy-in 导入数据,对应命令 COPY FROM STDINcopy-out 导出数据,对应命令 COPY TO STDOUTcopy-both 用于 walsender,在主备间批量传输数据代码结构核心入口来源于Driver类,由它来完成所有JDBC接口类的调用openGauss驱动也提供了负载均衡、逻辑复制、copy等特有实现内容属性配置PBE核心流程编译openGauss的编译提供一键式编译脚本buildsh,代码仓中有详细的编译说明调试openGauss代码仓中已经提供了全套的juin4测试用例,最快捷的调试方法就是在工程下面添加新的测试用例验证第一步:更新测试数据库的配置信息(build,properties),也可以使用build.local.properties文件。第二步:添加测试case,进行驱动验证。参考org.postgresql.v511SelectFunctionTest进行纯jdbc测试case验证或者参考org.postgresqljdbc,DeepBatchednsertStatementTest继承自BaseTest4进行标准case验证2. 纯JDBC应用程序开发-驱动加载原理在idk1.6以前,通常编写idbc程序前需主动调用Class.formName(“orq.opengauss.Driver”)实现驱动的加载在jdk1.6及以后,java支持SPI机制实现驱动自发现,不需要再额外的操作标准应用开发逻辑复制openGauss提供逻辑复制功能以实现同构/异构数据库间的数据同步在本部分中,了解openGaussjdbc的加载过程和基本的jdbc应用程序编写。4. 使用ORM框架和连接池的应用程序开发ORM框架ORM (Obiect Relational Mapping)框架采用元数据来描述对象与关系映射的细节,元数据一般采用XML格式并且存放在专门的对象一映射文件中。简单理解为一种框架的格式,可以大大减少数据库的保存、删除、读取等重复性代码。数据库连接池(Connection Pooling)是将数据库的多个连接统一管理起来的程序,它可以动态地进行连接的申请、使用、释放管理。由于数据库创建连接是非常大的开销,所以连接复用是其核心思想。本文以druid为例进行讲解。由于连接池本身也是围绕JDBC规范而设计的,所以对ORM/连接池来说,使用用法基本一致,与数据库关系较小。了解与驱动密切相关的ORM和连接池概念,以及掌握mybatis和druid的使用。
  • [技术干货] MySQL迁移OpenGauss原理详解
    MySQL迁移OpenGauss原理详解通过本文,掌握MySQL和openGauss之间数据迁移和校验的实现原理,了解openGauss工具一体化平台Datakit,并能运用该平台进行数据迁移。1. 数据迁移概述1.1 数据迁移数据迁移是指将数据从一个数据库迁移至另一个数据库,按照数据库类型来分类,可分为同构数据库之间的迁移和异构数据库之间的迁移。按照数据的流向来分类,数据迁移分为数据导出和数据导入两种操作,通常会存在一种中间态文件,例如SOL文件、CSV文件等,中间态文件可保存在磁盘上,需要时再导入目标数据库中,可实现数据导出与导入的解耦。按照迁移是否停止应用来分类,数据迁移分为冷迁移和热迁移。冷迁移即为停服迁移,其操作简单,但需停止业务,不适用于实时在线业务:热迁移对用户业务影响较小,业务应用无感知,但迁移过程相对比较复杂。同构数据库迁移相对比较简单,可借助备份恢复技术(逻辑备份恢复和物理备份恢复)实现迁移。异构数据库迁移相对比较复杂,需综合考虑异构数据库的兼容性、选型、应用改造成本、迁移成本、性能等众多因素。主要介绍异构数据库(MySQL->openGauss)之间的热迁移。1.2 数据迁移五部曲1.3 小结本章节主要对数据迁移进行概述,并介绍了数据迁移的五步曲,包括迁移评估应用适配、数据迁移、试运行、生产割接五个步骤,并对openGauss现有具备的迁移能力进行总结。2. openGauss迁移工具集openGauss迁移工具集包含:全量迁移工具:支持基于快照点的全量数据迁移和对象迁移,支持MySQL、Oracle、反向 (openGauss->MySQL) 等的全量迁移;增量迁移工具:支持基于日志的增量数据和DDL操作迁移,支持MySQL、Oracle、反向 (openGauss->MySQL) 等的增量迁移;数据校验:支持MySQL与openGauss之间的全量和增量数据校验;4.操作Portal:独立的命令行工具,采用JAVA程序开发,主要完成对上述工具的安装、启停、维护等:安装:可以指定安装某个工具,也支持设定执行计划,例如: 安装MySQL全量迁移工具->安装MySQL增量迁移工具->安装数据校验工具操作Porta1支持按照该计划顺序完成操作;启停:可以指定运行某个工具,也支持设定执行计划,例如: 运行MySQL全量迁移->运行全量数据校验->运行MySQL增量迁移->运行增量数据校验->···,操作Porta1支持按照该计划顺序完成操作;维护:操作Portal监控工具的运行情况,在监测到工具异常时能尝试恢复工具,支持采集工具运行进度DataKit平台:以UI界面展示MySQL迁移全流程,简单易操作,过程可观测。2.1 全量迁移gs_mysync全量迁移将MySQL端已有数据和对象迁移至openGauss端。当前openGauss社区官网提供全量迁移工具gs mysync,本质为chameleon工具,其由python语言开发全量迁移支持的数据及对象:表、约束、索引、外键、表数据、函数、存储过程、触发器、视图。全量迁移的性能:sysbench测试模型,10张无主键表,单表数据量500w,20个读写并发线程迁移,整体性能可达300M/s。全量迁移实现原理:(1)采用多进程读写分离实现,生产者从MySQL侧读取数据写入CSV文件,消费者读取CSV文件写入openGauss,多个表并行处理(2) 针对大表,会将其分成多个CSV文件,默认一个CSV文件2M(3) 迁移顺序:表结构->表数据->表索引全量迁移实现逻辑:(1)记录全量迁移开始快照点(2)创建目标schema及表结构,不包含索引(3)创建多个读写进程,主进程针对每个表创建一个读任务,加入读任务队列(4)读写进程并行执行,读进程记录每个表的快照点,读取表数据存入多个csv文件;写进程同时copy csv文件至目标数据库(5)数据迁移完成后创建索引(6)所有任务完成后关闭读写进程约束及限制(1) openGauss端创建B兼容库进行迁移CREATE DATABASE opengauss database WITH dbcompatibility='B'(2) 迁移时大小写严格保持一致为保证大小写-致,还移时需保证MySQL的大小写参数lower case table names和openGauss的大小写参数dlphin.lower case table names保持致。 其中0表示大小写敏感,1表示大小写不敏感。对象迁移前需创建和MySQL对象所属definer同名的用户例如MySQL中view1所属的definer= mysql test @%,则在移前需在penGauss端创建5definer同名的用户'mysql test @%,并赋予一定的权限(至少对迁移后对象所处的schema要有创建权限),否则将导致对象迁移失败使用指南cid:link_02.2 增量迁移gs_replicate增量迁移将MySQL端产生的增量数据(JD操作及DDL)迁移至openGauss端。当前openGauss社区官网提吾言开发。供增量迁移工具gs replicate,其由Java语言开发实增量迁移实现原理:基于debezium+kafk(1) debezium mysql connector的source端,监控mysO格式写入到kafka;数据库的binlog日志,并将数据(DDL和DML操作)以AVAVRO格式数据(DDL和DML操作),并组装为事务,在o(2) debezium mysql connector的sink端,从kafka读取oenGauss端按照事务粒度并行回放,从而完成数据(DDL和DML操作)从mysql在线迁移至openGauss端(3)由于该方案严格保证事务的顺序性,因此将DDL]DML路由在kafka的一个topic下,且该topic的分区数只能为1(参数num.partitions=1),从而保证source端推送到kafka,和sink端从kafka拉取数据都是严格保序的利用sysbench对MyS梁作系统下,针对混合IUD场景,10张表50个线程 (insert-30戈程,update-10线程,delete-10线程),在迁移性能可达3w tpssink端日志回放双并行增量迁移并行机制:source端日志解析Source端并行原理开源组件mysql-binlog-connector-java用于解Tmysql端的binlog日志为event,原始实现方案为串于解析,通过对源代码进行修改,支持并行解析event事件,以提高debezium mysql connector作为source端的性能提供两种并行回放的机制(1)事务粒度并行回放:基于MySQL的主备并于复制机制实现并行回放行回放(2)表级粒度并行回放:基于表粒度并行实现事务粒度并行回放:基于MySQL的主备并行复制机制实现并行回放事务粒度并行回放:基于MySQL的主备并行复制机制实现并行回放事务粒度并行回放:基于MySQL的主备并行复制机制实现并行回放启动一个 Dispatcher线程负责分发待回放日志。每获取一条日志,需判断它是否能与当前正在回放的事务并行执行,判断规则为:如果所有正在回放的事务的最小sequence number大于该事务的last committed,那么该事务就可以并发执行。如果能并行则直接从Woker线程组中寻找一个空闲线程处理,如果不能并行则等待,直到满足条件后,再从Woker线程组中寻找一个空闲线程处理。如果没有空闲Woker线程,需要等待,直到有事务回放完释放Worker线程。两种并行方案对比约束及限制(1)MySQL5.7及以上版本;(2) MySQL参数配置:log bin=onbinlog format=rowbinglog_row_image=fullgtid mode=on #若未开启该参数,则sink端按照事务顺序串行回放,会降低在线迁移性能(3)支持DML和DDL迁移,在线迁移直接透传DDL,于openGauss和MySQL不兼容的语法,DDL迁移会报错使用指南cid:link_2增量迁移与全量迁移的配合(1)启动全量迁移全量迁移使用chameleon完成,全量迁移启动后,可在openGauss端的表sch chameleon.t replica batch中查询到全量迁移的快照点,单个表的快照点存储在 sch chameleon.t replica tables中。(2)启动source端启动source端开始前,需首先启动zookeeper,kafka,并注册schema。查询到全量迁移的快照点后,即可在source端的配置文件mysa-source.properties中配置全量迁移的快照点,并启动source端,无需等待全量迁移结末后才可启动source端。全量迁移启动后,即可启动source端,这样可以尽可能减少source端的时延,以达到减少迁移延迟的目的。启动source端后,针对全量迁移的表,若对其的DML事务位于表的快照点之前,将跳过对应的DML操作,避免数据出现重复,可保证迁移过程中数据不丢失,不重复。(3)全量迁移结束,启动sink端等待全量迁移结束后,即可启动sink端回放数据。若在全量迁移未结束时,就启动sink端,将会导致数据乱序,属于不合理的操作步骤,实际操作过程应避免不合理的操作。2.3 反向增量迁移gs_replicate反向增量迁移工具介绍Source端实现原理获得二进制流式数据,进行解析反向增量迁移source端在源库建立逻辑复制槽和发布订阅,source端支持从自定义的Xlog位置开始复制,在一个迁移任务中,正向增量迁移结束时会输出Xlog位置,反向增量迁移从该位置开始复制,保证了迁移任务由正向同步切换至反向同步的过程中数据不重不漏。Sink端实现原理反向增量迁移sink端从kafka抽取变更记录,按表并行构造sql语句并连接到目标库执行。Sink端从kaka抽取变更记录时,同时监控内存中待回放数据量的大小,若数据量过大,则暂停抽取,直至待处理数据量减少到一定程度。分发数据时,不同表的变更记录优先在不同的线程中执行,若表之间有依赖,则在同一个线程执行。对于执行失败的sgl语句,工具会定时输出到本地文件。约束与限制(1)openGauss需开启逻辑复制功能,修改GUC参数wal level=logical,且仅限拥有REPLICATION权限的用户进行操作;(2)需要调整数据库节点下的pg_hba.cnf以允许复制(这里的值取决于实际的网络配置及用于连接的用户);(3)openGauss的库与逻辑复制槽一一对应,当待迁移的库发生变化时,需重新配置逻辑复制槽的名字;(4)反向增量迁移暂不支持对DDL操作的迁移;(5)支持的源端库需openGauss 3.0.0及以上版本。2.4 校验工具gs datacheck校验工具实现原理校验工具 gs datacheck 采用JDBC方式抽取数据对表原始数据进行Hash计算,并将中间态数据暂存到kafka Topic中。使用源端和目标端的中间态数据同时构建两颗Merkle树并进行比较,从而实现了对源端数据库和目标端数据库数据一致性校验。技术框架采用 SpringBoot 、 kafka中间件、debezium开源社区地址: cid:link_1全量数据校验将MySQL源端和openGauss目标端数据通过分片方式抽取出来后进行规整,计算(hash),并将数据推送到kaka暂存Check服务即校验服务提取kafka中的数据,并对提取到的数据进行校验。输出校验结果,将校验结果输出到指定路径的文件中。增量数据校验通过debezium监控源端数据库的数据变更记录源端抽取服务按照一定的频率(时间+数量两个纬度)处理监听到的变更记录,对变更记录进行统计合并。将合并结果发送给数据Check服务。Check服务会对上次校验结果与当前增量数据进行合并根据合并之后的结果,Check服务发起增量数据抽取、校验、并将校验结果输出到指定路径文件规则过滤新增了表、行、列三种类别的过滤规则全量校验流程查询源端和目标端元数据信息information schematables,information schema.columns,获取全部待校验表信息根据待校验表构建抽取任务和校验任务对表记录数较小的表采用全表查询方式,对于大表则自动分解为多次抽取(通过where条件划分多个分片)。将表数据抽取后进行规整(标准化处理),计算(hash),并将最终处理后的Hash数据推送到kafka暂存。表记录数较少则将topic为单一topic分区,记录数较多则将数据存储在topic多个分区。抽取服务会给每张表分别创建一个topic,且源端和宿端分别使用不同的topic。Check服务以表为单位提取kafka中的数据进行校验。获取指定表源端和目标端Topic数据,分别构建两棵默克尔树。默克尔树构建成功后,通过对比两颗默克尔树完成表数据校验。输出校验结果,将校验结果输出到指定路径的文件中。数据抽取服务,是根据表元数据信息构建数据抽取任务。通过JDBC方式从数据库抽取表数据,并对数据进行规整和计算并将计算结果以表为单位,存储在kafka中。每张表创建一个topic。多表之间并行抽取,单个表根据数据量大小判断是否开启并行抽取。当表记录数大于指定记录阀值时,自动对当前任务进行分片,开启并行抽取。数据校验HASH算法:采用xxHash算法 中性能最优XXH3算法xXHash 是一种极快的哈希算法,在 RAM 速度限制下运行。它成功完成了评估哈希函数的碰撞、分散和随机性质量的SMHasher测试套件。代码是高度可移植的并且哈希值在所有平台上都是相同的。xXHash目前有4种实现:XXH32、XXH64、XXH128、XXH3 性能最优的是XXH3.过滤规则分为三类,表过滤规则,行过滤规则,以及列过滤规则。(1)表规则,即添加表的黑白名单,通过黑白名单(正则表达式)过滤是否校验那些表(2)行规则,即对指定范围的表添加行记录筛选,获取表的部分数据进行数据校验。(3)列规则,即对指定表添加列字段过滤规则,只校验当前表的部分字段数据。(4)表和行过滤规则是根据正则表达式进行匹配,列过滤规则是根据表名进行匹配,过滤规则在抽取服务加载元数据信息时进行触发,并执行。默克尔树(1) Merkle Tree是一种树,大多数是二叉树,也可以是多叉树。(2) Merkle tree的叶子节点的Value是数据集合的单元数据或者单元数据的HASH。非叶子节点的Value是根据它下面的叶子节点值,按照HASH算法计算得出的。创建Merkle tree是O(n)的复杂度,树高是loa(n)+1。(3)两个节点间数据进行比对时,从Merkle tree的根节点进行对比,根节点一致不再做任何处理:不一样,遍历Merkle tree定位不一致的节点。定位速度快定位的时间复杂度是O(log(n))。默克尔树节点比较默克尔树节点构建由于表记录数量不确定性(表可能100条记录,或者100万条记录)树最高不能超过15层,叶子节点不能超过32768个,那么100万记录如何校验? 这时候有了分桶概念,分桶就是将100万数据按照Hash规则将数据分散到32768个叶子节点中,那么每人节点会有个在诸容器,我们定义为桶。分散数据到各个桶的过程,我们定义为分桶。分桶是由默克尔树高度限制所决定,默克尔树高度在不超过15层时(当树高为15时,满二叉树叶子节点32768个),性能会比较好当树高度超过15层后会导致树构建以及遍历性能下降。数据分桶,将拉取的数据根据数据主键Hash值进行模运算,将数据分别添加到不同的桶中。一键式迁移工具gsrep_portal介绍键式迁移工具gs rep portal集成了全量迁移、增量迁移、反向迁移、数据校验的工具。gs rep portal支持键式安装上述工具,并设定迁移任务。gs rep_portal可以根据用户设定的迁移任务的执行计划顺序去调用相应工具完成每个迁移步骤,并能展示每个步骤的状态、进度、异常原因等。2.5 迁移工具总结本章节主要介绍了MySQL迁移全流程中五个关键步骤: 全量迁移、全量校验、增量迁移、增量校验、反向迁移的实现原理,接着介绍了一键式迁移portal,并对迁移工具集进行总结。3. 工具一体化平台DataKit3.1 DataKit介绍Datakit定位为openGauss的数据全生命周期生产力工具,支持数据全生命管理,覆盖openGauss安装部署数据开发、智能运维、数据迁移等阶段Debezium反向增量迁移工具支持将openGauss数据库的增量数据实时同步至MySQL数据库。DataKit是openGauss的一个工具集,采用B/S(即Browser/Server,浏览器/服务器)软件架构,提供基础的服务器、数据库实例等软硬件资源管理能力;同时支持通过按需部署功能插件扩展能力,目前社区提供安装部署数据迁移、数据开发、智能运维等功能插件Datakit也是一个丁具开发平台,支持用户根据插件接口和规范实现自己的特有功能。功能插件支持动态加载到DataKit上运行,也支持从Datakit上动态卸载。插件支持调用平台和其他插件的开放接口获取相应数据和功能,以实现快速构建特色功能包括:数据迁移插件提供了MySQL迁移所需的所有能迁移任务管理:用户可以通过配置迁移任务将单个或多个源端数据源中的数据迁移至目标数据源日志和错误信息,并进行相应的处理迁移过程监控:用户可以实时查看迁移进度l行,以提高迁移效率并发执行:用户可以创建多个迁移任务并行资源动态分配:系统能够根据最大化利用原,合理分配运行机器,以实现多任务并行迁移迁模式包括离线模式和在线模式,其中离线模式包括全量迁移、全量校验两个阶段,在线模式包括全量迁移、全量校验增量迁移、增量校验、反向迁移五个阶段3.2 DataKit部署3.3 Datakit实现MySQL迁移全流程MySQL全流程迁移包括全量迁移、全量校验、增量迁移、增量校验、反向增量迁移五个阶段,可通过DataKit平台完成一键式迁移。本章节主要介绍了工具一体化平台Datakit的能力,接着讲述了Datakit的部署方式,着重介绍了如何用DataKit实现MySQL迁移全流程。4. MySQL迁移全流程demo
  • [技术干货] openGauss性能优化探索与实践
    openGauss性能优化探索与实践摘要: 本文详细探讨了openGauss数据库的性能优化方法,通过实践验证了一系列策略的有效性。我们分析了查询优化、存储优化以及系统配置优化等多个方面,提供了丰富的示例代码,并为每种策略给出了具体的实施建议。一、引言openGauss是一款开源的关系型数据库管理系统,为企业级应用提供了高性能、高并发、高可用的数据存储和处理能力。然而,随着数据量的不断增长和业务需求的日益复杂,数据库性能优化成为了每个使用openGauss的企业和个人必须面对的问题。二、查询优化1.合理使用索引索引是提高查询性能的关键。在openGauss中,可以使用B-tree、Hash、Bitmap等多种类型的索引。选择合适的索引类型和正确的索引列可以大幅度提高查询速度。示例代码:-- 创建B-tree索引 CREATE INDEX idx_name ON table_name (column_name); -- 创建Hash索引 CREATE INDEX idx_name ON table_name USING hash (column_name);2.避免全表扫描全表扫描是性能杀手,尤其是在大表中。应尽量使用索引扫描来替代全表扫描。可以通过EXPLAIN命令查看查询的执行计划,从而发现是否存在全表扫描。示例代码:EXPLAIN SELECT * FROM table_name WHERE column_name = 'value';3.优化JOIN操作JOIN操作是数据库中最常见的操作之一,但也是最容易产生性能问题的地方。应尽量减少JOIN的数量,尤其是多表JOIN。同时,合理调整JOIN的顺序和使用合适的JOIN类型也可以提高性能。示例代码:-- 使用INNER JOIN替代CROSS JOIN SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;4.使用分页查询对于大量数据的查询,应使用分页查询来减少每次查询返回的数据量。可以使用LIMIT和OFFSET子句来实现分页。示例代码:SELECT * FROM table_name LIMIT 10 OFFSET 20;三、存储优化1.合理设计表结构表结构的设计直接影响到存储效率和查询性能。应尽量减少表的宽度,避免使用过多的列。同时,合理选择数据类型和分区策略也可以提高性能。2.使用压缩技术openGauss支持表级和列级的压缩技术,可以有效减少存储空间和提高I/O性能。可以根据数据的特性和访问模式选择合适的压缩算法。示例代码:-- 创建压缩表 CREATE TABLE compressed_table (column_name data_type) WITH (compression='zlib');3.定期维护数据库定期执行VACUUM和ANALYZE操作可以清理无效数据和更新统计信息,从而提高查询性能。可以使用cron或其他调度工具来自动化这些操作。示例代码:-- 执行VACUUM操作 VACUUM (ANALYZE, FULL) table_name;四、系统配置优化1.调整内存配置openGauss的内存配置对性能有很大影响。应根据系统的内存大小和负载情况调整shared_buffers、work_mem等参数的值。可以使用性能监控工具来观察内存的使用情况并进行调整。 2.优化磁盘I/O磁盘I/O是数据库性能的瓶颈之一。可以通过使用SSD、配置RAID等方式来提高磁盘I/O性能。同时,合理设置数据库的存储路径和文件系统的挂载参数也可以提高性能。
  • [技术干货] openGauss数据库性能调优示例及代码
    优化查询语句:使用合适的索引:分析查询语句的执行计划,确定是否需要创建索引来加速查询。可以使用EXPLAIN语句来查看执行计划。 优化WHERE子句:确保WHERE子句中的条件可以充分利用索引,避免全表扫描。 避免使用SELECT *:只选择需要的列,避免不必要的数据传输和处理。 使用连接查询替代子查询:连接查询通常比子查询效率更高。 避免使用函数和表达式:函数和表达式的使用可能导致查询无法使用索引。 配置数据库参数:shared_buffers:适当增加shared_buffers参数的值,以提高内存缓存的效果。 work_mem:调整work_mem参数的值,以适应查询中的排序和哈希操作的内存需求。 maintenance_work_mem:增加maintenance_work_mem参数的值,以加快索引创建和重建的速度。 max_connections:根据系统负载和并发连接数的需求,适当调整max_connections参数的值。 effective_cache_size:根据系统可用内存大小,合理设置effective_cache_size参数的值。 监控和优化系统资源:监控数据库性能:使用openGauss提供的性能监控工具,如pg_stat_activity、pg_stat_bgwriter等,监控数据库的活动和性能指标。 调整并发连接数:根据系统负载和资源使用情况,适时调整并发连接数,避免资源竞争和性能下降。 分析慢查询:使用pg_stat_statements等工具分析慢查询,找出性能瓶颈并进行优化。 下面是一个示例代码,展示如何使用EXPLAIN语句查看查询执行计划:-- 创建一个示例表 CREATE TABLE employees ( id SERIAL PRIMARY KEY, name VARCHAR(100), age INT, department VARCHAR(100) );-- 创建索引 CREATE INDEX idx_employees_department ON employees (department);-- 查询示例 EXPLAIN SELECT * FROM employees WHERE department = 'IT'; 通过运行以上代码,您可以查看查询语句的执行计划,确定是否使用了索引以及其他优化信息。
  • GaussDB支持的数据类型笔记分享
    高斯数据库(GaussDB)支持多种数据类型,包括数值、日期/时间、字符串、二进制数据等。数值类型INTEGER(INT):整数,通常为4字节。SMALLINT:较小的整数,通常为2字节。BIGINT:较大的整数,通常为8字节。NUMERIC(DECIMAL):固定精度和小数位数的数值,可存储较大范围和精度的数值。FLOAT(DOUBLE PRECISION):浮点数,具有双精度,适用于存储较大范围的数值。REAL:浮点数,具有单精度,适用于存储较小范围的数值。日期/时间类型DATE:日期,存储年、月、日。TIME:时间,存储小时、分钟、秒。TIMESTAMP:时间戳,存储日期和时间。INTERVAL:时间间隔,表示两个日期/时间值之间的差值。字符串类型CHAR:定长字符串。VARCHAR:可变长度字符串,可存储不定长的字符串。TEXT:大型文本数据,可存储大量字符。二进制数据类型BYTEA:二进制数据,用于存储二进制文件,如图像、音频等。BLOB:大型二进制对象,用于存储较大的二进制数据。布尔类型BOOLEAN:布尔值,表示真(TRUE)或假(FALSE)。枚举类型ENUM:枚举类型,可以存储一组预定义的值。UUID类型UUID:通用唯一标识符,用于生成唯一的ID。总结此外,高斯数据库还支持时序数据和图数据等特殊数据类型,具有较强的兼容性,能够应对不同类型的业务场景。
  • [问题求助] gaussdb是否支持创建kafka外部连接
    官方提供的sqlCREATE SERVER server_name      FOREIGN DATA WRAPPER fdw_name     OPTIONS ( { option_name ' value ' } [, ...] ) ; 查看了 FOREIGN DATA WRAPPER 支持的外部数据封装器,我只看到了dfs_fdw和gc_fdw我想问一下是否支持kafka类型的,例如:CREATE SERVER kafka_server  FOREIGN DATA WRAPPER kafka_fdw 
  • [问题求助] 轻量化数据库工具数据库访问密码
    联系方式:13250826656
  • [用户实践] 利用OpenGauss设计和实现成绩管理系统
    一、需求分析先介绍系统开发意义、可行性和应用环境等。某校管理学生成绩的工作人员,根据实际工作需要,提出了以下基本数据和业务处理需求:(1)学校设置了各专业,在专业下开设班级,每个班级包含若干学生,学生信息至少需要包含学号、姓名、性别、年龄、生源所在地、已修学分总数等数据项;另外,需要有地区信息,用于统计某一地区的学生数;(2)课程信息表至少需包含课程编号、课程名称、任课教师、开课学期、学时、考试或考查、学分等数据项,课程根据班级开设。(3)教师信息至少需要包含教师编号、姓名、性别、年龄、职称、联系电话等数据项;(4)学生成绩至少需要学号,学期,课程名称,成绩,任课老师等数据项;(5)需要实现业务处理和查询功能:a) 学生成绩按每学年成绩统计;学生成绩b) 名次排定;c) 每门课程平均成绩统计;d) 学生所学课程及学分统计;e) 对每个学生输入成绩的时候,自动生成学生的已修学分总数;f) 学生成绩查询;g) 教师任课查询;h) 班级课程开设查询。(6) 补充说明a) 假设学籍管理制度是采用学年制,且暂不考虑选修课情况。b) 同一专业可能有多个班,所以同一门课可能需要多个教师上课,一个教师在一学期可能上多门课程。1.1 数据需求描述分析系统的数据需求,用数据字典和数据流图描述系统的数据需求,一般要求有2级(初级和详细级)数据流图,并确定系统开发边界。1.1.1数据字典➢ 数据项名 数据项名:学号含义说明:唯一标识每个学生数据类型:CHAR长度:12数据项名:学生姓名含义说明:标识每个学生的姓名数据类型:CHAR长度:20数据项名:学生性别含义说明:学生性别数据类型:CHAR长度:3取值范围:“男”或“女”取值含义:学生分为男生和女生数据项名:学生出生日期含义说明:表明每个学生的出生日期数据类型:DATESTAMP数据项名:籍贯(省)含义说明:表明每个学生入学前的来源地数据类型:CHAR长度:20数据项名:籍贯(市)含义说明:表明每个学生入学前的来源地数据类型:CHAR长度:20数据项名:已修学分总数含义说明:学生已修课程的学分总数数据类型:FLOAT长度:4取值范围:>=0取值含义:已修学分不可能小于0与其他数据项的逻辑关系: 等于该学生所有课程的学分数据项之和数据项名:学生登录密码含义说明:学生账户用于登录系统时的密码数据类型:CHAR长度:20数据项名:成绩含义说明:学生某一课程的成绩数据类型:INT长度:3取值范围:0 ~ 100取值含义:课程成绩60以上为合格,100为满分,不可能低于0分数据项名:上课时间含义说明: 表示教师授课和学生上课的时间数据类型: CHAR长 度: 20数据项名:上课地点含义说明: 表示教师授课和学生上课的地点数据类型: CHAR长 度: 20数据项名:专业编号含义说明: 唯一标识每一个专业数据类型: CHAR长 度: 20数据项名:专业名称含义说明:表示咋混也的名称数据类型: CHAR长 度: 20数据项名:班级编号含义说明: 唯一标识每一个班级数据类型: CHAR长 度: 20数据项名:班级名称含义说明:表示班级的名称数据类型: CHAR长 度: 20数据项名:课程编号含义说明:唯一标识每一门课程数据类型: CHAR长 度: 20数据项名:课程名称含义说明:表示课程的名称数据类型: CHAR长 度: 20数据项名:开课学期含义说明:某课程开设的时间节点数据类型: CHAR长 度: 20取值范围:类似于2021-2022(1),2022-2023(2)这样代表某一学年第几学期数据项名:学时含义说明:某课程总共需要的授课时间数据类型: INT长 度: 3取值范围:(0,999)取值含义:课程授课时间不小于0小时,不大于999小时数据项名:学分含义说明:某课程的学分数据类型:FLOAT数据项名:考核方式含义说明:某课程的评价方式数据类型: CHAR长 度: 2取值范围:考查/考试取值含义:课程只有考查和考试两种考核方式数据项名:教师编号含义说明:唯一标识每一位教师数据类型:CHAR长度: 20数据项名:教师姓名含义说明:表示每一位教师的姓名数据类型:CHAR长度: 20数据项名:教师性别含义说明:表示每一位教师的姓名数据类型:CHAR长度: 2取值范围:男/女取值含义:教师性别只有男和女数据项名:教师出生日期含义说明:表示每一位教师的出生日期,可计算教师的年龄数据类型:DATE数据项名:职称含义说明:表示每一位教师的职称数据类型:CHAR长度:20数据项名:联系电话含义说明:教师的联系电话数据类型:CHAR长度:20数据项名:教师登录密码含义说明:教师账户用于登录系统时的密码数据类型:CHAR长度:20数据项名:管理员登录账号含义说明:管理员账户用于登录系统时的密码数据类型:CHAR长度:20数据项名:管理员登录密码含义说明:管理员账户用于登录系统时的密码数据类型:CHAR长度:20➢ 数据结构 数据结构名:学生别名:学生基本信息含义说明:定义了每一个学生的基本信息组成:学号、学生姓名、学生性别、学生出生日期、籍贯(省)、籍贯(市)数据结构名:班级别名:学生基本信息含义说明:定义了每一个班级的基本信息组成:班级编号、班级名称数据结构名:专业别名:专业基本信息含义说明:定义了每一个专业的基本信息组成:专业编号、专业名称数据结构名:课程别名:课程基本信息含义说明:定义了每一个学生的基本信息组成:学号、学生姓名、学生性别、学生出生日期、籍贯(省)、籍贯(市)数据结构名:教师别名:教师基本信息含义说明:定义了每个教师的基本信息组 成: 教师编号、教师姓名、教师性别、教师出生日期、职称、联系电话、教师登录密码数据结构名:管理员别名:管理员基本信息含义说明:定义了每个管理员的基本信息组 成: 管理员账号、管理员登录密码➢ 数据流数据流名:输入登录信息含义说明: 登录系统对用户身份进行验证数据来源: 用户数据去向: 身份信息表组 成: 用户账户、用户密码、用户身份数据流名:查询、添加、修改、删除学生本人基本信息、成绩、选课含义说明: 学生进行个人信息的查询,教师、管理员对学生信息进行管理数据来源: 用户数据去向: 学生信息表组 成: 学号、学生姓名、学生性别、出生日期、生源所在省市、班级、专业、选课、课程成绩、已修总学分数据流名:查询、添加、修改、删除教师基本信息、任教情况、任教班级成绩含义说明: 教师对学生及个人信息进行管理、管理员对教师信息进行管理数据来源: 用户数据去向: 教师信息表、学生信息表、选课信息表组 成: 教师编号、教师姓名、性别、出生日期、职称、联系电话、任教信息、任教班级成绩信息➢ 数据存储 数据存储名: 用户账号信息说明: 记录用户账号信息输入数据流: 管理员输入、修改、删除账号信息操作输出数据流: 用户账号表组 成: 用户账号,用户密码,用户身份存取方式: 随机存取数据存储名:学生信息说明: 记录学生基本信息输入数据流: 管理员输入、更新、删除学生信息操作输出数据流: 学生信息表组 成: 学号、学生姓名、学生性别、出生日期、生源所在省市、班级、专业、已修总学分存取方式: 随机存取数据存储名: 教师信息说明: 记录教师基本信息输入数据流: 管理员输入、更新、删除教师信息操作输出数据流: 教师信息表组 成: 教师编号、教师姓名、性别、出生日期、职称、联系电话存取方式: 随机存取数据存储名: 课程信息说明: 记录课程基本信息输入数据流: 管理员输入、更新、删除课程信息操作输出数据流: 课程信息表组 成: 课程编号、课程名称、课程学时、课程学分、开设学期、考核方式存取方式: 随机存取数据存储名: 教师信息说明: 记录专业班级基本信息输入数据流: 管理员输入、更新、删除专业班级信息操作输出数据流: 专业班级信息表组 成: 班级编号、专业名称、专业编号存取方式: 随机存取数据存储名: 教师信息说明: 记录教师任教信息及成绩信息输入数据流: 管理员输入、更新、删除任教信息操作,教师录入成绩操作输出数据流: 任教信息表组 成: 课程编号、教师编号、学生学号、课程成绩存取方式: 随机存取1.1.2 数据流图数据流图主要分为两级,分别为顶级数据流图和次级数据流图。其中顶级数据流图包括学生模块、教师模块、管理员模块,描述了这三个模块与高校管理系统间的数据传递关系。具体如下图1-1所示。图1-1 顶级数据流图次级数据流图是对顶级数据流图局部模块的细化描述与拓展描述,这里根据三个模块将顶级数据流图细化出了三个次级数据流图,分别为学生模块次级数据流图、教师模块次级数据流图、管理员模块次级数据流图。学生模块的主要功能为课程信息、个人信息和成绩、已修总学分的查询,具体的数据流图如下图 1-2 所示:图 1-2 学生模块次级数据流图教师模块的主要功能为授课信息、教师个人信息、授课班级成绩信息的查询以及学生课程成绩的录入,具体的数据流图如下图 1-3 所示:图 1-3 教师模块次级数据流图管理模块的主要功能为学生成绩的查询以及对于学生、课程、教师信息的管理,具体的数据流图如下图 1-4 所示图 1-4 管理模块次级数据流图1.2 系统功能需求本高校成绩管理数据库系统分为4个界面,分别为登录界面、学生界面、教师界面和管理员界面,并由登录界面中的身份选择来决定界面的选择。学生界面有3个功能,分别为学生个人信息查询、个人成绩查询和班级课程查询功能;教师界面有5个功能,分别为教师个人信息查询、授课信息查询、学生成绩统计、学生成绩查询和学生成绩录入功能;管理员界面有5个功能,分别为对学生信息、成绩信息、教师信息、课程信息的管理(查询、添加、删除、更新)以及地区人数的统计功能。其中,由于管理员不具备更改成绩的权限,因此管理员界面不设置对成绩信息的更新功能。除此之外,本系统对所有的信息都具有模糊查询和按各数据项排序的功能, 而且实现了灵活排版调整内容的自适应界面。本系统的功能结构如下图 1-5 所示图 1-5 高校成绩管理数据库系统功能结构1.3 其他性能需求并发用户数:考虑到实际应用,数据库系统应面向在校学生和教师以及教务 处管理员使用,理论上并发用户数应到达上千数量级;响应时间:考虑到实际应用,数据库系统应响应时间足够短,理论上不大于 3s;存储需求:考虑到实际应该,数据库系统应在满足查询效率的前提下,尽量 精简存储空间,减少数据冗余。1.4 其他需求1. 保证用户数据操作的简单便捷;2. 用户更新信息时数据库应实时更新;3. 保证系统良好的交互性、功能性、稳定性;4. 建立存储过程,集成操作功能,增加数据更新的便利性;5. 建立触发器,保证数据项格式的规范化以及数据的一致性;6. 保证前端界面的简洁美观、人性化,能对错误信息进行提示;7. 满足高并发下的大数据量交互需求,满足数据备份的数据量迁移;8. 用户分身份以账号密码登录数据库应用系统,涉及不同的界面和功能。二、概念结构设计2.1 局部E-R图局部 E-R 模式的设计一般可分解为以下三步骤:1. 确定局部 E-R 模式的范围设计局部 E-R 模式的第一步就是确定局部结构的范围,即将用户需求划分 成若干个部分,其划分方式一般有以下两种:(1) 根据企业的组织机构对其进行自然划分;(2) 根据数据库提供的服务种类进行划分,使得每一种服务所使用的数据明显地不同于其他种类,这样就可为每一类服务设计一个局部 E-R 模式。本系统采用第二种划分方式,根据数据库提供的服务种类进行划分。高校成 绩管理数据库可以按提供的服务分为以下三种类型:(1) 学生专业班级信息查询; (2) 学生成绩查询; (3) 教师任教班级课程查询。2. 查询定义实体型每一个局部 E-R 模式都包括一些实体型,定义实体型就是从选定的局部范 围中的用户需求出发,确定每一个实体型的属性和主键。 实体型的设计可参考以下三个原则:(1) 信息描述原则;(2) 依赖性原则;(3) 一致性原则。在确定了实体型和属性后,需对下述几个方面作详细描述:(1) 给实体集与属性命名;(2) 确定实体标识;(3) 非空值原则。3. 定义联系在 E-R 模型中,“联系”用于刻画实体集之间的关联。在定义了实体型和 属性并进行描述后,还要确定实体集之间的联系及其属性。实体集之间的联系非 常广泛,大致可分为以下三种:a) 存在性联系b) 功能性联系c) 事件联系由此,可最终根据学生专业班级信息查询、学生成绩查询、教师任教班级课 程查询三种服务确定三个局部 E-R 模式如下:(1) 学生专业班级信息查询的局部 E-R 图根据高校成绩管理的实际需求,专业信息包括专业编号、专业名称等数据项;班级信息包括班级编号、班级名称等数据项。但为了查询方便,将二者置于一张表中,并且设置班级编号为主键。学生个人信息包含学号、姓名、性别、出生日期、生源所在省、生源所在市、已修学分总数,学生登录密码等数据项,学号为主键。在设计学生实体型的属性时,为满足对学生的年龄信息查询需求,同时又省 去随时间定期更新数据库带来的维护成本,将年龄替换为出生日期。即年龄可由 当前年份减去出生年份获得,使得数据库中信息变得准确又易维护。同时,考虑到之后以学生身份登录系统的需求,将学生登录密码也作为学生 实体型的属性,以方便数据存储和查询。由此定义实体型(下划线处为主键)如下:a) 专业班级(班级编号,班级名称,专业编号,专业名称);b) 学生(学号、学生姓名、学生性别、教师出生日期、生源所在省、生源 所在市、已修学分总数、学生登录密码)。学校设置了各专业,在专业下开设班级,每个班级包含若干学生,并且考虑 到课程根据班级开设,因此将专业班级表也纳入学生专业班级信息查询的局部 E-R 图中。由此定义联系如下:c) 包含:班级和学生之间具有一对多联系,“包含”为联系名。由此可得学生专业班级信息查询的局部 E-R 图如图 2-1 所示:图 2-1 学生专业班级信息查询的局部 E-R 图(2) 学生成绩查询的局部 E-R 图根据高校成绩管理的实际需求,课程信息包括课程编号、课程名称、开课学期、学时、学分、考核方式等数据项,课程编号为主键。由此定义实体型(下划 线处为主键)如下:a) 课程(课程编号、课程名称、开课学期、学时、学分、考核方式);学生选修课程,一名学生可选择多门课程,一门课程可由多名学生选修,每 名学生的每门课程都有一个成绩。由此定义联系如下:b) 选课:学生和课程之间具有多对多联系,“选课”为联系名,包含成绩 属性;由此可得学生成绩查询的局部 E-R 图如图 2-2 所示:图 2-2 学生成绩查询的局部 E-R 图(3) 教师任教班级课程查询的局部 E-R 图在定义实体集之间的联系时,要尽量消去冗余的联系,以免将这些问题留给全局E-R模式的集成阶段,从而造成困难和麻烦。一个班级开设的一门课程只有一个教师,一个教师在一个班可能教授多门课程,一个教师可能教授多个班级同一门课程,因此教师与班级、课程之间的联系是一对多的,可将三者联系设定为1:m:n的联系。图 2-3 教师任教班级课程查询的局部 E-R 图然而,考虑到实际情况中可能存在三者不一定同时知道的情况,即可能仅知道教师所教授的班级,但不知道教师所教授的课程。因此,仍然采取建立三张关系表说明三者之间的两两关系。根据高校成绩管理的实际需求,教师信息包括教师编号、教师姓名、教师性别、教师出生日期、职称、联系电话,教师登录密码等数据项。教师实体型中教 师出生日期和教师登录密码属性的设计思路同学生实体型,此处不再赘述。由此 定义实体型(下划线处为主键)如下:a) 教师(教师编号、教师姓名、教师性别、教师出生日期、职称、联系电 话、教师登录密码)。 一名教师可教授多门课程,一门课程可以有多名教师;一个班级可以开设多 门课程,一门课程可以为多个班级设置;一名教师可以给多个班级授课,一个班 级可以有多名教师任课。由此定义实体型如下:a) 教授:教师和课程之间具有多对多联系,“教授”为联系名;b) 设置:班级和课程之间具有多对多联系,“设置”为联系名;c) 任课:教师和班级之间具有多对多联系,“任课”为联系名。由此可得教师任教班级课程查询的局部 E-R 图如图 2-4 所示:图2-4 教师任教班级课程查询的局部 E-R 图2.2 全局E-R图当各个局部 E-R 模式设计完成后,就需要对它们进行合并,将其集成为一 个全局的 E-R 模式,即数据库的全局概念结构。全局 E-R 模式的集成过程,一般可以分成两步进行:1. 确定公共实体型公共实体型是多个局部 E-R 模式综合集成的基础,因此必须首先确定各局 部 E-R 模式之间的公共实体型。在这一步中,一般仅根据实体型名称和主键来 认定公共实体型,即把同名实体型作为一个候选的公共实体型,把具有相同主键 的实体型作为另一个候选的公共实体型。本系统公共实体型为:(1) 专业班级(班级编号,班级名称,专业编号,专业名称)(2) 课程(课程编号、课程名称、开课学期、学时、学分、考核方式)(3) 学生(学号、学生姓名、学生性别、学生出生日期、生源所在省、生源 所在市、已修学分总数,学生登录密码)(4) 教师(教师编号、教师姓名、教师性别、教师出生日期、职称、联系电 话,教师登录密码)2. 合并局部 E-R 模式局部 E-R 模式的合并顺序有时会影响处理效率和结果。一般都采用逐步合 并的方式,即首先将两个具有公共实体型的局部 E-R 模式进行合并,然后每次 将一个新的与前面已合并模式具有公共实体型的局部 E-R 模式合并起来,最后 再加入独立的局部 E-R 模式,这样即可终获得全局 E-R 模式。 合并局部 E-R 模式可能会产生的冲突通常可分为三种类型:(1) 属性冲突;(2) 命名冲突;(3) 结构冲突。消除冲突后,合并后的全局 E-R 模式如图 2-5 所示:图2-5 全局 E-R 图2.3 优化E-R图按照前面的方法将各个局部 E-R 模式合并后就得到一个初步的全局 E-R 模式,之所以这样称呼是因为其中可能存在冗余的数据和冗余的联系等。所谓冗余的数据是指可由基本数据导出的数据,冗余的联系是指可由其他联系导出的联系。冗余的数据和冗余的联系容易破坏数据库的完整性,给数据库维护带来困难,因此再得到初步的全局 E-R 模式后,还应当进一步检查 E-R 图中是否存在冗余,如果存在冗余则一般应设法将其消除。 一个好的全局 E-R 模式,不仅能全面、准确地反映用户需求,而且应该满足如下的一些条件:实体型的个数尽可能少;实体型所含属性个数尽可能少;实体型之间联系无冗余。下面从优化全局 E-R 模式时需要重点考虑的几个问题入手优化全局 E-R 图1. 实体型是否合并的问题初步全局 E-R 模式不存在冗余的实体型,且没有一对一联系,因此不需要 合并实体型。2. 冗余属性是否消除的问题初步全局 E-R 模式没有冗余属性,因此不需要消除冗余属性。3. 冗余联系是否消除的问题在设计局部 E-R 模式的定义联系时,考虑到已将教师与课程之间的“讲授” 联系、班级与课程之间的“设置”联系、教师与班级之间的“授课”联系转化成 教师、班级与课程之间的一对多三元联系,大大减小了存储空间,降低了维护代 价。三、逻辑结构设计3.1 关系模式设计将 E-R 图转换为关系模式,定义实体型、属性及其联系,关系模式定义如下,其中下划直线的属性为主键,下划波浪线的属性为外键。3.2 数据类型定义对关系模式中的属性定义类型、长度和约束如下表所示:表 3-1 学生信息基本表 linc_Students08字段名数据类型长度约束学生学号sja_Sno08NVARCHAR50主键学生姓名sja_Sname08NVARCHAR50-学生性别sja_Ssex08CHAR3男/女学生生日sja_Sbirthday08DATE--生源省sja_Sprovince08NVARCHAR50-生源市sja_Scity08NVARCHAR50-已修总学分sja_Countcredit08FLOAT--学生登录密码sja_Spassword08NVARCHAR50-班级编号sja_CLno08NVARCHAR50外键表 3-2 专业班级基本表 linc_CLasses08字段名数据类型长度约束班级编号sja_Clno08NVARCHAR50主键专业编号sja_Mno08NVARCHAR50-专业名称sja_Mname08NVARCHAR50-班级名称sja_CLnameNVARCHAR50-表 3-3 课程信息基本表 linc_Courses08字段名数据类型长度约束课程编号sja_Cno08NVARCHAR50主键课程名称sja_Cname08NVARCHAR50-开设学期sja_Cterm08NVARCHAR50-学时sja_Cclasshour08INT4-学分sja_Credit08FLOAT--考核方式sja_Cexamine08NVARCHAR50考察/考试表 3-4 教师信息基本表 linc_Teacher08字段名数据类型长度约束教师编号sja_Tno08NVARCHAR50主键教师名称sja_Tname08NVARCHAR50-教师性别sja_Tsex08CHAR3男/女教师生日sja_Tbirthday08DATE--职称sja_Ttitle08NVARCHAR50助教/讲师/副教授/教授联系电话sja_Tphone08NVARCHAR50-教师登录密码sja_Tpassword08NVARCHAR50考察/考试表 3-5 选课基本表 linc_ChooseClass08字段名数据类型长度约束学生学号sja_Sno08NVARCHAR50主键,外键课程编号sja_Cno08NVARCHAR50主键,外键成绩sja_Score08INT30~100表 3-6 上课基本表 linc_Teaching08字段名数据类型长度约束班级编号sja_CLno08NVARCHAR50主键,外键课程编号sja_Cno08NVARCHAR50主键,外键上课时间sja_Time08NVARCHAR50-上课地点sja_Place08NVARCHAR50-表 3-7 老师授课班级基本表 linc_Teaching08字段名数据类型长度约束班级编号sja_CLno08NVARCHAR50主键,外键教师编号sja_Tno08NVARCHAR50主键,外键表 3-8 老师授课课程基本表 linc_Teaching08字段名数据类型长度约束课程编号sja_Cno08NVARCHAR50主键,外键教师编号sja_Tno08NVARCHAR50主键,外键表 3-9 管理员基本表 linc_ctrlogin08字段名数据类型长度约束管理员登录用户名sja_Ctrno08NVARCHAR50主键,外键管理员登录密码sja_Ctrpassword08NVARCHAR50主键,外键3.3 关系模式的优化3.3.1 规范化处理考察关系模式的数据依赖集合,仅为函数依赖,上述关系模式都属于 BC 范式,无需规范化分解。3.3.2 模式的评价与修正1. 模式评价(1) 功能评价根据需求分析的结果,规范化后的关系模式可以支持用户的所有应用要求,且满足无损连接性。(2) 性能评价经过逻辑记录访问估算,观察到专业关系模式和班级关系模式经常需要执行连接操作,因此考虑在模式修正时合并两者。2. 模式修正为减少连接操作,提高查询效率,故将专业关系模式和班级关系模式合并。同时,考虑到专业名称和班级名称不会出现重名现象,故将班级编号作为主键,修改后得到专业班级关系模式如下:专业班级(班级编号,班级名称,专业编号,专业名称)在上述关系模式中班级编号决定专业编号,专业编号决定专业名称,班级编号决定专业名称,因此存在非主属性对主键的传递函数依赖,属于第二范式。但考虑到查询效率和专业名称使用的频率,不对该关系模式进行规范化。因此,关模式优化后最终的关系模式如下:四、物理结构设计4.1 聚簇设计聚簇是将有关的数据元组集中存放于一个物理块内或若干相邻物理块内或同一柱面内,以提高查询效率的数据存储结构。所谓聚簇设计,就是根据用户需求确定每个关系是否需要建立聚簇,如果需要,则应确定在该关系的哪些属性列上建立聚簇。当一个关系按照某些属性列建立聚簇后,关系中的元组都按照聚簇属性列的顺序存放在磁盘的一个物理块或若干相邻物理块内,因此对这些属性列的查询特别有效,它可以明显提高查询效率,但是对于非聚簇属性列的查询效果不佳。此外,数据库系统建立和维护聚簇的开销很大,每次修改聚簇属性列值或增加、删除元组都将导致关系中的元组移动其物理存储位置,并且重建该关系的聚簇。因此,只有在遇到以下一些特定情况时才考虑对一个关系建立聚簇:(1) 当对一个关系的某些属性列的访问时该关系的主要应用,而对其他属性的访问很少或是次要应用时,可考虑对该关系在这些属性列上建立聚簇;(2) 若一关系在某些属性列上的值重复率很高,则可考虑对该关系在这些组属性列上建立聚簇;(1) 若一关系一旦装入数据,某些属性列的值很少修改,也很少增加或删除元组,则可考虑对该关系在这些组属性列上建立聚簇。考虑到上述信息,对在每个关系模式的主键上建立聚簇。4.2 索引设计索引设计时数据库物理设计的基本问题,对关系选择有效的索引对提高数据 库访问效率有很大的帮助。索引也是按照关系的某些属性列建立的,它与聚簇的 不同之处在于,当索引属性列发生变化,或增加、删除元组时,只有索引发生变 化,而关系中原先元组的存放位置不受影响。此外,每个关系只能建立一个聚簇, 但却可以同时建立多个索引。 对于一个确定的关系,通常在下列情况下可以考虑建立索引:(1) 在主键属性列和外键属性列上通常都可分别建立索引,不仅有助于唯一 性检查和完整性检查,而且可以加快连接查询的速度;(2) 以查询为主的关系可建立尽可能多的索引;(3) 对等值连接,但满足条件的元组较少的查询可考虑建立索引;(4) 如果查询可以从索引直接得到结果而不必访问关系,则对此种查询可建 立索引。例如,为查询某个属性的 MIN, MAX, AVG, SUM, COUNT 等函数值,可在该属性列上建立索引。考虑到上述信息,对每个关系模式的外键都建立索引;同时,为满足最统计 同一地区学生数的需求,在学生关系模式的生源所在省和生源所在市的属性列上 分别建立索引;为满足经常查询的需求,在课程关系模式的开课学期和教师关系 模式的职称属性列上建立索引。4.3 分区设计数据库中的数据,包括关系、索引、聚簇、日志等,一般都存放在磁盘内, 由于数据量的增大,往往需要用到多个磁盘驱动器或磁盘阵列,这就产生了数据 在多个磁盘如何分配的问题,即磁盘分区设计问题。磁盘分区设计的本质市确定 数据库数据的存放位置,其目的市提高系统性能,是数据库物理设计的内容之一。 磁盘分区设计的一般原则是:(1) 减少访问冲突,提高 I/O 并行性。多个事务并发访问同一磁盘时,会产 生磁盘访问冲突而导致效率低下,如果事务访问数据能均匀分布于不同磁盘上, 则 I/O 可并发执行,从而提高数据库访问速度。(2) 分散热点数据,均衡 I/O 负担。在数据库中数据访问的频率是不均匀的, 那些经常被访问的数据称为热点数据,此类数据宜分散存放于不同的磁盘上,以 均衡各个磁盘的负荷,充分发挥多磁盘并行操作的优势。(3) 保证关键数据快速访问,缓解系统“瓶颈”。在数据库中有些数据如数 据字典等的访问频率很高,为保证对它的访问不直接影响整个系统的效率,可以 将其存放在某一固定磁盘上,以保证其快速访问。 由于高校成绩管理数据库系统的数据所需存储规模较小,因此不进行分区设 计。五、数据库实施创建数据库,如图 5-1 所示:图5-1 数据库建立5.1 基本表建立(1)教师表建立该表格包含两个列:`sja_Aacc08`和`sja_Apwd08`。`sjA_Aacc08`列是一个字符类型(CHAR),长度为12个字符,且不允许为空(NOT NULL)。它将用作表格的主键(PRIMARY KEY),这意味着每个记录在该列上必须具有唯一的值。`sja_Apwd08`列也是一个字符类型(CHAR),长度为10个字符。它使用了DEFAULT关键字,表示如果没有为该列提供值,则该列的默认值为NULL。因此,这个表格的主要目的是存储管理员账户的信息。每个管理员账户由一个唯一的12位字符编码(sja_Aacc08)和一个最长为10个字符的密码(sja_Apwd08)组成。图5-2 建立教师表(2) 专业表建立该表格包含两个列:`sja_Mno08`和`sja_Mname08`。`sja_Mno08`列是一个字符类型(CHAR),长度为10个字符,且不允许为空(NOT NULL)。它将用作表格的主键(PRIMARY KEY),这意味着每个记录在该列上必须具有唯一的值。`sja_Mname08`列也是一个字符类型(CHAR),长度为10个字符。它使用了DEFAULT关键字,表示如果没有为该列提供值,则该列的默认值为NULL。除了主键之外,还定义了一个约束(CONSTRAINT),名为`Major_Mno`。该约束确保`shengja_Majors08`表格中的`sja_Mno08`列的值是唯一的,即每个记录都必须具有不同的`sja_Mno08`值。这个表格的主要目的是存储专业(Major)的信息。每个专业由一个唯一的10位字符编码(sja_Mno08)和一个最长为10个字符的名称(sja_Mname08)组成。约束确保了每个专业编码的唯一性。图5-3 建立专业表(3) 班级表建立该表格包含三个列:`sja_Classno08`、`sja_Classname08`和`sja_Mno08`。`sja_Classno08`列是一个字符类型(CHAR),长度为10个字符,且不允许为空(NOT NULL)。它将用作表格的主键(PRIMARY KEY),这意味着每个记录在该列上必须具有唯一的值。`sja_Classname08`列也是一个字符类型(CHAR),长度为10个字符。它使用了DEFAULT关键字,表示如果没有为该列提供值,则该列的默认值为NULL。`sja_Mno08`列也是一个字符类型(CHAR),长度为10个字符。它使用了DEFAULT关键字,表示如果没有为该列提供值,则该列的默认值为NULL。除了主键之外,还定义了两个约束:1. UNIQUE约束,确保每个记录的组合值(sja_Mno08和sja_Classno08)都是唯一的。这意味着每个班级编号在给定的专业中必须是唯一的。2. FOREIGN KEY约束,将`sja_Mno08`列作为外键,引用了`shengja_Majors08`表格中的`sja_Mno08`列。这意味着`sja_Mno08`列的值必须存在于`shengja_Majors08`表格的`sja_Mno08`列中的某个记录中。同时,ON DELETE RESTRICT和ON UPDATE RESTRICT指定了在删除或更新`shengja_Majors08`表格中的记录时对关联的班级表格进行限制操作,即不允许删除或更新被引用的记录。因此,这个表格的主要目的是存储班级(Class)的信息。每个班级由一个唯一的10位字符编码(sja_Classno08)、一个最长为10个字符的名称(sja_Classname08)和对应的专业编码(sja_Mno08)组成。约束确保了班级编号和对应的专业编码的唯一性,并且与`shengja_Majors08`表格建立了外键关系。图5-4 建立班级表(4) 学生表建立该表格包含七个列:`sja_Sno08`、`sja_Sname08`、`sja_Ssex08`、`sja_Sage08`、`sja_Sorig08`、`sja_Scredits08`和`sja_Classno08`。`sja_Sno08`列是一个字符类型(CHAR),长度为12个字符,且不允许为空(NOT NULL)。它将用作表格的主键(PRIMARY KEY),这意味着每个记录在该列上必须具有唯一的值。`sja_Sname08`列是一个字符类型(CHAR),长度为20个字符。它表示学生的姓名。`sja_Ssex08`列是一个字符类型(CHAR),长度为5个字符。它表示学生的性别。`sja_Sage08`列是一个整数类型(INT),用于表示学生的年龄。`sja_Sorig08`列是一个字符类型(CHAR),长度为20个字符。它表示学生的来源地。`sja_Scredits08`列是一个整数类型(INT),表示学生的学分。`sja_Classno08`列是一个字符类型(CHAR),长度为10个字符。它表示学生所属的班级编号。除了主键之外,还定义了两个约束:1. UNIQUE约束,确保每个记录的组合值(sja_Sno08和sja_Classno08)都是唯一的。这意味着每个学生编号在给定的班级中必须是唯一的。2. FOREIGN KEY约束,将`sja_Classno08`列作为外键,引用了`shengja_Classes08`表格中的`sja_Classno08`列。这意味着`sja_Classno08`列的值必须存在于`shengja_Classes08`表格的`sja_Classno08`列中的某个记录中。同时,ON DELETE RESTRICT和ON UPDATE RESTRICT指定了在删除或更新`shengja_Classes08`表格中的记录时对关联的学生表格进行限制操作,即不允许删除或更新被引用的记录。因此,这个表格的主要目的是存储学生(Student)的信息。每个学生由一个唯一的12位字符编码(sja_Sno08)、一个最长为20个字符的姓名(sja_Sname08)、性别(sja_Ssex08)、年龄(sja_Sage08)、来源地(sja_Sorig08)、学分(sja_Scredits08)和所属班级编号(sja_Classno08)组成。约束确保了学生编号和所属班级编号的唯一性,并且与`shengja_Classes08`表格建立了外键关系。图5-5 建立学生表(5) 课程表建立图5-6 建立课程表(6) 报告表建立图5-7 建立报告表(7) 教师-班级表建立图5-8 建立教师-班级表(8) 学生-课程表建立图5-9 建立课程学习表(9) 教师-课程表建立图5-10 建立教师-课程表(10) 管理员表建立图5-11 创建登录表5.2 视图的建立(1)视图每门课程平均成绩统计的建立图5-10:每门课程平均成绩统计图5-11:学生成绩图5-12:每门课程学分统计图5-13:教师教授课程统计图5-14:班级开设课程统计v图5-15:学生生源地统计图5-16:教师课程成绩统计5.3 索引的建立图5-17:表教师唯一索引的建立图5-18:其他表唯一索引的建立5.4 触发器建立(1)更新学分:图5-19:更新学分触发器建立(2)删除学生:图5-20:删除学生触发器的建立5.5存储过程建立自动计算学分:图5-21:自动计算学分创建学生信息:图5-22:创建学生信息创建教师信息:图5-23:创建教师信息5.6 业务处理和查询功能SQL语句1)学生成绩按每学年进行成绩统计的SQL语句:图5-24学生成绩按每学年进行成绩统计运行结果2)学生成绩名次排定SQL语句: 图5-25学生成绩名次排定运行结果3)每门课程平均成绩统计SQL语句:图5-26每门课程平均成绩统计运行结果4)学生所学课程及学分统计SQL语句:图5-27学生所学课程及学分统计运行结果5)输入每个学生成绩时,自动生成该学生已修总学分SQL语句:图5-28自动生成该学生已修总学分运行结果图5-29自动生成该学生已修总学分运行结果图5-30自动生成该学生已修总学分运行结果图5-31自动生成该学生已修总学分运行结果6)学生成绩查询SQL语句:图5-32学生成绩查询运行结果7)教师任课查询SQL语句:图5-33教师任课查询运行结果8)班级课程开设查询SQL语句:图5-34班级课程开设查询运行结果六、应用系统开发与试运行6.1 开发平台和开发环境介绍(1)硬件环境:处理器    Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz 2.59 GHz机带 RAM    16.0 GB (15.8 GB 可用)系统类型    64 位操作系统, 基于 x64 的处理器(2) 软件环境:系统:windows 10 64家庭教育版数据库软件:Microsoft SQLSever2014应用系统开发环境:IntelliJ IDEA 2019.1.1 x64, Tomcat 8.0.50,6.2 前台界面与后台数据库连接说明,代码实现Web端与SQL连接代码:const { Client } = require('pg');var sql = `SELECT r.sja_Cno08, c.sja_Cname08, Round(AVG(r.sja_Grade08),2) as AvgGradeFROM shengja.shengja_Reports08 rJOIN shengja.shengja_Courses08 c ON c.sja_Cno08 = r.sja_Cno08GROUP BY r.sja_Cno08, c.sja_Cname08; `;const client = new Client({ host: '192.168.198.129', port: 26000, database: 'shengjamis08', user: 'opengaussuser', password: 'openGauss@123',});// 连接数据库client.connect((err) => { if (err) { console.error('Failed to connect to database:', err); } else { console.log('Connected to database'); // 在连接成功后可以执行其他数据库操作 client.query(sql, (err, result) => { if (err) { console.error('Error executing query:', err); } else { console.log('Query result:', result.rows); } // 关闭数据库连接 // client.end(); }); }});module.exports = { query: (sql) => client.query(sql),};首先,通过`require('pg')`引入了`pg`库,它是一个用于连接和操作PostgreSQL数据库的Node.js库。然后,定义了一个SQL查询语句,该查询语句从表格`shengja_Reports08`和`shengja_Courses08`中检索数据,计算每个课程的平均成绩,并返回课程编号(sja_Cno08)、课程名称(sja_Cname08)和平均成绩(AvgGrade)。接下来,创建了一个`Client`对象,配置了连接数据库所需的信息,包括主机名、端口号、数据库名称、用户名和密码。使用`client.connect()`方法连接到数据库。如果连接成功,输出"Connected to database"。如果连接失败,输出"Failed to connect to database"。在成功连接数据库后,使用`client.query()`方法执行SQL查询。传入查询语句和一个回调函数作为参数。回调函数用于处理查询结果。如果查询成功,输出查询结果的行数据;如果查询失败,输出错误信息。最后,通过`module.exports`将`query`方法导出,使其可以在其他模块中使用。`query`方法接受一个SQL语句作为参数,并使用`client.query()`方法执行该查询。总体而言,以上代码的功能是连接到指定的PostgreSQL数据库,执行给定的SQL查询语句,并将查询结果输出到控制台。6.3 系统各功能设计和运行界面截图1) 登陆界面在正式进入系统前,系统会要求用户输入账号和密码进行登录。图6-1系统登录界面2) 欢迎界面进入系统后,对用户显示欢迎信息。图6-2系统登录界面3) 学生成绩查询界面-学年成绩查询展示所选学年中学生学号,选修课程以及成绩图6-3学年成绩查询界面4) 学年排名查询界面展示所选学年学生的平均绩点以及排名图6-4学年排名查询界面5) 指定学号查询界面展示指定学生的课程成绩信息图6-5指定学号查询界面6) 学生成绩编辑界面修改编辑所选学生指定课程成绩图6-6学生成绩编辑界面7) 学生成绩插入及删除界面插入及删除所选学生选课信息以及成绩图6-7学生成绩插入界面图6-8学生成绩插入结果界面图6-9学生成绩删除界面8) 课程平均成绩查询界面查询各课程学生平均成绩图6-10课程平均成绩查询界面9) 班级课程查询界面查询指定班级开设课程图6-11班级课程查询界面10) 生源地统计界面统计学生生源地图6-12生源地统计界面11) 教师任课查询界面查询指定教师或所有教师任课信息图6-13教师任课查询界面
  • [问题求助] 华为openGauss数据库有哪些优点
    相比于市面上其他的数据库,openGauss数据库还有哪些优点
  • [问题求助] 【求助】请问下各位大神,华为openGauss的服务器工具 gs_restore 的下载页面究竟藏在那里?
    我苦苦搜寻,始终没有找到可用的下载连接。这个工具是需要开一台云数据库才能获取到吗?求解。
总条数:66 到第
上滑加载中