主流云数据库中的PL调研

简介


Figure 1. Database-as-a-Service Wave, Q2 2017

如今主流云数据库产品大多采用传统RDS上云的方式,在传统RDS上面增加了即时伸缩、监控、数据快照与备份等功能。从开发的角度上看,使用这些云RDS是与传统RDS是相同的,现有数据的代码、应用程序和工具也可以用在这些云RDS上面。对于PL,这些传统云RDS也是支持的,用法和使用与传统RDS一致。

AWS的Aurora和Google的Spanner是两个分布式RDS的代表。Spanner目前尚未提供PL服务,Aurora是兼容MySQL的,提供PL功能的同时,还可以结合AWS Lambda服务使用,减轻了业务逻辑的耦合,又提高了云产品生态圈的粘性。

阿里云已经推出类似的函数计算服务,但是目前仅仅可以通过OSS(对象存储)和fcli命令行触发执行,预计未来会支持API GateWay和RDS,其中RDS触发函数计算服务,很有可能采用与AWS一样的解决方案,即通过PL来调用。
阿里云函数计算

亚马逊AWS RDS

AWS RDS可选6种数据库引擎

  • Amazon Aurora
  • MariaDB
  • MySQL
  • Oracle
  • SQL Server
  • PostgreSQL

Amazon Aurora已支持PL

Amazon Aurora 是与 MySQL 和 PostgreSQL 兼容的关系数据库引擎,既具备高端商用数据库的速度和可用性,又有开源数据库的简单性和成本效益。它的性能最高可达到 MySQL 的五倍,具有商业数据库的安全性、可用性和可靠性,但成本只是商业数据库的十分之一。

性能:在最大的 Amazon Aurora 实例上,您最高可以实现每秒 50 万次读取和 10 万次写入。

PL支持(着重调研AWS Lambda):

  1. 传统方式使用存储过程
  2. 通过存储过程调用AWS Lambda服务(相当于把业务逻辑转移至Lambda服务)

AWS Lambda无需配置或管理服务器即可运行代码。您只需按消耗的计算时间付费 – 代码未运行时不产生费用
AWS Lambda官方介绍

官方推荐的做法是对 mysql.lambda_async 的调用包装在存储过程中,mysql.lambda_async 过程是一个异步调用 Lambda 函数的内置存储过程.即将存储过程的逻辑封装在mysql.lambda_async中,通过CALL存储过程或者触发器来调用mysql.lambda_async中的逻辑。

AWS Lambda 结合PL examples:

  • 通过调用存储过程来调用 AWS Lambda 函数

    AWS Lambda 函数(放置业务逻辑)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    import boto3

    ses = boto3.client('ses')

    def SES_send_email(event, context):

    return ses.send_email(
    Source=event['email_from'],
    Destination={
    'ToAddresses': [
    event['email_to'],
    ]
    },

    Message={
    'Subject': {
    'Data': event['email_subject']
    },
    'Body': {
    'Text': {
    'Data': event['email_body']
    }
    }
    }
    )

    存储过程

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     DROP PROCEDURE IF EXISTS SES_send_email;
    DELIMITER ;;
    CREATE PROCEDURE SES_send_email(IN email_from VARCHAR(255),
    IN email_to VARCHAR(255),
    IN subject VARCHAR(255),
    IN body TEXT) LANGUAGE SQL
    BEGIN
    CALL mysql.lambda_async(
    'arn:aws:lambda:us-west-2:123456789012:function:SES_send_email',
    CONCAT('{"email_to" : "', email_to,
    '", "email_from" : "', email_from,
    '", "email_subject" : "', subject,
    '", "email_body" : "', body, '"}')
    );
    END
    ;;
    DELIMITER ;
调用存储过程来调用 AWS Lambda 函数

1
mysql> call SES_send_email('example_from@amazon.com', 'example_to@amazon.com', 'Email subject', 'Email content');
  • 调用 AWS Lambda 函数来从触发器发布事件

    AWS Lambda 函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import boto3

    sns = boto3.client('sns')

    def SNS_publish_message(event, context):

    return sns.publish(
    TopicArn='arn:aws:sns:us-west-2:123456789012:Sample_Topic',
    Message=event['message'],
    Subject=event['subject'],
    MessageStructure='string'
    )

    存储过程

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      DROP PROCEDURE IF EXISTS SNS_Publish_Message;
    DELIMITER ;;
    CREATE PROCEDURE SNS_Publish_Message (IN subject VARCHAR(255),
    IN message TEXT) LANGUAGE SQL
    BEGIN
    CALL mysql.lambda_async('arn:aws:lambda:us-west-2:123456789012:function:SNS_publish_message',
    CONCAT('{ "subject" : "', subject,
    '", "message" : "', message, '" }')
    );
    END
    ;;
    DELIMITER ;

    1
    2
    3
    4
    5
    6
       CREATE TABLE `Customer_Feedback` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `customer_name` varchar(255) NOT NULL,
    `customer_feedback` varchar(1024) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    触发

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      DELIMITER ;;
    CREATE TRIGGER TR_Customer_Feedback_AI
    AFTER INSERT ON Customer_Feedback
    FOR EACH ROW
    BEGIN
    SELECT CONCAT('New customer feedback from ', NEW.customer_name), NEW.customer_feedback INTO @subject, @feedback;
    CALL SNS_Publish_Message(@subject, @feedback);
    END
    ;;
    DELIMITER ;

    将行插入表中触发通知

    1
    mysql> insert into Customer_Feedback (customer_name, customer_feedback) VALUES ('Sample Customer', 'Good job guys!');

参考文献

  1. 从 Amazon Aurora 数据库群集调用 Lambda 函数
  2. 亚马逊推Aurora新功能 进一步完善AWS服务

MySQL Oracle SQL Server PostgreSQL的PL可以直接在AWS RDS上使用

Amazon RDS 让您能够访问非常熟悉的 MySQL、Oracle、SQL Server 或 PostgreSQL 数据库的功能。这意味着您当前用于现有 数据库的代码、应用程序和工具也可以无缝用于 Amazon RDS
AWS RDS官方说明

MariaDB基于MySQL开发,故可以沿用MySQL的PL

MariaDB Server 是由 MySQL 的原始开发人员创建的一种常用的开源关系数据库。MariaDB 数据库引擎与 MySQL Community Edition 版本 5.5 完全兼容
AWS MariaDB官方文档

##Google Cloud Platform

  • Cloud SQL
  • Cloud Spanner

Cloud SQL是MySQL和PostgreSQL的云数据库版本,在Google Cloud Platform上托管,其中MySQL是5.6或5.7,PostgreSQL是9.6,支持存储过程,语法使用PL/pgSQL SQL procedural language

注意:
Spanner官方文档 中未提及Spanner支持存储过程

微软Azure

  • MySQL
  • PostgreSQL
  • SQL Server
  • Azure Cosmos DB (NoSQL)

原有传统关系型数据库上云,可在云端迅速创建实例并即时伸缩,集成安全、监控、数据快照等功能,减轻数据库管理负担。存储过程的使用与传统关系型数据库相同。

IBM BlueMix

  • Oracle on the cloud
  • MySQL on the cloud
  • DB2 on the cloud

支持存储过程

Oracle Cloud

  • Oracle Exadata Cloud Service
  • MySQL on the cloud

支持存储过程

SAP

SAP HANA提供PL功能及PL的调试
HANA调试PL

EnterpriseDB

对存储过程的支持采用SPL语言
SPL语言
Java调用EDB存储过程