前端技术
HTML
CSS
Javascript
前端框架和UI库
VUE
ReactJS
AngularJS
JQuery
NodeJS
JSON
Element-UI
Bootstrap
Material UI
服务端和客户端
Java
Python
PHP
Golang
Scala
Kotlin
Groovy
Ruby
Lua
.net
c#
c++
后端WEB和工程框架
SpringBoot
SpringCloud
Struts2
MyBatis
Hibernate
Tornado
Beego
Go-Spring
Go Gin
Go Iris
Dubbo
HessianRPC
Maven
Gradle
数据库
MySQL
Oracle
Mongo
中间件与web容器
Redis
MemCache
Etcd
Cassandra
Kafka
RabbitMQ
RocketMQ
ActiveMQ
Nacos
Consul
Tomcat
Nginx
Netty
大数据技术
Hive
Impala
ClickHouse
DorisDB
Greenplum
PostgreSQL
HBase
Kylin
Hadoop
Apache Pig
ZooKeeper
SeaTunnel
Sqoop
Datax
Flink
Spark
Mahout
数据搜索与日志
ElasticSearch
Apache Lucene
Apache Solr
Kibana
Logstash
数据可视化与OLAP
Apache Atlas
Superset
Saiku
Tesseract
系统与容器
Linux
Shell
Docker
Kubernetes
[MySQL数据库shtd_store表结...]的搜索结果
这里是文章列表。热门标签的颜色随机变换,标签颜色没有特殊含义。
点击某个标签可搜索标签相关的文章。
点击某个标签可搜索标签相关的文章。
转载文章
...和下单的总金额,存入MySQL数据库shtd_store的nationeverymonth表(表结构如下)中,然后在Linux的MySQL命令行中根据订单总数、消费总额、国家表主键三列均逆序排序的方式,查询出前5条,将SQL语句与执行结果截图粘贴至对应报告中; spark.sql("select nationkey,regexp_replace(nationname,'\'','') as nationname,regionkey,regexp_replace(regionname,'\'','') as regionname,sum(totalnum) as totalorder,sum(totalprice) as totalconsumption,year,month from nationeverymonth group by nationkey,regionkey,month,nationname,year,regionname;") 我为了方便查询和之后的操作,将上面的查询结果导入到新表nationeverymonths 查表 接下来将hive中的数据导入mysql中 package com.atguigu.spark.sqlimport org.apache.spark.SparkConfimport org.apache.spark.sql.SparkSessionimport java.util.Propertiesobject DataHiveToMySQL {def main(args: Array[String]): Unit = {val sparkConf = new SparkConf().setMaster("local[]").setAppName("sparkSQL")val spark = SparkSession.builder().enableHiveSupport().config(sparkConf).getOrCreate()val result=spark.sql("select from ods.nationeverymonths")val props=new Properties()props.setProperty("user","root")props.setProperty("password","123456")props.setProperty("driver","com.mysql.jdbc.Driver")result.write.mode("overwrite").jdbc("jdbc:mysql://192.168.230.132:3306/user?serverTimezone=UTC&characterEncoding=UTF-8&useSSL=false", "nationeverymonth", props)println("导入成功")spark.stop()} } 运行可见导入成功 进入MySQL中查看结果 可见数据成功导入 接下来按照要求查询: 2.请根据dwd层表计算出某年每个国家的平均消费额和所有国家平均消费额相比较结果(“高/低/相同”),存入MySQL数据库shtd_store的nationavgcmp表(表结构如下)中,然后在Linux的MySQL命令行中根据订单总数、消费总额、国家表主键三列均逆序排序的方式,查询出前5条,将SQL语句与执行结果截图粘贴至对应报告中; 在解这道题的时候遇见一个问题,在求所有国家平均消费额的时候一直报错,由于没有数据这道题的题意还是有点没看明白,于是我就用了最简单的办法先新增一列,再单独将所有国家平均消费额求出来然后再插入,如果各位大佬有解决这个问题的办法希望能指导一下 先将每个国家的平均消费额求出来 spark.sql("select nationkey,nationname,avg(totalconsumption) as nationavgconsumption from nationeverymonths group by nationkey,nationname") 再新增一列所有国家平均消费额 spark.sql("alter table nationeverymonths add columns(avg_allstring)") 再将查询到的所有国家平均消费额导入进去 spark.sql("insert overwrite table nationeverymonths1 select nationkey,nationname,avg_totalconsumpt,1500 from nationeverymonths1") 再次查表 按照题意添加比较结果字段 spark.sql("select ,case when avg_totalconsumpt>avg_all then '高' when avg_totalconsumpt<avg_all then '低' when avg_totalconsumpt=avg_all then '相同' else 'null' end as comparison from nationeverymonths1").show 最后的排序语句和题一一样 本篇文章为转载内容。原文链接:https://blog.csdn.net/guo_0423/article/details/126352162。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-09-01 10:55:33
319
转载
Datax
在大数据处理与迁移的实际场景中,唯一键约束冲突只是众多可能遇到的问题之一。最近,业界对数据一致性、完整性和精准性问题的关注度日益提升,特别是在云服务和分布式数据库广泛普及的当下,如何避免类似Datax Writer写入时的约束冲突显得更为关键。 2021年,一篇发表在《计算机工程》杂志上的论文深入探讨了数据预处理的重要性,并提出了一种基于机器学习的实时去重算法,能够在海量数据导入数据库之前有效识别并剔除重复项,从而减少唯一键冲突的发生概率。同时,该研究还强调了数据库设计阶段应遵循的原则,包括合理规划主键和唯一键约束,以及运用范式理论优化表结构设计,降低冗余和冲突风险。 另外,近期Amazon Redshift等主流云数据库服务提供商也在其产品更新中强化了对唯一键冲突检测与修复的功能支持,通过智能化的数据加载策略和错误反馈机制,帮助用户在数据迁移过程中更高效地应对约束冲突问题。 因此,在实际工作中,我们不仅要关注具体工具如Datax的操作技巧,更要紧跟行业前沿动态和技术发展趋势,从数据全生命周期管理的角度出发,综合运用先进的预处理技术与最佳实践的数据库设计理念,才能确保在大规模数据操作过程中既能满足业务需求,又能有效规避各类潜在问题。
2023-10-27 08:40:37
721
初心未变-t
转载文章
... 最终找到办法,就是mysql设置的问题,有my.ini的就找这个文件,没有的就找my.cnf(这个一般都在/ect/my.conf) 本作者使用的CentOS7.6系统: 然后打开MySql配置文件 然后找到[MySql] 然后找 sql-mode=STRICT_TRANS_TABLESNO_ENGINE_SUBSTITUTION 问题原因: 主要是MySQL使用了严格验证方式: 解决方法: 直接把sql-mode模式改变下 这个可能你我的不相同,你只要找到sql-mode 就好 然后把这句删掉,改成: sql-mode=NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION 然后在重启数据库 service mysqld restart 完美解决 更多教程:www.zcxsmart.com 本篇文章为转载内容。原文链接:https://blog.csdn.net/LizmWintac/article/details/126901852。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-12-02 23:16:25
289
转载
MySQL
MySQL 是一款普遍的关联型DBMS,我们可以通过一些基础操作来看 MySQL 中的表格基本信息。 首先,我们需要登陆到 MySQL 数据库中。下面是用命令行方式登陆 MySQL 的示例脚本: mysql -h host -u user -p 其中, host 表示 MySQL 数据库服务器 IP 地址或服务器名称, user 是接入 MySQL 数据库所使用的账户名, -p 是要求输入口令,用于校验登陆。 接着,我们可以查看 MySQL 中当前所有的数据库,使用 的命令为: SHOW DATABASES; 然后,我们需要选择一个数据库进行操作,使用的命令为: USE database; 其中, database 表示需要操作的数据库名称。 现在,我们已经成功进入到了 MySQL 数据库中,可以看到库中的表格基本信息,使用命令如下: SHOW TABLES; 执行该命令后,MySQL 将会显示该库中所有的表名称。 最后,我们可以查看特定表中的所有信息,使用的命令如下: DESCRIBE table; 其中, table 表示需要查看的表名称。 通过上述基础操作,我们可以轻松地了解 MySQL 数据库中的基础表信息。
2023-08-18 09:15:20
62
算法侠
MySQL
在理解了MySQL中创建表的基本语法和关键要素后,我们可以进一步探讨数据库设计的实战应用以及最新技术动态。近期,随着MySQL 8.0版本的发布,对InnoDB存储引擎进行了多项性能优化和功能增强,例如提高了并发性、支持窗口函数等,使得在创建新表时,开发者可以充分利用这些新特性提升数据处理效率。 此外,对于表结构设计与字段选择的实际案例分析也尤为重要。例如,在构建电商系统时,用户订单表的设计可能不仅包括用户ID、商品ID等基础信息,还会涉及交易状态、下单时间等业务逻辑相关的字段,并且为了保证数据一致性,主键设计通常采用复合主键或者UUID以应对高并发场景下的自增主键冲突问题。 另外,关于字符集的选择,虽然UTF8仍然是广泛应用的标准,但随着全球化的深入发展,对于包含更多特殊字符或 emoji 的应用场景,MySQL 8.0 版本还引入了utf8mb4字符集的支持,能够存储更多的Unicode字符,确保更全面的语言兼容性。 同时,数据库设计中的注释规范也不容忽视,良好的注释不仅可以方便团队成员间的协作沟通,还能为后续的数据库维护、数据分析提供清晰的上下文信息。在实际工作中,建议遵循一定的数据库注释标准,如使用统一的注释格式,详细描述列的作用、数据来源及更新规则等,提高数据库的整体可读性和管理效率。 总之,MySQL建表只是数据库设计与管理的第一步,深入学习和掌握如何根据业务需求合理设计表结构、选择合适的数据类型及存储引擎,关注数据库技术的发展趋势,将有助于我们更好地构建高效、稳定、易于维护的数据库系统。
2023-10-30 22:22:20
117
码农
Datax
在处理大数据传输和交换任务时,Datax作为一款高效的数据同步工具,其最大行数限制问题的解决方案具有广泛的应用价值。近期,随着数据量爆炸式增长,越来越多的企业和团队在使用Datax进行大规模数据迁移或整合过程中,可能会频繁遭遇此类问题。因此,深入理解和灵活应对这一限制显得尤为重要。 在实际操作中,不仅需要根据数据量合理分批处理,还应关注Datax的并发配置优化以及数据库表结构设计,如MySQL、Oracle等目标库可能存在的max insert row count参数设置。同时,通过实时监控系统性能与资源占用情况,可以更精准地调整Datax作业参数,以适应不断变化的数据处理需求。 此外,随着技术的发展,不少云服务商也针对此类场景推出了更高级别的数据迁移服务,支持自动分片、动态扩容等功能,从而有效避免单次操作的数据量限制问题。例如,阿里云推出的DTS(Data Transmission Service)就提供了超大数据量下的稳定、高效迁移方案,用户无需过于关注底层细节,即可实现大规模数据的无缝迁移。 总之,在面对Datax或其他数据同步工具的最大行数限制挑战时,一方面要掌握并运用现有工具的高级配置技巧,另一方面也要关注业界最新的数据迁移服务和技术趋势,以提升整体数据处理效率和可靠性,更好地满足业务发展对数据处理能力的需求。
2023-08-21 19:59:32
525
青春印记-t
HBase
...探讨与实战解析 在大数据处理领域,HBase作为一款开源、分布式、面向列的NoSQL数据库,因其卓越的大数据存储和实时查询能力而备受青睐。然而,在面对人山人海的数据量和每秒上万次的访问压力时,怎样才能让HBase这个大块头更聪明地使用I/O和CPU资源,从而跑得更快、更强,无疑变成了一项既关键又颇具挑战性的任务。本文将通过实例剖析与实战演示的方式,引导你一步步探寻优化策略。 1. HBase I/O优化策略 1.1 数据块大小调整 HBase中的Region是其基本的数据存储单元,Region内部又由多个HFile组成,而每个HFile又被划分为多个数据块(Block Size)。默认情况下,HBase的数据块大小为64KB。如果数据块太小,就像是把东西分割成太多的小包装,这样一来,每次找东西的时候,就像翻箱倒柜地找小物件,不仅麻烦还增加了I/O操作的次数,就像频繁地开开关关抽屉一样。反过来,如果数据块太大,就好比你一次性拎一大包东西,虽然省去了来回拿的功夫,但可能会导致内存这个“仓库”空间利用得不够充分,有点儿大材小用的感觉。根据实际业务需求及硬件配置,适当调整数据块大小至关重要: java Configuration conf = HBaseConfiguration.create(); conf.setInt("hbase.hregion.blocksize", 128 1024); // 将数据块大小设置为128KB 1.2 利用Bloom Filter降低读取开销 Bloom Filter是一种空间效率极高的概率型数据结构,用于判断某个元素是否在一个集合中。在HBase中,启用Bloom Filter可以显著减少无效的磁盘I/O。以下是如何在表级别启用Bloom Filter的示例: java HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf("myTable")); tableDesc.addFamily(new HColumnDescriptor("cf").set BloomFilterType(BloomType.ROW)); admin.createTable(tableDesc); 2. HBase CPU优化策略 2.1 合理设置MemStore和BlockCache MemStore和BlockCache是HBase优化CPU使用的重要手段。MemStore用来缓存未写入磁盘的新写入数据,BlockCache则缓存最近访问过的数据块。合理分配两者内存占比有助于提高系统性能: java conf.setFloat("hbase.regionserver.global.memstore.size", 0.4f); // MemStore占用40%的堆内存 conf.setFloat("hfile.block.cache.size", 0.6f); // BlockCache占用60%的堆内存 2.2 精细化Region划分与预分区 Region数量和大小直接影响到HBase的并行处理能力和CPU资源分配。通过对表进行预分区或适时分裂Region,可以避免热点问题,均衡负载,从而提高CPU使用效率: java byte[][] splits = new byte[][] {Bytes.toBytes("A"), Bytes.toBytes("M"), Bytes.toBytes("Z")}; admin.createTable(tableDesc, splits); // 预先对表进行3个区域的划分 3. 探讨与思考 优化HBase的I/O和CPU使用率是一个持续的过程,需要结合业务特性和实际运行状况进行细致分析和调优。明白了这个策略之后,咱们就得学着在实际操作中不断尝试和探索。就像调参数时,千万得瞪大眼睛盯着系统的响应速度、处理能力还有资源使用效率这些指标的变化,这些可都是我们判断优化效果好坏的重要参考依据。 总之,针对HBase的I/O和CPU优化不仅关乎技术层面的深入理解和灵活运用,更在于对整个系统运行状态的敏锐洞察和精准调控。每一次实践都是对我们对技术认知的深化,也是我们在大数据领域探索过程中不可或缺的一部分。
2023-08-05 10:12:37
506
月下独酌
Cassandra
对于时间序列数据,如何设计Cassandra表结构? 在处理海量时序数据的场景下,Apache Cassandra是一个非常出色的选择。它的分布式架构以及对大数据读写操作的高度优化,使其成为存储和查询时间序列数据的理想平台。不过,有效地利用Cassandra的前提是精心设计数据模型。本文将带你手把手地深入挖掘,如何为时间序列数据量身打造Cassandra的表结构设计。咱会借助实例代码和亲身实战经验,像揭开宝藏地图那样揭示其中的设计秘诀,让你明明白白、实实在在地掌握这门技艺。 1. 理解时间序列数据特点 时间序列数据是指按时间顺序记录的一系列数据点,每个数据点通常与一个特定的时间戳相关联。这类数据在咱们日常生活中可不少见,比如物联网(IoT)、监控系统、金融交易还有日志分析这些领域,都离不开它。它的特点就是会随着时间的推移,像滚雪球一样越积越多。而在查询的时候,人们最关心的通常就是最近产生的那些新鲜热辣的数据,或者根据特定时间段进行汇总统计的信息。 2. 设计原则 (1)分区键选择 在Cassandra中,分区键对于高效查询至关重要。当你在处理时间序列数据时,一个很接地气的做法就是拿时间来做分区的一部分。比如说,你可以把年、月、日、小时这些信息拼接起来,弄成一个复合型的分区键。这样一来,同一时间段的数据就会乖乖地呆在同一个分区里,这样咱们就能轻松高效地一次性读取到这一整段时期的数据了,明白吧? cql CREATE TABLE sensor_data ( sensor_id uuid, event_time timestamp, data text, PRIMARY KEY ((sensor_id, date_of(event_time)), event_time) ) WITH CLUSTERING ORDER BY (event_time DESC); 这里date_of(event_time)是对事件时间进行提取日期部分的操作,形成复合分区键,便于按天或更粗粒度进行分区。 (2)排序列簇与查询路径 使用CLUSTERING ORDER BY定义排序列簇,按照时间戳降序排列,确保最新数据能快速获取。 (3)限制行大小与集合使用 尽管Cassandra支持集合类型,但对于时间序列数据,应避免在一个集合内存放大量数据,以免读取性能受到影响。由于集合不会分页,如果需要存储连续的时序数据点,最好让每一行只包含单个数据点。 (4)宽行与稀疏索引 采用“宽行”策略,即每行代表一段时间窗口内的多个数据点属性,而不是每条数据一个行。这有助于减少跨分区查询,提高查询效率。同时呢,对于那些跟时间没关系的筛选条件,我们可以琢磨着用一下稀疏索引。不过得注意啦,这里有个“度”的把握,就是索引虽然能让查询速度嗖嗖提升,但同时也会让写入数据时的开销变大。所以嘞,咱们得在这两者之间找个最佳平衡点。 3. 示例设计 物联网传感器数据存储 假设我们有一个物联网项目,需要存储来自不同传感器的实时测量值: cql CREATE TABLE sensor_readings ( sensor_id uuid, reading_time timestamp, temperature float, humidity int, pressure double, PRIMARY KEY ((sensor_id, reading_time)) ) WITH CLUSTERING ORDER BY (reading_time DESC); 这个表结构中,sensor_id和reading_time共同组成复合分区键,每个传感器在某一时刻的温度、湿度和压力读数都存放在一行里。 4. 总结与思考 设计Cassandra时间序列数据表的关键在于理解数据访问模式并结合Cassandra的特性和局限性。选对分区键这招儿,就像给海量数据找个宽敞的储藏室,让它们能分散开来存放和快速找到;而把列簇整得井井有条,那就相当于帮我们轻松摸到最新鲜的数据,一抓一个准儿。再配上精心设计的宽行结构,加上恰到好处的索引策略,甭管查询需求怎么变花样,都能妥妥地满足你。 当然,具体实践时还需要根据业务的具体情况进行调整和优化,例如预测未来的数据增长规模、评估查询性能瓶颈以及是否需要进一步的数据压缩等措施。总的来说,用Cassandra搭建时间序列数据模型不是个一劳永逸的事儿,它更像是一个持久的观察、深度思考和反复调整优化的过程。只有这样,我们才能真正把Cassandra处理海量时序数据的洪荒之力给释放出来。
2023-12-04 23:59:13
769
百转千回
转载文章
...le 表名(属性名 数据类型[约束条件],…); Paimary key 主键 auto_increment自增 foreign key 外键 references 另一表名(字段名).–>外键这个表连接着另外一个表的哪个键. 删除表: drop table 表名;–>表结构也删除了(也即是这个表没了) Truncate table 表名 --> 只删除表中数据,表结构不会删除. 2.In 与 not in 在或不在这个(1,3)里面,单个查询,只会查询(1或者3) 3.Between and 与 not … 和上面差不多,Between 1 and 3 但是这个是范围查询(1,3) 1-3 之间(包含1,3) 4.Like,模糊查询 “%” 代表任意字符,”_”代表单个字符. 5.Is Not null 与 is null 是否为空 6.And 与 or 一个是所有条件都要完成,or则是任何一个条件完成即可 7.Distinct 去重 8.Order by age asc 与 desc 排序,假如根据age排序,asc正序(升序默认),desc倒叙(降序) 9.Gruop by 分组查询,单独使用无意义,group_concat(字段),拼接,若是根据age group by 则会发现age一样的会出现在同一字段内 例如: : 最后要注意group by 后面的字段与所查字段的关系(一对一),当然还有having,having和where基本一样,只不过跟在group by后面. 10.Limit 分页查询 limit 0,5 .查询前5条数据,从0开始,5结束,但是5取不到,也即是取头不取尾. 11.聚合函数:count() 查询数据的总数据量 经常使用别名 例如:as total sum(字段)函数:求和…若字段为成绩,where条件或gruop by 为个人的id,那么查出的就是个人的成绩总分. AVG(字段),但是查的是平均分,min(字段)与max(字段) 查出最小或最大. 三者都类似sum(),当然max()与min()若是在最前面使用,就会当条件查询只会出来这一笔数据.例如: 12.Sql多表查询,内连接不只是inner join,平时写的from a表,b表 where 条件这也是内连接,意思就是两张表中数据都有才可以查询出来 13.而外连接分为左连接和右连接,意思是以左表或右表为主,假如两张表,左表数据多,右表数据少,且条件符合,则左连接的时候左表数据全部出来,右表没有的为null,反之也是一样. 14.Exist() 与 not exist() …()内的数据是否为空,若是为空则代表false,返回数据为空,若不为空,则代表true,正常查询. 15.Any 与 all 例如 age > any(age1,age2) 大于两者中的一个就可以,但是all的情况下则是全部大于.也就是相当于,any为大于最小的,all则是大于最大的就行了,当然若是小于号那就是另外一种情况了,另外分析. 16.Union,(也就是联合的意思,自带distinct,重复的去除)用法,例如两张表的id要全部查出来,则:select id from A union select id from B ,若Aid为1,2,3,Bid为1,2,4.则查出来的数据为1.2.3.4,若是union all,则不带distinct,用法一样,查出来以后为1.2.3.1.2.4. 17.给表取别名,表名 空格 别名 给字段取别名 字段名 as 别名. 18.Insert插入数据时若是使用insert into 表名 values();主键必须到写进去,当然与其他数据不相同即可,若是自增,可以写null.若是insert into 表名(字段)values(值),这时插入数据,字段不用写主键字段,写入其他数据字段名与值就可以完成数据的添加.(主键自己生成为前提,UUID,auto_increament都可以). 19.Insert into 插入多条数据时,其他与18一样,只不过由values()变成了values(),(),(); 20.索引是由数据库表中一列或多列组合而成,其作用提高对表数据的查询速度.像图书目录. 优缺点:优:提高了查询数据的效率.缺:创建和维护索引的时间增加了(内容改了,目录也要改). 21.索引分类:普通索引,唯一性索引UNIQUE(unique修饰,例如主键),全文索引FULLTEXT(创建在文本上,例如:char,varchar,varchar2等,mysql默认引擎不支持,),单列索引:单个字段建立索引,多列索引:多个字段创建一个索引,空间索引SPATIAL:不常用(mysql默认引擎不支持) 22.创建索引: index为关键字,或者key (1)可以index(字段名)–>普通索引 (2)Unique index(字段名)–>唯一索引 (3)Unique index 别名(字段名)–>取别名的唯一索引 (4)index 别名(字段名1,字段名2)–>取别名的多列索引 1.创建表的时候创建索引, 前三个为参数修饰,唯一性,全文,空间索引; 2.在已存在的表上创建索引,或者用ALTER TABLE 表名 ADD 索引,也就是用修改表的形式来创建索引 Create index 索引别名 on 表名(字段名) -->普通单列索引 Create index 索引别名 on 表名(字段名1,字段名2) -->多列索引 Create unique index 索引别名 on 表名(字段名) -->唯一单列索引 Alter table 表名 add +(1)|(2)|(3)|(4)即可. 23.删除索引: drop index 索引名 on 表名. 24.NOW(); mysql的函数,表示当前时间 25.视图:是一个虚拟的表,没有物理数据,是从其他表中导出的数据,当原表数据发生改变时,视图数据也会发生改变,反之也一样. (1)作用:操作简单化;增加数据安全性:不直接对表进行操作;提高表的逻辑性:原表修改字段对视图无影响. (2)创建视图:语法:create view 视图名 as 查询语句. 例如:create view vi as select id,name from user;–>这是把user中id,name字段的数据写入到vi视图中. 若是想自己定义字段名不用查出的字段名,可以如下面这样写. 例如:create view vi(vi_id,vi_name) as select id,name from user;–>这样的话id对应vi_id,name对应vi_name; 上面的都是单表的视图,多表的视图也是一样的,只不过后面的单表查询变成多表查询了. 建议创建视图后自己定义字段名,也即是定义别名. (3)查看视图: Describe(desc) 视图名–>查看视图基本信息 Show table status like ‘视图名’ --> 查看视图基本信息 Show create view 视图名 --> 视图详细信息,建表具体信息. 在view表中查看视图详细信息–>view 系统表 自带的. (4)修改视图:修改使徒的定义 Create or replace view 没有的话就创建,有的话就替换 例如:Create or replace view vi(id,name) as select语句. Alter view 只修改不能创建(也就是说视图必须存在的情况下才可修改) Alter view vi as select语句 (5)更新视图:视图是虚拟的,对视图进行的crud操作都会对原表的数据产生影响. 也就是说对视图的操作最后都会转换为对视图所连接那个表的操作. (6)删除视图:删除数据库中已存在的视图,视图为虚表,因此只会删除结构,不会删除数据. Drop view if exist 视图名. 26.触发器:由事件来触发某个操作,这些事件包括insert语句,update语句和delete语句.当数据库系统执行这些事件时,就会激活触发器执行相应的方法. 创建触发器:create trigger 触发器名 (before/after) 触发事件 on 表名 for each row sql语句. 这里的new是指代新插入的拿一条数据(更新的也算),若是old的话,指的是删除的那一条数据(更新之前的数据).(new和old属于过渡变量) 这条触发器的意思时:当t_book有插入数据时,就会根据新插入数据的id找到t_bookType的id,并试该条数据的bookNum加1. Begin与end写sql语句,中间可以写多条sql语句用分号;分隔开…也即是说语句要写完成,不能少分号. Delimiter | 设置分隔符,要不然好像只会执行begin与and之间的第一条sql语句. 查看触发器: 1.show triggers; 语句查看触发器信息.(查询所有的触发器) 2.在triggers表中查看触发器信息.(在数据库原始表triggers中可以查看) 删除触发器: Drop trigger 触发器名称 ; 27.函数: (1)日期函数: CURDATE()当前日期,CURTIME()当前时间,MONTH(d):返回日期d中的月份值,范围试1-12 (2)字符串函数:CHAR_LENGTH(s) 计算字段s值->字符串的长度.UPPER(s) 把该字段的值中所有英文都变成大写,LOWER(s) 和相面相反->把英文都变成小写. (3)数学函数:sum():求和,ABS(s) 求绝对值,SQRT(s):求平方根,mod(x,y),求余x/y (4)加密函数:PASSWORD(STR) 一般对密码加密 不可逆… MD5(STR) 普通加密 ,不可逆. ENCODE(str,pswd_str) 加密函数,结果是一个二进制文件,用blob类型的字段保存,pswd_str类似一个加密的钥匙,可以随便写. DECODE(被加密的值,pswd_str)–>对encode进行解密. 28.存储过程: (1)存储过程和函数:两者是在数据库中定义一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句.存储过程和函数可以避免重复的写一些sql语句,而且存储过程是在mysql服务器中存储和执行的,减少客户端和服务器端的数据传输.(类似于java代码写的工具类.) (2)创建存储过程和函数: Create procedure 关键字 pro_book 存储过程名称, in 输入 bT 输入参数名称 int 输入参数类型 out 输出 count_num 输出参数名称 int 输入参数类型 Begin 过程开始 end过程结束 中间是sql语句, Delimiter 默认是分号,而他的作用就是若是遇见分号时就开始执行该过程(语句),但是一个存储过程可能有很多sql语句且以分号结束,若这样的情况下当第一条sql语句结束后就会开始执行该过程,产生的后果是创建过程时,执行到第一个分号就会开始创建,导致存储过程创建错误.(若是有多个参数,在多条sql中均有参数,第一条设置完执行了,而这时第二条的参数有可能还么有设置完成,导致sql执行失败.)因此,需要把默认执行过程的demiliter关键字的默认值改为其他的字符,例如上面的就是改为&&,(当然我认为上面就一条sql语句,改不改默认的demiliter的默认值都一样.) . 使用navicat的话不使用delimiter好像也是可以的. Reads sql data则是上面图片所提到的参数指定存储过程的特性.(这个是指读数据,当然还有写输入与读写数据专用的参数类型.)看下图 经常用contains sql (应该是可以读,) 这个是调用上面的存储过程,1为入参,@total相当于全局变量,为出参. 这是一个存储函数,create function 为关键字,fun_book为函数名称, 括号里面为传入的参数名(值)以及入参的类型.RETURNS 为返回的关键字,后面接返回的类型. BEGIN函数开始,END函数结束.中间是return 以及查询数据的sql语句, 这里是指把bookId 传进去,通过存储函数返回对应的书本名字, ---------存储函数的调用和调用系统函数一样 例如:select 存储函数名称(入参值) Select 为查询 func_book 为存储函数名 2为入参值. (3)变量的使用:declaer:声明变量的值 Delimiter && Create procedure user() Begin Declare a,b varchar2(20) ; — a,b有默认的值,为空 Insert into user values(a,b); End && Delimiter ; Set 可以用来赋值,例如: 可以从其他表中查询出对应的值插入到另一个表中.例如: 从t_user2中查询出username2与password2放入到变量a,b中,然后再插入到t_user表中.(当然这只是创建存储过程),创建完以后,需要用CALL 存储过程名(根据过程参数描写.)来调用存储过程.注意:这一种的写法只可以插入单笔数据,若是select查询出多笔数据,因为无循环故而会插入不进去语句,会导致倒致存储过程时出错.下面的游标也是如此. (4)游标的使用.查询语句可能查询出多条记录,在存储过程和函数中使用游标逐条读取查询结果集中的记录.游标的使用包括声明游标,打开游标,使用游标和关闭游标.游标必须声明到处理程序之前,并且声明在变量和条件之后. 声明:declare 游标名 curson for 查询sql语句. 打开:open 游标名 使用:fetch 游标名 into x, 关闭:close 游标名 ----- 游标只能保存单笔数据. 类似于这一个,意思就是先查询出来username2,与password2的值放入到cur_t_user2的游标中(声明,类似于赋值),然后开启->使用.使用的意思就是把游标中存储的值分别赋值到a,b中,然后执行sql语句插入到t_user表中.最后关闭游标. (5)流程控制的使用:mysql可以使用:IF 语句 CASE语句 LOOP语句 LEAVE语句 ITERATE 语句 REPEAT语句与WHILE语句. 这个过程的意思是,查询t_user表中是否存在id等于我们入参时所写的id,若有的情况下查出有几笔这样的数据并且把数值给到全局变量@num中,if判断是否这样的数据是否存在,若是存在执行THEN后面的语句,即使更新该id对应的username,若没有则插入一条新的数据,最后注意END IF. 相当于java中的switch case.例如: 这里想当然于,while(ture){ break; } 这里的意思是,参数一个int类型的参数,loop aaa循环,把参数当做主键id插入到t_user表中,每循环一次参入的参数值减一,直到参数值为0,跳出循环(if判断,leave实现.) 相当于java的continue. 比上面的多了一个当totalNum = 3时,结束本次循环,下面的语句不在执行,直接执行下一次循环,也即是说插入的数据没有主键为3的数据. 和上面的差不多,只不过当执行到UNTIL时满足条件时,就跳出循环.就如上面那一个意思就是当执行到totalNum = 1时,跳出循环,也就是说不会插入主键为0的那一笔数据 当while条件判断为true时,执行do后面的语句,否则就不再执行. (6)调用存储过程和函数 CALL 存储过程名字(参数值1,参数值2,…) 存储函数名称(参数值1,参数值2,…) (7)查看存储过程和函数. Show procedure status like ‘存储过程名’ --只能查看状态 Show create procedure ‘存储过程名’ – 查看定义(使用频率高). 存储函数查看也和上面的一样. 当然还可以从information_schema.Routines中(系统数据库表)查看存储过程与函数. (8)修改存储过程与函数: 修改存储过程comment属性的值 ALTER procedure 存储过程名 comment ‘新值’; (9)删除存储过程与函数: DROP PROCEDURE 存储过程名; DROP function 存储函数名; 29.数据备份与还原: (1)数据备份:数据备份可以保证数据库表的安全性,数据库管理员需要定期的进行数据库备份. 命令:使用mysqldump(下图),或者使用图形工具 Mysqldump在msql文件夹+bin+mysqldump.exe中,相当于一个小软件.执行的话是在dos命令窗操作的. 其实就是导出数据库数据,在navacat中可以如下图导出 (2)数据还原: 若是从navacat中就是把外部的.sql文件数据导入到数据库中去.如下图 本篇文章为转载内容。原文链接:https://blog.csdn.net/qq_42847571/article/details/102686087。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-04-26 19:09:16
83
转载
Mongo
NoSQL数据库系统 , NoSQL(Not Only SQL)是一种非关系型数据库管理系统,与传统的关系型数据库相比,它不依赖于固定的表结构和模式,更注重水平扩展和大数据处理能力。在MongoDB中,数据以文档的形式存储,每个文档可以有独特的键值对集合,允许灵活的数据模型和高效的读写操作。 副本集 , 在MongoDB中,副本集是一个包含多个数据复制节点的集群,其中一个为主节点,其余为从节点。主节点负责处理所有的写入请求,并将变更同步到从节点,从而实现数据冗余和高可用性。当主节点出现故障时,副本集能够自动选举新的主节点,确保数据一致性及服务连续性。 分片集群 , MongoDB分片集群是一种分布式数据存储架构,通过将大量数据划分为多个逻辑部分(称为分片),并将这些分片分布到多个服务器上。这种架构设计允许数据库横向扩展,提高处理海量数据的能力和查询性能。每个分片都可以独立地进行读写操作,同时通过分片路由进程协调跨分片的查询和更新,确保整个集群的一致性和数据完整性。 Write Concern , Write Concern是MongoDB中用于控制数据写入确认级别的一种机制,它定义了数据库在执行写操作后必须满足的条件,如确认写入操作是否已成功记录到磁盘、是否已复制到指定数量的从节点等。通过调整Write Concern参数,开发者可以根据实际需求权衡数据一致性和写入性能,确保在特定场景下达到期望的数据可靠性标准。
2023-12-21 08:59:32
77
海阔天空-t
Sqoop
... Sqoop:大数据生态中的数据搬运工 1. 引言 Sqoop(SQL-to-Hadoop)作为大数据生态系统中的重要工具,承担着关系型数据库与Hadoop之间高效、便捷的数据迁移重任。它就像一个超级能干的“数据搬运工”,不辞辛苦地把企业那些海量的、整齐排列的数据从RDBMS这个仓库,搬到Hadoop的大数据分析基地去深度挖掘和处理;或者有时候也会反向操作,把数据从Hadoop搬回到RDBMS中。 shell 一个简单的Sqoop导入示例 sqoop import \ --connect jdbc:mysql://localhost:3306/mydatabase \ --username myuser \ --password mypassword \ --table mytable \ --target-dir /user/hadoop/mytable_imported 这个命令展示了如何从MySQL数据库导入mytable表到HDFS的/user/hadoop/mytable_imported目录下。 2. Sqoop工作原理及功能特性 (此处详细描述Sqoop的工作原理,如并行导入导出、自动生成Java类、分区导入等特性) 2.1 并行导入示例 Sqoop利用MapReduce模型实现并行数据导入,大幅提高数据迁移效率。 shell sqoop import --num-mappers 4 ... 此命令设置4个map任务并行执行数据导入操作。 3. Sqoop的基本使用 (这里详细说明Sqoop的各种命令,包括import、export、create-hive-table等,并给出实例) 3.1 Sqoop Import 实例详解 shell 示例:将Oracle表同步至Hive表 sqoop import \ --connect jdbc:oracle:thin:@//hostname:port/service_name \ --username username \ --password password \ --table source_table \ --hive-import \ --hive-table target_table 这段代码演示了如何将Oracle数据库中的source_table直接导入到Hive的target_table。 4. Sqoop高级应用与实践问题探讨 (这部分深入探讨Sqoop的一些高级用法,如增量导入、容错机制、自定义连接器等,并通过具体案例阐述) 4.1 增量导入策略 shell 使用lastmodified或incremental方式实现增量导入 sqoop import \ --connect ... \ --table source_table \ --check-column id \ --incremental lastmodified \ --last-value 这段代码展示了如何根据最后一次导入的id值进行增量导入。 5. Sqoop在实际业务场景中的应用与挑战 (在这部分,我们可以探讨Sqoop在真实业务环境下的应用场景,以及可能遇到的问题及其解决方案) 以上仅为大纲及部分内容展示,实际上每部分都需要进一步拓展、深化和情感化的表述,使读者能更好地理解Sqoop的工作机制,掌握其使用方法,并能在实际工作中灵活运用。为了达到1000字以上的要求,每个章节都需要充实详尽的解释、具体的思考过程、理解难点解析以及更多的代码实例和应用场景介绍。
2023-02-17 18:50:30
130
雪域高原
Hive
Hive表数据损坏:原因、影响与恢复策略 1. 引言 当我们谈论大数据处理时,Apache Hive作为Hadoop生态系统中的重要组件,以其SQL-like查询语言和对大规模数据集的高效管理能力赢得了广泛的认可。然而,在我们日常运维的过程中,有时候会遇到个让人超级头疼的状况——Hive表的数据竟然出岔子了,或者干脆是损坏了。这篇东西咱们要实实在在地把这个难题掰开了、揉碎了讲明白,从它可能的“病因”一路聊到会带来哪些影响,再到解决这个问题的具体步骤和策略,还会手把手地带你瞅瞅实例代码是怎么操作演示的。 2. 数据损坏的原因剖析 (1)元数据错误 在Hive中,元数据存储在如MySQL或Derby等数据库中,若这部分信息出现丢失或损坏,可能导致Hive无法正确解析和定位数据块。例如,分区信息错误、表结构定义丢失等情况。 sql -- 假设某个分区信息在元数据库中被误删除 ALTER TABLE my_table DROP PARTITION (dt='2022-01-01'); (2)HDFS文件系统问题 Hive底层依赖于HDFS存储实际数据,若HDFS发生节点故障、网络中断导致数据复制因子不足或者数据块损坏,都可能导致Hive表数据不可用。 (3)并发写入冲突 多线程并发写入Hive表时,如果未做好事务隔离和并发控制,可能导致数据覆盖或损坏。 3. 数据损坏的影响及应对思考 数据损坏直接影响业务的正常运行,可能导致数据分析结果错误、报表异常、甚至业务决策失误。因此,发现数据损坏后,首要任务是尽快定位问题根源,并采取相应措施: - 立即停止受影响的服务,防止进一步的数据写入和错误传播。 - 备份当前状态,为后续分析和恢复提供依据。 - 根据日志排查,查找是否有异常操作记录或其他相关线索。 4. 数据恢复实战 (1)元数据恢复 对于元数据损坏,通常需要从备份中恢复,或重新执行DDL语句以重建表结构和分区信息。 sql -- 重新创建分区(假设已知分区详情) ALTER TABLE my_table ADD PARTITION (dt='2022-01-01') LOCATION '/path/to/backup/data'; (2)HDFS数据恢复 对于HDFS层的数据损坏,可利用Hadoop自带的hdfs fsck命令检测并修复损坏的文件块。 bash hdfs fsck /path/to/hive/table -blocks -locations -files -delete 此外,如果存在完整的数据备份,也可直接替换损坏的数据文件。 (3)并发控制优化 对于因并发写入引发的数据损坏,应在设计阶段就充分考虑并发控制策略,例如使用Hive的Transactional Tables(ACID特性),确保数据的一致性和完整性。 sql -- 开启Hive ACID支持 SET hive.support.concurrency=true; SET hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; 5. 结语 面对Hive表数据损坏的挑战,我们需要具备敏锐的问题洞察力和快速的应急响应能力。同时,别忘了在日常运维中做好预防工作,这就像给你的数据湖定期打个“小强针”,比如按时备份数据、设立警戒线进行监控告警、灵活配置并发策略等等,这样一来,咱们的数据湖就能健健康康,稳稳当当地运行啦。说实在的,对任何一个大数据平台来讲,数据安全和完整性可是咱们绝对不能马虎、时刻得捏在手心里的“命根子”啊!
2023-09-09 20:58:28
642
月影清风
Cassandra
...ssandra中实现数据的实时数据监控策略? 1. 引言 嗨,小伙伴们!今天我们要聊聊一个超级酷的话题——在Cassandra中实现数据的实时监控策略。也许你现在心里在嘀咕:“这个东西听起来挺高端的,咋整呢?”别慌,咱们慢慢来,我会尽量用大白话给你讲清楚,让你觉得就像跟老朋友闲聊那么自在。 2. 为什么要实现实时数据监控? 首先,我们得明白为什么需要这样做。想象一下,你正忙着打理一家电商平台,每天都要处理成千上万的订单。这时候,你肯定想搞清楚哪些东西卖得火,哪些货快要断货了吧?这就凸显了实时数据监控的重要性了。它能让你随时掌握最新的业务动态,及时调整策略,从而避免损失或者抓住机会。 3. Cassandra简介 接下来,简单介绍一下Cassandra。Cassandra是一个分布式数据库,由Facebook开发,后来贡献给了Apache基金会。它厉害的地方在于能搞定海量数据,还能在多个数据中心之间复制数据,简直是大数据处理的神器啊!所以,要是你手头有一大堆数据得处理,还希望随时能查到,那Cassandra绝对是你的最佳拍档。 4. 实现步骤 4.1 设计表结构 设计表结构是第一步。这里的关键是要确保表的设计能够支持高效的查询。例如,假设我们有一个电商应用,想要实时监控订单状态。我们可以设计一张表,表名叫做orders,包含以下字段: - order_id: 订单ID - product_id: 商品ID - status: 订单状态(如:待支付、已发货等) - timestamp: 记录时间戳 sql CREATE TABLE orders ( order_id UUID PRIMARY KEY, product_id UUID, status TEXT, timestamp TIMESTAMP ); 4.2 使用CQL实现数据插入 接下来,我们来看一下如何插入数据。想象一下,有个新订单刚刚飞进来,咱们得赶紧把它记在咱们的“订单簿”里。 sql INSERT INTO orders (order_id, product_id, status, timestamp) VALUES (uuid(), uuid(), '待支付', toTimestamp(now())); 4.3 实时监控数据 现在数据已经存进去了,那么如何实现实时监控呢?这就需要用到Cassandra的另一个特性——触发器。虽然Cassandra自己没带触发器这个功能,但我们可以通过它的改变流(Change Streams)来玩个变通,实现类似的效果。 4.3.1 启用Cassandra的Change Streams 首先,我们需要启用Cassandra的Change Streams功能。这可以通过修改配置文件cassandra.yaml中的enable_user_defined_functions属性来实现。将该属性设置为true,然后重启Cassandra服务。 yaml enable_user_defined_functions: true 4.3.2 创建用户定义函数 接着,我们创建一个用户定义函数来监听数据变化。 sql CREATE FUNCTION monitor_changes (keyspace_name text, table_name text) RETURNS NULL ON NULL INPUT RETURNS map LANGUAGE java AS $$ import com.datastax.driver.core.Row; import com.datastax.driver.core.Session; Session session = cluster.connect(keyspace_name); String query = "SELECT FROM " + table_name; Row row = session.execute(query).one(); Map changes = new HashMap<>(); changes.put("order_id", row.getUUID("order_id")); changes.put("product_id", row.getUUID("product_id")); changes.put("status", row.getString("status")); changes.put("timestamp", row.getTimestamp("timestamp")); return changes; $$; 4.3.3 实时监控逻辑 最后,我们需要编写一段逻辑来调用这个函数并处理返回的数据。这一步可以使用任何编程语言来实现,比如Python。 python from cassandra.cluster import Cluster from cassandra.auth import PlainTextAuthProvider auth_provider = PlainTextAuthProvider(username='your_username', password='your_password') cluster = Cluster(['127.0.0.1'], auth_provider=auth_provider) session = cluster.connect('your_keyspace') def monitor(): result = session.execute("SELECT monitor_changes('your_keyspace', 'orders')") for row in result: print(f"Order ID: {row['order_id']}, Status: {row['status']}") while True: monitor() 4.4 结论与展望 通过以上步骤,我们就成功地实现了在Cassandra中对数据的实时监控。当然啦,在实际操作中,咱们还得面对不少细碎的问题,比如说怎么处理错误啊,怎么优化性能啊之类的。不过,相信有了这些基础,你已经可以开始动手尝试了! 希望这篇文章对你有所帮助,也欢迎你在实践过程中提出更多问题,我们一起探讨交流。
2025-02-27 15:51:14
67
凌波微步
DorisDB
1. 引言 在大数据时代,数据库作为数据存储和查询的核心组件,其性能直接影响着业务效率。DorisDB,这款采用分布式、MPP架构设计的列式数据库,可以说是相当厉害了。它能像压缩饼干一样高效地“挤”数据,大大节省存储空间;查询速度更是快如闪电,让你无需漫长等待;而且它的实时分析功能强大到飞起,让用户们爱不释手。正是因为这些优点,DorisDB才赢得了众多用户的芳心和点赞呢!然而,在实际操作的时候,我们可能会遇到SQL查询速度卡壳的问题,这篇文呢,咱就来好好唠唠嗑,聊聊怎么通过各种小妙招优化DorisDB这个数据库系统的SQL查询效率,让它跑得溜溜的。 2. 理解与诊断查询性能 首先,我们需要对DorisDB的查询过程有一个基本理解,这包括查询计划的生成、数据分区的选择以及执行引擎的工作原理等。当你发现查询速度不尽如人意时,可以通过EXPLAIN命令来查看SQL语句的执行计划,如同医生检查病人的“体检报告”一样: sql -- 使用EXPLAIN获取查询计划 EXPLAIN SELECT FROM my_table WHERE key = 'some_value'; 通过分析这个执行计划,我们可以了解到查询涉及哪些分区、索引是否被有效利用等关键信息,从而为优化工作找准方向。 3. 优化策略一 合理设计表结构与分区策略 - 列选择性优化:由于DorisDB是列式存储,高选择性的列(即唯一或接近唯一的列)能更好地发挥其优势。例如,对于用户ID这样的列,将其设为主键或构建Bloom Filter索引,可以大幅提升查询性能。 sql -- 创建包含主键的表 CREATE TABLE my_table ( user_id INT PRIMARY KEY, ... ); - 分区设计:根据业务需求和数据分布特性,合理设计分区策略至关重要。比如,咱们可以按照时间段给数据分区,这样做的好处可多了。首先呢,能大大减少需要扫描的数据量,让查询过程不再那么费力;其次,还能巧妙地利用局部性原理,就像你找东西时先从最近的地方找起一样,这样就能显著提升查询的效率,让你的数据查找嗖嗖快! sql -- 按天分区 CREATE TABLE my_table ( ... ) PARTITION BY RANGE (dt) ( PARTITION p20220101 VALUES LESS THAN ("2022-01-02"), PARTITION p20220102 VALUES LESS THAN ("2022-01-03"), ... ); 4. 优化策略二 SQL查询优化 - 避免全表扫描:尽量在WHERE子句中指定明确的过滤条件,利用索引加速查询。例如,假设我们已经为user_id字段创建了索引,那么以下查询会更高效: sql SELECT FROM my_table WHERE user_id = 123; - 减少数据传输量:只查询需要的列,避免使用SELECT 。同时,合理运用聚合函数和分组,避免不必要的计算和排序。 sql -- 只查询特定列,避免全表扫描 SELECT user_name, email FROM my_table WHERE user_id = 123; -- 合理运用GROUP BY和聚合函数 SELECT COUNT(), category FROM my_table GROUP BY category; 5. 优化策略三 系统配置调优 DorisDB提供了丰富的系统参数供用户调整以适应不同场景下的性能需求。比方说,你可以通过调节max_scan_range_length这个参数,来决定每次查询时最多能扫描多少数据范围,就像控制扫地机器人的清扫范围那样。再者,通过巧妙调整那些和内存相关的设置,就能让服务器资源得到充分且高效的利用,就像精心安排储物空间,让每个角落都物尽其用。 6. 结语 优化DorisDB的SQL查询性能是一个综合且持续的过程,需要结合业务特点和数据特征,从表结构设计、查询语句编写到系统配置调整等多个维度着手。每个环节都需细心打磨,才能使DorisDB在大数据洪流中游刃有余,提供更为出色的服务。每一次对DorisDB的优化,都是我们携手这位好伙伴,一起摸爬滚打、不断解锁新技能、共同进步的重要印记。这样一来,咱的数据分析之路也能走得更顺溜,效率嗖嗖往上涨,就像坐上了火箭一样快呢!
2023-05-07 10:47:25
500
繁华落尽
转载文章
... 这条命令可以初始化mysql,删除匿名用户,设置root密码等等....mysql_secure_installation1.输入当前密码,初次安装后是没有密码的,直接回车2.询问是否使用 'unix_socket' 进行身份验证: n3.为 root 设置密码:y4.输入 root 的新密码: root5.确认输入 root 的新密码: root6.是否移除匿名用户,这个随意,建议删除: y7.拒绝用户远程登录,这个建议开启:n8.删除 test 库,可以保留:n9.重新加载权限表:y 6. 设置mysql的中文编码支持,修改/etc/my.cnf 1.vi /etc/my.cnf在[mysqld]中添加参数,使得mariadb服务端支持中文[mysqld]character-set-server=utf8collation-server=utf8_general_ci2.重启mariadb服务,读取my.cnf新配置systemctl restart mariadb 3.登录数据库,查看字符编码mysql -uroot -p输入 \s 查看编码 7. mysql常用命 desc 查看表结构create database 数据库名create table 表名查看如何创建db的show create database 库名 查看如何创建table结构的show create table 表名; 修改mysql的密码set password = PASSWORD('redhat'); 创建mysql的普通用户,默认权限非常低create user zhang@'%' identified by '123456'; 查询mysql数据库中的用户信息use mysql;select host,user,password from user; 7. 给用户添加权限命令 对所有库和所有表授权所有权限grant all privileges on . to 账户@主机名 给zhang用户授予所有权限grant all privileges on . to zhang@'%'; 刷新授权表flush privileges; 8. 给用户添加权限命令 给zhangsan用户授予所有权限grant all privileges on . to zhangsan@'%'; 给与root权限授予远程登录的命令 'centos这是密码随意设置grant all privileges on . to root@'%' identified by '123456'; 此时可以在windows登录linux的数据库 连接服务器的mysqlmysql -uyining -p -h 服务器的地址 9. 数据备份与恢复 导出当前数据库的所有db,到一个文件中1.mysqldump -u root -p --all-databases > /data/AllMysql.dump2.登录mysql 导入数据mysql -u root -p> source /data/AllMysql.dump3.通过命令导入数据 在登录时候,导入数据文件,一样可以写入数据mysql -uroot -p < /data/AllMysql.dump 10. 修改Mariadb存储路径 10.1 首先确定MariaDB数据库能正常运行,确定正常后关闭服务 systemctl stop mariadb 10.2 建立要更改数据存放的目录,如:我这单独分了一个区/data存放MariaDB的数据 mkdir /data/mysql_data chown -R mysql:mysql /data/mysql_data 10.3 复制默认数据存放文件夹到/data/mysql_data cp -a /var/lib/mysql /data/mysql_data 10.4 修改/etc/my.cnf.d/server.cnf vim /etc/my.cnf.d/server.cnf 在[mysqld]标签下添加如下内容 datadir=/data/mysql_data/mysqlsocket=/var/lib/mysql/mysql.sockdefault-character-set=utf8character_set_server=utf8slow_query_log=onslow_query_log_file=/data/mysql_data/slow_query_log.loglong_query_time=2 10.5 配置MariaDB慢查询 touch /data/mysql_data/slow_query_log.logchown mysql:mysql /data/mysql_data/slow_query_log.log 10.6 重启数据库 systemctl start mariadb 10.7 注意: 1、配置文件my.cnf存在,但是修改的并不是my.cnf,而是/etc/my.cnf.d/server.cnf; 2、并没有更改mysql.sock的路径配置; 3、没有修改/etc/init.d/mysql中的内容; 4、没有修改mysql_safe中的内容; 5、增加了数据库的慢查询配置。 11. Mariadb主从复制 11.1 主从库初始化 这条命令可以初始化mysql,删除匿名用户,设置root密码等等....mysql_secure_installation1.输入当前密码,初次安装后是没有密码的,直接回车2.询问是否使用 'unix_socket' 进行身份验证: n3.为 root 设置密码:y4.输入 root 的新密码: root5.确认输入 root 的新密码: root6.是否移除匿名用户,这个随意,建议删除: y7.拒绝用户远程登录,这个建议开启:n8.删除 test 库,可以保留:n9.重新加载权限表:y 11.2 修改主库配置 [root@mster mysql] grep -Ev "^$|^" /etc/my.cnf.d/server.cnf[server][mysqld]character-set-server=utf8collation-server=utf8_general_ciserver_id = 13 一组主从组里的每个id必须是唯一值。推荐用ip位数log-bin= mysql-bin 二进制日志,后面指定存放位置。如果只是指定名字,默认存放在/var/lib/mysql下lower_case_table_names=1 不区分大小写binlog-format=ROW 二进制日志文件格式log-slave-updates=True slave更新是否记入日志sync-master-info=1 值为1确保信息不会丢失slave-parallel-threads=3 同时启动多少个复制线程,最多与要复制的数据库数量相等即可binlog-checksum=CRC32 效验码master-verify-checksum=1 启动主服务器效验slave-sql-verify-checksum=1 启动从服务器效验[galera][embedded][mariadb][mariadb-10.6][root@mster-k8s mysql] 11.2 修改从库配置 [mysqld]character-set-server=utf8collation-server=utf8_general_ciserver_id=14log-bin= mysql-bin log-bin是二进制文件relay_log = relay-bin 中继日志, 后面指定存放位置。如果只是指定名字,默认存放在/var/lib/mysql下lower_case_table_names=1 11.3 重启主库和从库服务 systemctl restart mariad 11.4 master节点配置 MariaDB [huawei]> grant replication slave, replication client on . to 'liu'@'%' identified by '123456';Query OK, 0 rows affected (0.001 sec)MariaDB [huawei]> show master status;+------------------+----------+--------------+------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |+------------------+----------+--------------+------------------+| mysql-bin.000001 | 4990 | | |+------------------+----------+--------------+------------------+1 row in set (0.000 sec)MariaDB [huawei]> select binlog_gtid_pos('mysql-bin.000001', 4990 );+-------------------------------------------+| binlog_gtid_pos('mysql-bin.000001', 4990) |+-------------------------------------------+| 0-13-80 |+-------------------------------------------+1 row in set (0.000 sec)MariaDB [huawei]> flush privileges; 11.5 slave节点配置 MariaDB [(none)]> set global gtid_slave_pos='0-13-80';Query OK, 0 rows affected (0.004 sec)MariaDB [(none)]> change master to master_host='101.34.141.216',master_user='liu',master_password='123456',master_use_gtid=slave_pos;Query OK, 0 rows affected (0.008 sec)MariaDB [(none)]> start slave;Query OK, 0 rows affected (0.005 sec)MariaDB [(none)]> 11.6 验证salve状态 MariaDB [(none)]> show slave status\G 1. row Slave_IO_State: Waiting for master to send eventMaster_Host: 101.34.141.216Master_User: liuMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 13260Relay_Log_File: relay-bin.000002Relay_Log_Pos: 10246Relay_Master_Log_File: mysql-bin.000001Slave_IO_Running: YesSlave_SQL_Running: YesReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 13260Relay_Log_Space: 10549Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File: 本篇文章为转载内容。原文链接:https://blog.csdn.net/l363130002/article/details/126121255。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-07-12 10:11:01
310
转载
转载文章
...媒资信息 需求分析 数据模型 Dao Service 测试 0x03 Logstash:扫描课程计划媒资 创建索引 创建模板文件 配置 mysql.conf 启动 logstash.bat Logstash多实例运行 0x04 搜素服务:查询课程媒资接口 需求分析 Api接口定义 Service Controller 测试 三、在线学习:接口开发 0x01 需求分析 0x02 搭建开发环境 0x03 Api接口 0x04 服务端开发 需求分析 搜索服务注册Eureka 搜索服务客户端 自定义错误代码 Service Controller 测试 0x05 前端开发 需求分析 api方法 配置代理 视频播放页面 简单的测试 完整的测试 1、上传文件 一些问题 ~~方案1:删除本地分块文件重新尝试上传~~ 方案2:检查前端提交的MD5值是否正确 2、为课程计划选择媒资信息 3、前端门户测试 四、待完善的一些功能 😁 认识作者 一、学习页面:查询课程计划 0x01 需求分析 到目前为止,我们已可以编辑课程计划信息并上传课程视频,下一步我们要实现在线学习页面动态读取章节对应的视频并进行播放。在线学习页面所需要的信息有两类: 课程计划信息 课程学习信息(视频地址、学习进度等) 如下图: 在线学习集成媒资管理的需求如下: 1、在线学习页面显示课程计划 2、点击课程计划播放该课程计划对应的视频 本章节实现学习页面动态显示课程计划,进入不同课程的学习页面右侧动态显示当前课程的课程计划。 0x02 Api接口 课程计划信息从哪里获取? 在课程发布完成后会自动发布到一个 course_pub 的表中,logstash 会自动将课程发布后的信息自动采集到 ES 索引库中,这些信息也包含课程计划信息。 所以考虑性能要求,课程发布后对课程的查询统一从 ES 索引库中查询。 前端通过请求 搜索服务 获取课程信息,需要单独在 搜索服务 中定义课程信息查询接口。 本接口接收课程id,查询课程所有信息返回给前端。 我们在搜素服务 API 下添加以下方法 @ApiOperation("根据id搜索课程发布信息")public Map<String,CoursePub> getdetail(String id); 返回的课程信息为 json 结构:key 为课程id,value 为课程内容。 0x03 服务端开发 在搜索服务中开发查询课程信息接口。 Controller 在搜素服务下添加以下方法 / 根据id搜索课程发布信息 @param id 课程id @return JSON数据/@Override@GetMapping("/getdetail/{id}")public Map<String, CoursePub> getdetail(@PathVariable("id")String id) {return esCourseService.getdetail(id);} Service / 根据id搜索课程发布信息 @param id 课程id @return JSON数据/public Map<String, CoursePub> getdetail(String id) {//设置索引SearchRequest searchRequest = new SearchRequest(es_index);//设置类型searchRequest.types(es_type);//创建搜索源对象SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//设置查询条件,根据id进行查询searchSourceBuilder.query(QueryBuilders.termQuery("id",id));//这里不使用source的原字段过滤,查询所有字段// searchSourceBuilder.fetchSource(new String[]{"name", "grade", "charge","pic"}, newString[]{});//设置搜索源对象searchRequest.source(searchSourceBuilder);//执行搜索SearchResponse searchResponse = null;try {searchResponse = restHighLevelClient.search(searchRequest);} catch (IOException e) {e.printStackTrace();}//获取搜索结果SearchHits hits = searchResponse.getHits();SearchHit[] searchHits = hits.getHits(); //获取最优结果Map<String,CoursePub> map = new HashMap<>();for (SearchHit hit: searchHits) {//从搜索结果中取值并添加到coursePub对象Map<String, Object> sourceAsMap = hit.getSourceAsMap();String courseId = (String) sourceAsMap.get("id");String name = (String) sourceAsMap.get("name");String grade = (String) sourceAsMap.get("grade");String charge = (String) sourceAsMap.get("charge");String pic = (String) sourceAsMap.get("pic");String description = (String) sourceAsMap.get("description");String teachplan = (String) sourceAsMap.get("teachplan");CoursePub coursePub = new CoursePub();coursePub.setId(courseId);coursePub.setName(name);coursePub.setPic(pic);coursePub.setGrade(grade);coursePub.setTeachplan(teachplan);coursePub.setDescription(description);//设置map对象map.put(courseId,coursePub);}return map;} 测试 使用 swagger-ui 或 postman 测试查询课程信息接口。 0x04 前端开发 配置NGINX虚拟主机 学习中心的二级域名为 ucenter.xuecheng.com ,我们在 nginx 中配置 ucenter 虚拟主机。 学成网用户中心server {listen 80;server_name ucenter.xuecheng.com;个人中心location / {proxy_pass http://ucenter_server_pool;} } 前端ucenterupstream ucenter_server_pool{server 127.0.0.1:7081 weight=10;server 127.0.0.1:13000 weight=10;} 在学习中心要调用搜索的 API,使用 Nginx 解决代理,如下图: 在 ucenter 虚拟主机下配置搜索 Api 代理路径 后台搜索(公开api)upstream search_server_pool{server 127.0.0.1:40100 weight=10;} 学成网用户中心server {listen 80;server_name ucenter.xuecheng.com;个人中心location / {proxy_pass http://ucenter_server_pool;}后端搜索服务location /openapi/search/ {proxy_pass http://search_server_pool/search/;} } 前端 API 方法 在学习中心 xc-ui-pc-leanring 对课程信息的查询属于基础常用功能,所以我们将课程查询的 api 方法定义在base 模块下,如下图: 在system.js 中定义课程查询方法: import http from './public'export const course_view = id => {return http.requestGet('/openapi/search/course/getdetail/'+id);} 前端 API 方法调用 在 learning_video.vue 页面中调用课程信息查询接口得到课程计划,将课程计划json 串转成对象。 xc-ui-pc-leanring/src/module/course/page/learning_video.vue 1、定义视图 课程计划 <!--课程计划部分代码--><div class="navCont"><div class="course-weeklist"><div class="nav nav-stacked" v-for="(teachplan_first, index) in teachplanList"><div class="tit nav-justified text-center"><i class="pull-left glyphicon glyphicon-th-list"></i>{ {teachplan_first.pname} }<i class="pull-right"></i></div><li v-if="teachplan_first.children!=null" v-for="(teachplan_second, index) in teachplan_first.children"><i class="glyphicon glyphicon-check"></i><a :href="url" @click="study(teachplan_second.id)">{ {teachplan_second.pname} }</a></li><!-- <div class="tit nav-justified text-center"><i class="pull-left glyphicon glyphicon-th-list"></i>第一章<i class="pull-right"></i></div><li ><i class="glyphicon glyphicon-check"></i><a :href="url" >第一节</a></li>--><!--<li><i class="glyphicon glyphicon-unchecked"></i>为什么分为A、B、C部分</li>--></div></div></div> 课程名称 <div class="top text-center">{ {coursename} }</div> 定义数据对象 data() {return {url:'',//当前urlcourseId:'',//课程idchapter:'',//章节Idcoursename:'',//课程名称coursepic:'',//课程图片teachplanList:[],//课程计划playerOptions: {//播放参数autoplay: false,controls: true,sources: [{type: "application/x-mpegURL",src: ''}]},} } 在 created 钩子方法中获取课程信息 created(){//当前请求的urlthis.url = window.location//课程idthis.courseId = this.$route.params.courseId//章节idthis.chapter = this.$route.params.chapter//查询课程信息systemApi.course_view(this.courseId).then((view_course)=>{if(!view_course || !view_course[this.courseId]){this.$message.error("获取课程信息失败,请重新进入此页面!")return ;} let courseInfo = view_course[this.courseId]console.log(courseInfo)this.coursename = courseInfo.nameif(courseInfo.teachplan){let teachplan = JSON.parse(courseInfo.teachplan);this.teachplanList = teachplan.children;} })}, 测试 在浏览器请求:http://ucenter.xuecheng.com//learning/4028e581617f945f01617f9dabc40000/0 4028e581617f945f01617f9dabc40000:第一个参数为课程 id,测试时从 ES索引库找一个课程 id 0:第二个参数为课程计划 id,此参数用于点击课程计划播放视频。 如果出现跨域问题,但是确定已经配置了跨域,请尝试结束所以 nginx.exe 的进程 和 清空浏览器缓存。 如果还没有解决?重启电脑试试。 二、学习页面:获取视频播放地址 0x01 需求分析 用户进入在线学习页面,点击课程计划将播放该课程计划对应的教学视频。 业务流程如下: 业务流程说明: 1、用户进入在线学习页面,页面请求搜索服务获取课程信息(包括课程计划信息)并且在页面展示。 2、在线学习请求学习服务获取视频播放地址。 3、学习服务校验当前用户是否有权限学习,如果没有权限学习则提示用户。 4、学习服务校验通过,请求搜索服务获取课程媒资信息。 5、搜索服务请求ElasticSearch获取课程媒资信息。 为什么要请求 ElasticSearch 查询课程媒资信息? 出于性能的考虑,公开查询课程信息从搜索服务查询,分摊 mysql 数据库的访问压力。 什么时候将课程媒资信息存储到 ElasticSearch 中? 课程媒资信息是在课程发布的时候存入 ElasticSearch,因为课程发布后课程信息将基本不再修改。 0x02 课程发布:储存媒资信息 需求分析 课程媒资信息是在课程发布的时候存入 ElasticSearch 索引库,因为课程发布后课程信息将基本不再修改,具体的业务流程如下。 1、课程发布,向课程媒资信息表写入数据。 1)根据课程 id 删除 teachplanMediaPub 中的数据 2)根据课程 id 查询 teachplanMedia 数据 3)将查询到的 teachplanMedia 数据插入到 teachplanMediaPub 中 2、Logstash 定时扫描课程媒资信息表,并将课程媒资信息写入索引库。 数据模型 在 xc_course 数据库创建课程计划媒资发布表: CREATE TABLE teachplan_media_pub (teachplan_id varchar(32) NOT NULL COMMENT '课程计划id',media_id varchar(32) NOT NULL COMMENT '媒资文件id',media_fileoriginalname varchar(128) NOT NULL COMMENT '媒资文件的原始名称',media_url varchar(256) NOT NULL COMMENT '媒资文件访问地址',courseid varchar(32) NOT NULL COMMENT '课程Id',timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT'logstash使用',PRIMARY KEY (teachplan_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 数据模型类如下: package com.xuecheng.framework.domain.course;import lombok.Data;import lombok.ToString;import org.hibernate.annotations.GenericGenerator;import javax.persistence.;import java.io.Serializable;import java.util.Date;@Data@ToString@Entity@Table(name="teachplan_media_pub")@GenericGenerator(name = "jpa-assigned", strategy = "assigned")public class TeachplanMediaPub implements Serializable {private static final long serialVersionUID = -916357110051689485L;@Id@GeneratedValue(generator = "jpa-assigned")@Column(name="teachplan_id")private String teachplanId;@Column(name="media_id")private String mediaId;@Column(name="media_fileoriginalname")private String mediaFileOriginalName;@Column(name="media_url")private String mediaUrl;@Column(name="courseid")private String courseId;@Column(name="timestamp")private Date timestamp;//时间戳} Dao 创建 TeachplanMediaPub 表的 Dao,向 TeachplanMediaPub 存储信息采用先删除该课程的媒资信息,再添加该课程的媒资信息,所以这里定义根据课程 id 删除课程计划媒资方法: public interface TeachplanMediaPubRepository extends JpaRepository<TeachplanMediaPub, String> {//根据课程id删除课程计划媒资信息long deleteByCourseId(String courseId);} 从TeachplanMedia查询课程计划媒资信息 //从TeachplanMedia查询课程计划媒资信息public interface TeachplanMediaRepository extends JpaRepository<TeachplanMedia, String> {List<TeachplanMedia> findByCourseId(String courseId);} Service 编写保存课程计划媒资信息方法,并在课程发布时调用此方法。 1、保存课程计划媒资信息方法 本方法采用先删除该课程的媒资信息,再添加该课程的媒资信息,在 CourseService 下定义该方法 //保存课程计划媒资信息private void saveTeachplanMediaPub(String courseId){//查询课程媒资信息List<TeachplanMedia> byCourseId = teachplanMediaRepository.findByCourseId(courseId);if(byCourseId == null) return; //没有查询到媒资数据则直接结束该方法//将课程计划媒资信息储存到待索引表//删除原有的索引信息teachplanMediaPubRepository.deleteByCourseId(courseId);//一个课程可能会有多个媒资信息,遍历并使用list进行储存List<TeachplanMediaPub> teachplanMediaPubList = new ArrayList<>();for (TeachplanMedia teachplanMedia: byCourseId) {TeachplanMediaPub teachplanMediaPub = new TeachplanMediaPub();BeanUtils.copyProperties(teachplanMedia, teachplanMediaPub);teachplanMediaPubList.add(teachplanMediaPub);}//保存所有信息teachplanMediaPubRepository.saveAll(teachplanMediaPubList);} 2、课程发布时调用此方法 修改课程发布的 coursePublish 方法: ....//保存课程计划媒资信息到待索引表saveTeachplanMediaPub(courseId);//页面urlString pageUrl = cmsPostPageResult.getPageUrl();return new CoursePublishResult(CommonCode.SUCCESS,pageUrl);..... 测试 测试课程发布后是否成功将课程媒资信息存储到 teachplan_media_pub 中,测试流程如下: 1、指定一个课程 2、为课程计划添加课程媒资 3、执行课程发布 4、观察课程计划媒资信息是否存储至 teachplan_media_pub 中 注意:由于此测试仅用于测试发布课程计划媒资信息的功能,可暂时将 cms页面发布的功能暂时屏蔽,提高测试效率。 测试结果如下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vrzs5589-1595567273126)(https://qnoss.codeyee.com/20200704_15/image7)] 0x03 Logstash:扫描课程计划媒资 Logstash 定时扫描课程媒资信息表,并将课程媒资信息写入索引库。 创建索引 1、创建 xc_course_media 索引 2、并向此索引创建如下映射 POST: http://localhost:9200/xc_course_media/doc/_mapping {"properties" : {"courseid" : {"type" : "keyword"},"teachplan_id" : {"type" : "keyword"},"media_id" : {"type" : "keyword"},"media_url" : {"index" : false,"type" : "text"},"media_fileoriginalname" : {"index" : false,"type" : "text"} }} 索引创建成功 创建模板文件 在 logstach 的 config 目录文件 xc_course_media_template.json 文件路径为 %ES_ROOT_DIR%/logstash6.8.8/config/xc_course_media_template.json %ES_ROOT_DIR% 为 ElasticSearch 和 logstash 的安装目录 内容如下: {"mappings" : {"doc" : {"properties" : {"courseid" : {"type" : "keyword"},"teachplan_id" : {"type" : "keyword"},"media_id" : {"type" : "keyword"},"media_url" : {"index" : false,"type" : "text"},"media_fileoriginalname" : {"index" : false,"type" : "text"} }},"template" : "xc_course_media"} } 配置 mysql.conf 在logstash的 config 目录下配置 mysql_course_media.conf 文件供 logstash 使用,logstash 会根据 mysql_course_media.conf 文件的配置的地址从 MySQL 中读取数据向 ES 中写入索引。 参考https://www.elastic.co/guide/en/logstash/current/plugins-inputs-jdbc.html 配置输入数据源和输出数据源。 input {stdin {} jdbc {jdbc_connection_string => "jdbc:mysql://localhost:3306/xc_course?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC" 数据库信息jdbc_user => "root"jdbc_password => "123123" MYSQL 驱动地址,修改为maven仓库对应的位置jdbc_driver_library => "D:/soft/apache-maven-3.5.4/repository/mysql/mysql-connector-java/5.1.40/mysql-connector-java-5.1.40.jar" the name of the driver class for mysqljdbc_driver_class => "com.mysql.jdbc.Driver"jdbc_paging_enabled => "true"jdbc_page_size => "50000"要执行的sql文件statement_filepath => "/conf/course.sql"statement => "select from teachplan_media_pub where timestamp > date_add(:sql_last_value,INTERVAL 8 HOUR)"定时配置schedule => " "record_last_run => truelast_run_metadata_path => "D:/soft/elasticsearch/logstash-6.8.8/config/xc_course_media_metadata"} } output {elasticsearch {ES的ip地址和端口hosts => "localhost:9200"hosts => ["localhost:9200","localhost:9202","localhost:9203"]ES索引库名称index => "xc_course_media"document_id => "%{teachplan_id}"document_type => "doc"template => "D:/soft/elasticsearch/logstash-6.8.8/config/xc_course_media_template.json"template_name =>"xc_course_media"template_overwrite =>"true"} stdout {日志输出codec => json_lines} } 启动 logstash.bat 启动 logstash.bat 采集 teachplan_media_pub 中的数据,向 ES 写入索引。 logstash.bat -f ../config/mysql_course_media.conf 课程发布成功后,Logstash 会自动参加 teachplan_media_pub 表中新增的数据,效果如下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ILPBxfXi-1595567273134)(https://qnoss.codeyee.com/20200704_15/image10)] Logstash多实例运行 由于之前我们还启动了一个 Logstash 对课程的发布信息进行采集,所以如果想两个 logstash 实例同时运行,因为每个实例都有一个.lock文件,所以不能使用同一个目录来存放数据,所以我们需要使用 --path.data= 为每个实例指定单独的数据目录,具体的代码如下: 该配置是在windows下进行的 课程发布实例 logstash_start_course_pub.bat @title logstash in course_publogstash.bat -f ..\config\mysql.conf --path.data=../data/course_pub 课程计划媒体发布实例 logstash_start_teachplan_media.bat @title logstash i n teachplan_media_publogstash.bat -f ../config/mysql_course_media.conf --path.data=../data/teachplan_media/ 同时运行效果如下 0x04 搜素服务:查询课程媒资接口 需求分析 搜索服务 提供查询课程媒资接口,此接口供学习服务调用。 Api接口定义 @ApiOperation("根据课程计划查询媒资信息")public TeachplanMediaPub getmedia(String teachplanId); Service 1、配置课程计划媒资索引库等信息 在 application.yml 中配置 xuecheng:elasticsearch:hostlist: ${eshostlist:127.0.0.1:9200} 多个结点中间用逗号分隔course:index: xc_coursetype: docsource_field: id,name,grade,mt,st,charge,valid,pic,qq,price,price_old,status,studymodel,teachmode,expires,pub_time,start_time,end_timemedia:index: xc_course_mediatype: docsource_field: courseid,media_id,media_url,teachplan_id,media_fileoriginalname 2、service 方法开发 在 课程搜索服务 中定义课程媒资查询接口,为了适应后续需求,service 参数定义为数组,可一次查询多个课程计划的媒资信息。 / 根据一个或者多个课程计划id查询媒资信息 @param teachplanIds 课程id @return QueryResponseResult/public QueryResponseResult<TeachplanMediaPub> getmedia(String [] teachplanIds){//设置索引SearchRequest searchRequest = new SearchRequest(media_index);//设置类型searchRequest.types(media_type);//创建搜索源对象SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//源字段过滤String[] media_index_arr = media_field.split(",");searchSourceBuilder.fetchSource(media_index_arr, new String[]{});//查询条件,根据课程计划id查询(可以传入多个课程计划id)searchSourceBuilder.query(QueryBuilders.termsQuery("teachplan_id", teachplanIds));searchRequest.source(searchSourceBuilder);SearchResponse searchResponse = null;try {searchResponse = restHighLevelClient.search(searchRequest);} catch (IOException e) {e.printStackTrace();}//获取结果SearchHits hits = searchResponse.getHits();long totalHits = hits.getTotalHits();SearchHit[] searchHits = hits.getHits();//数据列表List<TeachplanMediaPub> teachplanMediaPubList = new ArrayList<>();for(SearchHit hit:searchHits){TeachplanMediaPub teachplanMediaPub =new TeachplanMediaPub();Map<String, Object> sourceAsMap = hit.getSourceAsMap();//取出课程计划媒资信息String courseid = (String) sourceAsMap.get("courseid");String media_id = (String) sourceAsMap.get("media_id");String media_url = (String) sourceAsMap.get("media_url");String teachplan_id = (String) sourceAsMap.get("teachplan_id");String media_fileoriginalname = (String) sourceAsMap.get("media_fileoriginalname");teachplanMediaPub.setCourseId(courseid);teachplanMediaPub.setMediaUrl(media_url);teachplanMediaPub.setMediaFileOriginalName(media_fileoriginalname);teachplanMediaPub.setMediaId(media_id);teachplanMediaPub.setTeachplanId(teachplan_id);//将对象加入到列表中teachplanMediaPubList.add(teachplanMediaPub);}//构建返回课程媒资信息对象QueryResult<TeachplanMediaPub> queryResult = new QueryResult<>();queryResult.setList(teachplanMediaPubList);queryResult.setTotal(totalHits);return new QueryResponseResult<TeachplanMediaPub>(CommonCode.SUCCESS,queryResult);} Controller / 根据课程计划id搜索发布后的媒资信息 @param teachplanId @return/@GetMapping(value="/getmedia/{teachplanId}")@Overridepublic TeachplanMediaPub getmedia(@PathVariable("teachplanId") String teachplanId) {//为了service的拓展性,所以我们service接收的是数组作为参数,以便后续开发查询多个ID的接口String[] teachplanIds = new String[]{teachplanId};//通过service查询ES获取课程媒资信息QueryResponseResult<TeachplanMediaPub> mediaPubQueryResponseResult = esCourseService.getmedia(teachplanIds);QueryResult<TeachplanMediaPub> queryResult = mediaPubQueryResponseResult.getQueryResult();if(queryResult!=null&& queryResult.getList()!=null&& queryResult.getList().size()>0){//返回课程计划对应课程媒资return queryResult.getList().get(0);} return new TeachplanMediaPub();} 测试 使用 swagger-ui 和 postman 测试课程媒资查询接口。 三、在线学习:接口开发 0x01 需求分析 根据下边的业务流程,本章节完成前端学习页面请求学习服务获取课程视频地址,并自动播放视频。 0x02 搭建开发环境 1、创建数据库 创建 xc_learning 数据库,学习数据库将记录学生的选课信息、学习信息。 导入:资料/xc_learning.sql 2、创建学习服务工程 参考课程管理服务工程结构,创建学习服务工程: 导入:资料/xc-service-learning.zip 项目工程结构如下 0x03 Api接口 此 api 接口是课程学习页面请求学习服务获取课程学习地址。 定义返回值类型: package com.xuecheng.framework.domain.learning.response;import com.xuecheng.framework.model.response.ResponseResult;import com.xuecheng.framework.model.response.ResultCode;import lombok.Data;import lombok.NoArgsConstructor;import lombok.ToString;@Data@ToString@NoArgsConstructorpublic class GetMediaResult extends ResponseResult {public GetMediaResult(ResultCode resultCode, String fileUrl) {super(resultCode);this.fileUrl = fileUrl;}//媒资文件播放地址private String fileUrl;} 定义接口,学习服务根据传入课程 ID、章节 Id(课程计划 ID)来取学习地址。 @Api(value = "录播课程学习管理",description = "录播课程学习管理")public interface CourseLearningControllerApi {@ApiOperation("获取课程学习地址")public GetMediaResult getMediaPlayUrl(String courseId,String teachplanId);} 0x04 服务端开发 需求分析 学习服务根据传入课程ID、章节Id(课程计划ID)请求搜索服务获取学习地址。 搜索服务注册Eureka 学习服务要调用搜索服务查询课程媒资信息,所以需要将搜索服务注册到 eureka 中。 1、查看服务名称是否为 xc-service-search 注意修改application.xml中的服务名称:spring:application:name: xc‐service‐search 2、配置搜索服务的配置文件 application.yml,加入 Eureka 配置 如下: eureka:client:registerWithEureka: true 服务注册开关fetchRegistry: true 服务发现开关serviceUrl: Eureka客户端与Eureka服务端进行交互的地址,多个中间用逗号分隔defaultZone: ${EUREKA_SERVER:http://localhost:50101/eureka/,http://localhost:50102/eureka/}instance:prefer-ip-address: true 将自己的ip地址注册到Eureka服务中ip-address: ${IP_ADDRESS:127.0.0.1}instance-id: ${spring.application.name}:${server.port} 指定实例idribbon:MaxAutoRetries: 2 最大重试次数,当Eureka中可以找到服务,但是服务连不上时将会重试,如果eureka中找不到服务则直接走断路器MaxAutoRetriesNextServer: 3 切换实例的重试次数OkToRetryOnAllOperations: false 对所有操作请求都进行重试,如果是get则可以,如果是post,put等操作没有实现幂等的情况下是很危险的,所以设置为falseConnectTimeout: 5000 请求连接的超时时间ReadTimeout: 6000 请求处理的超时时间 3、添加 eureka 依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring‐cloud‐starter‐netflix‐eureka‐client</artifactId></dependency> 4、修改启动类,在class上添加如下注解: @EnableDiscoveryClient 搜索服务客户端 在 学习服务 创建搜索服务的客户端接口,此接口会生成代理对象,调用搜索服务: package com.xuecheng.learning.client;import com.xuecheng.framework.domain.course.TeachplanMediaPub;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;@FeignClient(value = "xc‐service‐search")public interface CourseSearchClient {@GetMapping(value="/getmedia/{teachplanId}")public TeachplanMediaPub getmedia(@PathVariable("teachplanId") String teachplanId);} 自定义错误代码 我们在 com.xuecheng.framework.domain.learning.response 包下自定义一个错误消息模型 package com.xuecheng.framework.domain.learning.response;import com.xuecheng.framework.model.response.ResultCode;import lombok.ToString;@ToStringpublic enum LearningCode implements ResultCode {LEARNING_GET_MEDIA_ERROR(false,23001,"学习中心获取媒资信息错误!");//操作代码boolean success;//操作代码int code;//提示信息String message;private LearningCode(boolean success, int code, String message){this.success = success;this.code = code;this.message = message;}@Overridepublic boolean success() {return success;}@Overridepublic int code() {return code;}@Overridepublic String message() {return message;} } 该消息模型基于 ResultCode 来实现,代码如下 package com.xuecheng.framework.model.response;/ Created by mrt on 2018/3/5. 10000-- 通用错误代码 22000-- 媒资错误代码 23000-- 用户中心错误代码 24000-- cms错误代码 25000-- 文件系统/public interface ResultCode {//操作是否成功,true为成功,false操作失败boolean success();//操作代码int code();//提示信息String message(); 从 ResultCode 中我们可以看出,我们约定了用户中心的错误代码使用 23000,所以我们定义的一些错误信息的代码就从 23000 开始计数。 Service 在学习服务中定义 service 方法,此方法远程请求课程管理服务、媒资管理服务获取课程学习地址。 package com.xuecheng.learning.service.impl;import com.netflix.discovery.converters.Auto;import com.xuecheng.framework.domain.course.TeachplanMediaPub;import com.xuecheng.framework.domain.learning.response.GetMediaResult;import com.xuecheng.framework.exception.ExceptionCast;import com.xuecheng.framework.model.response.CommonCode;import com.xuecheng.learning.client.CourseSearchClient;import com.xuecheng.learning.service.LearningService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class LearningServiceImpl implements LearningService {@AutowiredCourseSearchClient courseSearchClient;/ 远程调用搜索服务获取已发布媒体信息中的url @param courseId 课程id @param teachplanId 媒体信息id @return/@Overridepublic GetMediaResult getMediaPlayUrl(String courseId, String teachplanId) {//校验学生权限,是否已付费等//远程调用搜索服务进行查询媒体信息TeachplanMediaPub mediaPub = courseSearchClient.getmedia(teachplanId);if(mediaPub == null) ExceptionCast.cast(CommonCode.FAIL);return new GetMediaResult(CommonCode.SUCCESS, mediaPub.getMediaUrl());} } Controller 调用 service 根据课程计划 id 查询视频播放地址: @RestController@RequestMapping("/learning/course")public class CourseLearningController implements CourseLearningControllerApi {@AutowiredLearningService learningService;@Override@GetMapping("/getmedia/{courseId}/{teachplanId}")public GetMediaResult getMediaPlayUrl(@PathVariable String courseId, @PathVariable String teachplanId) {//获取课程学习地址return learningService.getMedia(courseId, teachplanId);} } 测试 使用 swagger-ui 或postman 测试学习服务查询课程视频地址接口。 0x05 前端开发 需求分析 需要在学习中心前端页面需要完成如下功能: 1、进入课程学习页面需要带上 课程 Id参数及课程计划Id的参数,其中 课程 Id 参数必带,课程计划 Id 可以为空。 2、进入页面根据 课程 Id 取出该课程的课程计划显示在右侧。 3、进入页面后判断如果请求参数中有课程计划 Id 则播放该章节的视频。 4、进入页面后判断如果 课程计划id 为0则需要取出本课程第一个 课程计划的Id,并播放第一个课程计划的视频。 进入到模块 xc-ui-pc-leanring/src/module/course api方法 let sysConfig = require('@/../config/sysConfig')let apiUrl = sysConfig.xcApiUrlPre;/获取播放地址/export const get_media = (courseId,chapter) => {return http.requestGet(apiUrl+'/api/learning/course/getmedia/'+courseId+'/'+chapter);} 配置代理 在 Nginx 中的 ucenter.xuecheng.com 虚拟主机中配置 /api/learning/ 的路径转发,此url 请转发到学习服务。 学习服务upstream learning_server_pool{server 127.0.0.1:40600 weight=10;}学成网用户中心server {listen 80;server_name ucenter.xuecheng.com;个人中心location / {proxy_pass http://ucenter_server_pool;}后端搜索服务location /openapi/search/ {proxy_pass http://search_server_pool/search/; }学习服务location ^~ /api/learning/ {proxy_pass http://learning_server_pool/learning/;} } 视频播放页面 1、如果传入的课程计划id为0则取出第一个课程计划id 在 created 钩子方法中完成 created(){//当前请求的urlthis.url = window.location//课程idthis.courseId = this.$route.params.courseId//章节idthis.chapter = this.$route.params.chapter//查询课程信息systemApi.course_view(this.courseId).then((view_course)=>{if(!view_course || !view_course[this.courseId]){this.$message.error("获取课程信息失败,请重新进入此页面!")return ;}let courseInfo = view_course[this.courseId]console.log(courseInfo)this.coursename = courseInfo.nameif(courseInfo.teachplan){console.log("准备开始播放视频")let teachplan = JSON.parse(courseInfo.teachplan);this.teachplanList = teachplan.children;//开始学习if(this.chapter == "0" || !this.chapter){//取出第一个教学计划this.chapter = this.getFirstTeachplan();console.log("第一个教学计划id为 ",this.chapter);this.study(this.chapter);}else{this.study(this.chapter);} }})}, 取出第一个章节 id,用户未输入课程计划 id 或者输入为 0 时,播放第一个。 //取出第一个章节getFirstTeachplan(){for(var i=0;i<this.teachplanList.length;i++){let firstTeachplan = this.teachplanList[i];//如果当前children存在,则取出第一个返回if(firstTeachplan.children && firstTeachplan.children.length>0){let secondTeachplan = firstTeachplan.children[0];return secondTeachplan.id;} }return ;}, 开始学习: //开始学习study(chapter){// 获取播放地址courseApi.get_media(this.courseId,chapter).then((res)=>{if(res.success){let fileUrl = sysConfig.videoUrl + res.fileUrl//播放视频this.playvideo(fileUrl)}else if(res.message){this.$message.error(res.message)}else{this.$message.error("播放视频失败,请刷新页面重试")} }).catch(res=>{this.$message.error("播放视频失败,请刷新页面重试")});}, 2、点击右侧课程章节切换播放 在原有代码基础上添加 click 事件,点击调用开始学习方法(study)。 <li v‐if="teachplan_first.children!=null" v‐for="(teachplan_second, index) inteachplan_first.children"><i class="glyphicon glyphicon‐check"></i><a :href="url" @click="study(teachplan_second.id)">{ {teachplan_second.pname} }</a></li> 3、地址栏路由url变更 这里需要注意一个问题,在用户点击课程章节切换播放时,地址栏的 url 也应该同步改变为当前所选择的课程计划 id 4、在线学习按钮 将 learnstatus 默认更改为 1,这样就能显示出马上学习的按钮,方便我们后续的集成测试。 文件路径为 xc-ui-pc-static-portal/include/course_detail_dynamic.html 部分代码块如下 <script>var body= new Vue({ //创建一个Vue的实例el: "body", //挂载点是id="app"的地方data: {editLoading: false,title:'测试',courseId:'',charge:'',//203001免费,203002收费learnstatus: 1 ,//课程状态,1:马上学习,2:立即报名、3:立即购买course:{},companyId:'template',company_stat:[],course_stat:{"s601001":"","s601002":"","s601003":""} }, 简单的测试 访问在线学习页面:http://ucenter.xuecheng.com//learning/课程id/课程计划id 通过 url 传入两个参数:课程id 和 课程计划id 如果没有课程计划则传入0 测试项目如下: 1、传入正确的课程id、课程计划id,自动播放本章节的视频 2、传入正确的课程id、课程计划id传入0,自动播放第一个视频 3、传入错误的课程id 或 课程计划id,提示错误信息。 4、通过右侧章节目录切换章节及播放视频。 访问: http://ucenter.xuecheng.com//learning/4028e58161bcf7f40161bcf8b77c0000/4028e58161bd18ea0161bd1f73190008 传入正确的课程id、课程计划id,自动播放本章节的视频 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ef0xxym7-1595567273153)(https://qnoss.codeyee.com/20200704_15/image17)] 传入正确的课程id、课程计划id传入0,自动播放第一个视频 访问 http://ucenter.xuecheng.com//learning/4028e58161bcf7f40161bcf8b77c0000/0 识别出第一个课程计划的 id 需要注意的是这里的 chapter 参数是我自己在 study 函数里加上去的,可以忽略。 传入错误的课程id或课程计划id,提示错误信息。 通过右侧章节目录切换章节及播放视频。 点击章节即可播放,但是点击制定章节后 url 没有发生改变,这个问题暂时还没有解决,关注笔记后面的内容。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TOGdxwb4-1595567273158)(https://qnoss.codeyee.com/20200704_15/image20)] 完整的测试 准备工作 启动 RabbitMQ,启动 Logstash、ElasticSearch 建议把所有后端服务都开起来 启动 前端静态门户、启动 nginx 、启动课程管理前端 我们整理一下测试的流程 上传两个媒资视频文件,用于测试 进入到课程管理,为课程计划选择媒资信息 发布课程,等待 logstash 将数据采集到 ElasticSearch 的索引库中 进入学成网主页,点击课程,进入到搜索门户页面 搜索课程,进入到课程详情页面 点击开始学习,进入到课程学习页面,选择课程计划中的一个章节进行学习。 1、上传文件 首先我们使用之前开发的媒资管理模块,上传两个视频文件用于测试。 第一个文件上传成功 一些问题 在上传第二个文件时,发生了错误,我们来检查一下问题出在了哪里 在媒体服务的控制台中可以看到,在 mergeChunks 方法在校验文件 md5 时候抛出了异常 我们在 MD5 校验这里打个断点,重新上传文件,分析一下问题所在。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OpEMZGI8-1595567273166)(https://qnoss.codeyee.com/20200704_15/image23)] 单步调试后发现,合并文件后的MD5值与用户上传的源文件值不相等 方案1:删除本地分块文件重新尝试上传 考虑到可能是在用户上传完 视频的分块文件时发生了一些问题,导致合并文件后与源文件的大小不等,导致MD5也不相同,这里我们把这个视频上传到本地的文件全部删除,在媒资上传页面重新上传文件。 对比所有分块文件的字节大小和本地源文件的大小,完全是相等的 删除所有文件后重新上传,md5值还是不等,考虑从调试一下文件合并的代码。 方案2:检查前端提交的MD5值是否正确 在查阅是否有其他的MD5值获取方案时,发现了一个使用 windows 本地命令获取文件MD5值的方法 certutil -hashfile .\19-在线学习接口-集成测试.avi md5 惊奇的发现,TM的原来是前端那边转换的MD5值不正确,后端这边是没有问题的。 从前面的图可以看出,本地和后端转换的都是以一个 f6f0 开头的MD5值 那么问题就出现在前端了,还需要花一些时间去分析一下,这里暂时就先告一段落,因为上传了几个文件测试中只有这一个文件出现了问题。 2、为课程计划选择媒资信息 进入到一个课程的管理页面 http://localhost:12000//course/manage/baseinfo/4028e58161bcf7f40161bcf8b77c0000 将刚才我们上传的媒资文件的信息和课程计划绑定 选择效果如下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-epKaqzCD-1595567273178)(https://qnoss.codeyee.com/20200704_15/image29)] 2、发布课程,等待 logstash 从 course_pub 以及 teachplan_media_pub 表中采集数据到 ElasticSearch 当中 发布成功后,我们可以从 teachplan_media_pub 表中看到刚才我们发布的媒资信息 再观察 Logstash 的控制台,发现两个 Logstash 的实例都对更新的课程发布信息进行了采集 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hTUve2ik-1595567273183)(https://qnoss.codeyee.com/20200704_15/image32)] 3、前端门户测试 打开我们的门户主站 http://www.xuecheng.com/ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4wZe9R84-1595567273185)(https://qnoss.codeyee.com/20200704_15/image33)] 点击导航栏的课程,进入到我们的搜索门户页面 如果无法进入到搜索门户,请检查你的 xc-ui-pc-portal 前端工程是否已经启动 进入到搜索门户后,可以看到一些初始化时搜索的课程数据,默认是搜索第一页的数据,每页2个课程。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BJ1AKoJb-1595567273187)(https://qnoss.codeyee.com/20200704_15/image34)] 我们可以测试搜索一下前面我们选择媒资信息时所用的课程 点击课程,进入到课程详情页面,然后再点击开始学习。 点击马上学习后,会进入到该课程的在线学习页面,默认自动播放我们第一个课程计划中的视频。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tcuLWnf2-1595567273193)(https://qnoss.codeyee.com/20200704_15/image37)] 我们可以在右侧的目录中选择第二个课程计划,会自动播放所选的课程计划所对应的媒资视频播放地址,该 播放地址正是我们刚才通过 Logstash 自动采集到 ElasticSearch 的索引信息,效果图如下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cvi9Dr0Y-1595567273195)(https://qnoss.codeyee.com/20200704_15/image38)] 四、待完善的一些功能 课程发布前,校验课程计划里面是否包含二级课程计划 课程发布前,校验课程计划信息里面是否全部包含媒资信息 删除媒资信息,并且同步删除ES中的索引 在获取该课程的播放地址时校验用户的合法、 在线学习页面,点击右侧目录中的课程计划同时改变url中的课程计划地址 视频文件 19-在线学习接口-集成测试.avi 前端上传时提交的MD5值不正确 😁 认识作者 作者:👦 LCyee ,全干型代码🐕 自建博客:https://www.codeyee.com 记录学习以及项目开发过程中的笔记与心得,记录认知迭代的过程,分享想法与观点。 CSDN 博客:https://blog.csdn.net/codeyee 记录和分享一些开发过程中遇到的问题以及解决的思路。 欢迎加入微服务练习生的队伍,一起交流项目学习过程中的一些问题、分享学习心得等,不定期组织一起刷题、刷项目,共同见证成长。 本篇文章为转载内容。原文链接:https://blog.csdn.net/codeyee/article/details/107558901。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-12-16 12:41:01
73
转载
MySQL
MySQL是一种很广泛应用的关系型数据库管理系统软件。在采用MySQL时,我们经常需要往要添加记录的列里写入数据。下面就介绍一下如何在MySQL中写入数据。 首先,我们需要接入到MySQL数据库,可以采用下面的代码: $conn = mysqli_connect("localhost", "username", "password", "dbname"); if (!$conn) { die("接入失败: " . mysqli_connect_error()); } 其中,localhost指接入的服务器地址,username和password分别指接入的账号和口令,dbname指接入的数据库实例。 接下来,我们需要创建执行语句,以往数据库里添加记录。简单的执行语句可以采用下面的模板: INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...); 其中,table_name指要添加记录的表格名称,column1,column2,column3, ...分别指要添加记录的字段名称,value1,value2,value3, ...分别指要添加记录的数据项。 此处为一个添加记录的示例: $sql = "INSERT INTO students (name, age, gender, class) VALUES ('张三', 18, '男', '一班')"; if (mysqli_query($conn, $sql)) { echo "新条目成功添加"; } else { echo "错误信息: " . $sql . " " . mysqli_error($conn); } 其中,students指要添加记录的表格名称,name、age、gender、class分别指要添加记录的字段名称,后面的数据项分别为'张三'、18、'男'、'一班'。 最后,我们需要关闭接入: mysqli_close($conn); 通过上面的步骤,我们可以在MySQL中往明确字段里写入数据。
2023-06-05 22:29:31
72
算法侠
MySQL
何为MySQL服务 MySQL是一种普遍的关联型DBMS,它使用SQL语言来检索、添加、修改和移除数据。MySQL服务是指在本地计算机上运行的一个MySQL例子,允许用户在命令行和其他客户端应用程序中访问和管控数据。 装配MySQL服务 在开启MySQL服务之前,您需要先装配MySQL安装包。您可以从MySQL官方网站获取适合您系统软件版次的安装包,并按照指示运行装配向导。装配完成后,您将获得一个MySQL服务器并可以开始开启服务。 开启MySQL服务 使用Windows的用户可以通过打开命令提示符(cmd)程序来开启MySQL服务。在开始菜单的搜索栏中输入“cmd”,然后选择打开程序。在命令提示符窗口中,输入以下命令: net start mysql 按下回车键后,MySQL服务将开始运行,您现在可以通过其他客户端应用程序(如MySQL Workbench)访问数据库。 关闭MySQL服务 有时候您需要关闭MySQL服务。在命令提示符窗口,输入以下命令: net stop mysql 按下回车键后,MySQL服务将停止运行。在您需要再次使用MySQL服务时,需要再次以相同方式开启服务。 总结 通过在命令提示符窗口输入简单的命令,您可以轻松开启和停止MySQL服务。如果您有其他需要处理的数据库任务,可以使用客户端数据库管控软件(如MySQL Workbench)来运行更高级的操作。MySQL服务是非常有用的工具,在适当的配置和使用下,可以帮助您轻松管控和处理大量的数据。
2023-04-15 17:10:20
127
键盘勇士
HTML
...图像和其他内容组织成结构化的网页,并定义其样式和交互行为。个人简历网页正是利用HTML代码构建的,以展示个人信息、教育背景、工作经验等内容。 SEO优化 , Search Engine Optimization,搜索引擎优化。在制作个人简历网页时,SEO优化是指通过合理使用HTML标签、关键词布局、网站结构设计等方式,提升网页在搜索引擎结果页面(SERP)中的自然排名,使求职者的简历更容易被潜在雇主搜索到。例如,在编写个人简历网页的HTML代码时,应遵循SEO原则,确保关键信息如姓名、技能和工作经历等易于被搜索引擎抓取和理解。 Spring框架 , Spring Framework是一个开源的Java平台应用程序框架,广泛应用于企业级Java应用开发。它提供了控制反转(IoC)、面向切面编程(AOP)、数据访问抽象层等多种功能,简化了Java应用程序的开发过程。在文中提到的个人简历中,熟练掌握Spring框架是求职者技术实力的重要体现,意味着该求职者具备使用Spring进行企业级应用开发的能力。 MySQL数据库 , MySQL是一款开源的关系型数据库管理系统(RDBMS),支持SQL语言,广泛应用于Web应用开发。在本文所述的个人简历中,求职者表明自己熟悉并能熟练使用MySQL进行数据处理,这说明他具备设计数据库结构、执行SQL查询、管理数据库以及与后端应用集成等相关技能,对于需要数据库管理能力的岗位来说,这是一个重要的资质证明。
2023-07-11 12:55:12
500
代码侠
Logstash
...集、处理并解压缩各种数据,并将其发送到各种存储库中。虽然这玩意儿功能确实强大,可有时候吧,也会闹点小脾气。比如说,你可能会遇到“输出插件跟部分输出目标玩不来”的情况。 一、什么是Logstash? Logstash 是由 Elastic 公司开发的一款强大的日志收集、处理和分析工具。它能够把各种来源的数据,比如日志文件啦、数据库里的信息呀,甚至是网络流量那些乱七八糟的东西,一股脑儿地收集起来,集中到一个地方进行统一处理。接着呢,我们可以灵活运用 Logstash 那些超级实用的插件,对这些数据进行各种预处理操作,就比如筛选掉无用的信息、转换数据格式、解析复杂的数据结构等等。最后一步,就是把这些已经处理得妥妥当当的数据,发送到各种各样的目的地去,像是 Elasticsearch、Kafka、Solr 等等,就像快递小哥把包裹精准投递到各个收件人手中一样。 二、问题出现的原因 那么,为什么会出现"输出插件不支持所有输出目标"的问题呢?其实,这主要归咎于 Logstash 的架构设计。 在 Logstash 中,每个输入插件都会负责从源数据源获取数据,然后将这些数据传递给一个或多个中间插件(也称为管道),这些中间插件会根据需求对数据进行进一步处理。最后,这些经过处理的数据会被传递给输出插件,输出插件将数据发送到指定的目标。 虽然 Logstash 支持大量的输入、中间和输出插件,但是并不是所有的插件都能支持所有的输出目标。比如说,有些输出插件啊,它就有点“挑食”,只能把数据送到 Elasticsearch 或 Kafka 这两个特定的地方,而对于其他目的地,它们就爱莫能助了。这就解释了为啥我们偶尔会碰到“输出插件不支持所有输出目标”的问题啦。 三、如何解决这个问题? 要解决这个问题,我们通常需要找到一个能够支持我们所需输出目标的输出插件。幸运的是,Logstash 提供了大量的输出插件,几乎可以满足我们的所有需求。 如果我们找不到直接支持我们所需的输出目标的插件,那么我们也可以尝试使用一些通用的输出插件,例如 HTTP 插件。这个HTTP插件可厉害了,它能帮我们把数据送到任何兼容HTTP接口的地方去,这样一来,咱们就能随心所欲地定制数据发送的目的地啦! 以下是一个使用 HTTP 插件将数据发送到自定义 API 的示例: ruby input { generator { lines => ["Hello, World!"] } } filter { grok { match => [ "message", "%{GREEDYDATA:message}"] } } output { http { url => "http://example.com/api/v1/messages" method => "POST" body => "%{message}" } } 在这个示例中,我们首先使用一个生成器插件生成一条消息。然后,我们使用一个 Grok 插件来解析这条消息。最后,我们使用一个 HTTP 插件将这条消息发送到我们自定义的 API。 四、结论 总的来说,"输出插件不支持所有输出目标" 是一个常见的问题,但是只要我们选择了正确的输出插件,或者利用通用的输出插件自定义数据发送的目标,就能很好地解决这个问题。 在实际应用中,我们应该根据我们的具体需求来选择最合适的输出插件,同时也要注意及时更新 Logstash 的版本,以获取最新的插件和支持。 最后,我希望这篇文章能帮助你更好地理解和使用 Logstash,如果你有任何问题或建议,欢迎随时向我反馈。
2023-11-18 22:01:19
303
笑傲江湖-t
Greenplum
...m的缓存优化策略。在数据处理这块儿,相信咱都明白一个道理,甭管是关系型数据库还是大数据平台,缓存这家伙可是个不可或缺的关键角色。那么,咱们究竟怎样才能通过一些实打实的缓存优化策略,让Greenplum的整体性能蹭蹭上涨呢?不如现在就一起踏上这场揭秘之旅吧! 二、Greenplum缓存的基本概念 首先,我们需要了解Greenplum中的缓存是如何工作的。在Greenplum中,缓存分为两种类型:系统缓存和查询缓存。系统缓存就像是一个超能的小仓库,它专门用来存放咱们绿宝石的各种重要小秘密,这些小秘密包括了表格的结构设计图、查找路径的索引标签等等。而查询缓存则是为了加速重复查询,存储的是SQL语句及其执行计划。 三、缓存的配置和管理 接下来,我们来看看如何配置和管理Greenplum的缓存。首先,我们可以调整Greenplum的内存分配比例来影响缓存的大小。例如,我们可以使用以下命令来设置系统缓存的大小为总内存的25%: sql ALTER SYSTEM SET gp_cached_stmts = 'on'; ALTER SYSTEM SET gp_cache_size = 25; 其次,我们可以通过gp_max_statement_mem参数来限制单条SQL语句的最大内存使用量。这有助于防止大查询耗尽系统资源,影响其他并发查询的执行。 四、缓存的优化策略 最后,我们将讨论一些实际的缓存优化策略。首先,我们应该尽可能地减少对缓存的依赖。你知道吗,那个缓存空间它可不是无限大的,就像我们的手机内存一样,也是有容量限制的。要是咱们老是用大量的数据去频繁查询,就相当于不断往这个小仓库里塞东西,结果呢,可能会把这个缓存占得满满当当的,这样一来,整个系统的运行速度和效率可就要大打折扣了,就跟人吃饱了撑着跑不动是一个道理哈。 其次,我们可以使用视图或者函数来避免多次查询相同的数据。这样可以减少对缓存的需求,并且使查询更加简洁和易读。 再者,我们可以定期清理过期的缓存记录。Greenplum提供了VACUUM命令来进行缓存的清理。例如,我们可以使用以下命令来清理所有过期的缓存记录: sql VACUUM ANALYZE; 五、总结 总的来说,通过合理的配置和管理,以及适当的优化策略,我们可以有效地利用Greenplum的缓存,提高其整体性能。不过呢,咱也得明白这么个理儿,缓存这家伙虽然神通广大,但也不是啥都能搞定的。有时候啊,咱们要是过分依赖它,说不定还会惹出些小麻烦来。所以,在实际动手干的时候,咱们得瞅准具体的情况和需求,像变戏法一样灵活运用各种招数,摸排出最适合自己的那套方案来。真心希望这篇文章能帮到你,要是你有任何疑问、想法或者建议,尽管随时找我唠嗑哈!谢谢大家!
2023-12-21 09:27:50
404
半夏微凉-t
Cassandra
...了Cassandra数据库中内存表(Memtable)切换异常的原理与应对策略后,我们可以进一步关注近期关于NoSQL数据库性能优化和故障处理的相关实践案例。例如,在2022年的一篇技术分享文章中,某大型互联网公司就公开了其在使用Cassandra时遭遇的类似问题以及解决过程,他们通过动态调整Memtable大小、优化写入流程,并结合硬件升级,成功地降低了由于Memtable满载导致的系统延迟问题,显著提升了服务稳定性。 此外,随着云原生时代的到来,Kubernetes等容器编排平台对于管理分布式系统的支持也在不断深化,为解决Cassandra这类分布式数据库的运维难题提供了新的思路。例如,有团队尝试将Cassandra部署在Kubernetes集群上,利用弹性伸缩功能自动根据负载情况调整节点资源,有效防止因资源不足引发的Memtable切换异常。 同时,学术界对NoSQL数据库内部机制的研究也在持续更新。最新的研究论文指出,通过对Memtable结构进行深度优化设计,比如引入多层分级存储、改进数据刷盘算法等方法,能够在保证数据持久性的同时,显著减少由Memtable切换带来的性能影响,这一研究成果有望在未来版本的Cassandra中得到应用。 综上所述,理解并妥善处理Cassandra数据库中的Memtable切换异常只是数据库运维工作的一部分,我们还需紧跟行业趋势和技术发展,结合最新研究成果与实践经验,以实现更加高效稳定的数据库运维管理。
2023-12-10 13:05:30
504
灵动之光-t
站内搜索
用于搜索本网站内部文章,支持栏目切换。
知识学习
实践的时候请根据实际情况谨慎操作。
随机学习一条linux命令:
tac file.txt
- 类似于cat但反向输出文件内容。
推荐内容
推荐本栏目内的其它文章,看看还有哪些文章让你感兴趣。
2023-04-28
2023-08-09
2023-06-18
2023-04-14
2023-02-18
2023-04-17
2024-01-11
2023-10-03
2023-09-09
2023-06-13
2023-08-07
2023-03-11
历史内容
快速导航到对应月份的历史文章列表。
随便看看
拉到页底了吧,随便看看还有哪些文章你可能感兴趣。
时光飞逝
"流光容易把人抛,红了樱桃,绿了芭蕉。"