spark操作关系型数据库

该博客介绍了如何使用Spark读取和写入MySQL及Oracle数据库的数据。提供了两种读取MySQL数据的方法,包括通过`jdbc`函数指定条件加载数据,并讨论了并行处理时的注意事项。同时展示了如何将处理后的数据写入Oracle数据库,使用`write`方法并设置相关选项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mysql

方法1

    val prop = new Properties()
    prop.setProperty("user", "xxx")
    prop.setProperty("password", "xxx")
    val url = "jdbc:mysql://ip:port/cdp?useUnicode=true&characterEncoding=utf-8"

    spark.read.
      option("driver", "com.mysql.jdbc.Driver").
      jdbc(url, "client_group",  prop).
 //   jdbc(url, "client_group", Array("proc_status=1", "opt_type!=2", "expired_time < now()"), prop).
      persist(StorageLevel.MEMORY_ONLY).
      createOrReplaceTempView("tv_client_group")

以下方法并行处理,但要注意条件是否包含重合数据

jdbc(url, "client_group", Array("proc_status=1", "opt_type!=2", "expired_time < now()"), prop)

方法2

val dataframe = spark.read.
      format("jdbc").
      option("driver", "com.mysql.jdbc.Driver").
      option("dbtable", "dbTableName").
      option("url", url).
      option("user", "userName").
      option("password", "password").
      load()

调用write方法

oracle

sql(
        s"""SELECT
           |  cast(MEMBER_ID as INT) MEMBER_ID,
           |  IF(sale_channel = '1',  CAST(NULL AS STRING), store_id) STORE_CODE,
           |  score INDI_VALUE,
           |  1 IS_LATEST,
           |  CAST('$quarterDate' AS TIMESTAMP) CREATE_TIME,
           |  bu_id BU_CODE,
           |  CAST(NULL AS INT) MEMBER_ID_TMP
           |FROM recommendation.member_attribute_store
           |WHERE create_date='$quarterDate'
           |""".stripMargin).
        write.option("driver", "oracle.jdbc.driver.OracleDriver").
        mode(SaveMode.Append).jdbc(url, tableName, prop) 

<think>嗯,用户这次想用Spark操作关系型数据库,还明确要求示例代码。之前系统指令要求用$$...$$格式,代码块单独处理就行。用户引用的资料里[^1]和[^3]提到SparkSQL和DataFrame操作,[^2]是MongoDB非关系型数据库,[^4]讲缓存,后两个可能用不上。用户可能正在搭建数据管道,需要Spark和传统数据库(比如MySQL、PostgreSQL)交互。ta特意强调“关系型数据库”,排除NoSQL方案。从ta直接要代码的行为看,可能急着做原型开发,或是作业deadline临近?技术细节上需要分三块回复:连接数据库(重点在JDBC配置)、读写操作、异常处理。引用[^3]的DataFrame示例可以直接复用,但要补充数据库交互部分。安全方面得提醒用户隐藏密码,性能方面要注意分区和批量操作。示例代码选Scala和Python双版本,覆盖主流用户群。Java版本太冗长,主动过滤掉。连接参数比如url格式是易错点,要单独标注。事务管理可能高级用户需要,列在相关问题里更合适。突然想到个隐患:用户环境可能有驱动jar包冲突,得在注意事项里加粗提示。另外测试阶段建议用小型数据集,避免直接污染生产库。</think> 以下是使用Spark连接和操作关系型数据库的完整指南,包含详细代码示例和最佳实践: --- ### 一、Spark连接关系型数据库步骤 #### 1. 添加JDBC驱动依赖 ```scala // Maven配置 (以MySQL为例) <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> ``` #### 2. 基础连接示例(Scala/Python) ```python # Python示例 (PySpark) from pyspark.sql import SparkSession spark = SparkSession.builder \ .appName("JDBCExample") \ .config("spark.jars", "mysql-connector-java-8.0.33.jar") \ # 驱动路径 .getOrCreate() # 数据库连接参数 jdbc_url = "jdbc:mysql://your-db-host:3306/your_db" connection_properties = { "user": "your_username", "password": "your_password", "driver": "com.mysql.jdbc.Driver" } ``` --- ### 三、核心操作示例 #### 1. 读取数据库表 → DataFrame ```python # 读取整表 df = spark.read.jdbc( url=jdbc_url, table="employees", properties=connection_properties ) # 条件读取 (高效分页) df_filtered = spark.read.jdbc( url=jdbc_url, table="(SELECT * FROM employees WHERE salary > 50000) AS tmp", properties=connection_properties ) ``` #### 2. 写入数据到数据库 ```python # 全量覆盖写入 df.write \ .format("jdbc") \ .option("url", jdbc_url) \ .option("dbtable", "new_employees") \ .option("user", "your_username") \ .option("password", "your_password") \ .mode("overwrite") \ .save() # 增量追加 df.write \ .mode("append") \ .jdbc(url=jdbc_url, table="existing_employees", properties=connection_properties) ``` --- ### 三、高级操作技巧 #### 1. 分区读取加速(百万级数据) ```python df_partitioned = spark.read.jdbc( url=jdbc_url, table="big_table", column="id", # 分区列 lowerBound=1, # 最小值 upperBound=1000000, # 最大值 numPartitions=8, # 并行分区数 properties=connection_properties ) ``` #### 2. 事务性批量写入(Python) ```python df.foreachPartition(lambda partition: # 每个分区建立独立连接 with pymysql.connect(**db_params) as conn: with conn.cursor() as cursor: for row in partition: cursor.execute(""" INSERT INTO orders (id, amount) VALUES (%s, %s) """, (row.id, row.amount)) conn.commit() ) ``` --- ### 四、注意事项 1. **连接池管理**: ```scala .config("spark.datasource.connectionPool", "HikariCP") // 使用连接池提升性能 ``` 2. **数据类型映射**: - Spark的`DecimalType` ↔ 数据库`DECIMAL` - `DateType` ↔ `DATE`/`DATETIME` 3. **事务控制**: - 批量操作时启用`rewriteBatchedStatements=true` (MySQL) - 设置`isolationLevel=READ_COMMITTED` --- ### 五、最佳实践 1. **资源优化**: ```bash # 提交作业时限制内存 spark-submit --executor-memory 8g ... ``` 2. **容错处理**: ```python try: df.write.jdbc(...) except java.sql.BatchUpdateException as e: # 处理主键冲突等异常 ``` 3. **数据校验**: ```python source_count = df.count() written_count = spark.read.jdbc(...).where("batch_id=123").count() assert source_count == written_count ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大怀特

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值