承接 vonbraunlabs/sql-ddl-generator 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

vonbraunlabs/sql-ddl-generator

Composer 安装命令:

composer require vonbraunlabs/sql-ddl-generator

包简介

README 文档

README

A tool to aid on generating DDL SQL. It was conceived to abstract away the boring part of writing the SQL tables and let developers/DBAs focus on the business logic. This tool assumes that every table have:

  • an integer ID column that uniquely identifies the row and is named ID
  • audit columns to specify created time and last updated time
  • audit columns to specify the db user who created the row and the one who last updated the row
  • active column that indicates wether that row is active or should be regarded as deleted/inactive

The file user.json contains the following JSON:

{
    "name": "mydatabase",
    "table": {
        "name": "user",
        "field_list": [
            {
                "name": "username",
                "type": "VARCHAR(30)",
                "not_null": true,
                "comment": "Login username"
            },
            {
                "name": "email",
                "type": "VARCHAR(64)",
                "not_null": true,
                "comment": "User email"
            },
            {
                "name": "password",
                "type": "VARCHAR(128)",
                "not_null": true,
                "comment": "User password"
            },            
            {
                "name": "confirmed_at",
                "type": "DATETIME",
                "not_null": false,
                "comment": "User confirmation date"
            }
        ],
        "fk_list": [
            {
                "name": "inviter_id",
                "references": "user",
                "comment": "If user was invited by someone, contains the ID of that user account, NULL otherwise"
            }
        ],
        "unique_list": [
            ["username"],
            ["email"]
        ]
    }
}

The name of the schema/database is mydatabase. It is creating a table named user, with four columns: username, email, password and confirmed_at. Moreover, it declares a foreign key column inviter_id to itself. On its last part, the snippet declares UNIQUE constraints. The rows must have unique username and unique email. Executing ./sql-ddl-generator user.json the following is printed to standard output:

-- Generated by VBL - sql-ddl-generator
-- -----------------------------------------------------
-- Database mydatabase
-- -----------------------------------------------------

CREATE SCHEMA IF NOT EXISTS `mydatabase` DEFAULT CHARACTER SET utf8 ;
USE `mydatabase`;

-- -----------------------------------------------------
-- Table `mydatabase`.`user`
-- -----------------------------------------------------

CREATE TABLE IF NOT EXISTS `mydatabase`.`user` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
    `username` VARCHAR(30) NOT NULL COMMENT 'Login username',
    `email` VARCHAR(64) NOT NULL COMMENT 'User email',
    `password` VARCHAR(128) NOT NULL COMMENT 'User password',
    `confirmed_at` DATETIME COMMENT 'User confirmation date',
    `active` BOOLEAN NOT NULL DEFAULT 1,
    `create_by` VARCHAR(32) NOT NULL,
    `create_time` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `update_by` VARCHAR(32) NOT NULL,
    `update_time` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `inviter_id` INT UNSIGNED COMMENT 'If user was invited by someone, contains the ID of that user account, NULL otherwise',
    PRIMARY KEY (`id`),
    CONSTRAINT `fk_user_inviter_id`
        FOREIGN KEY(`inviter_id`)
        REFERENCES `mydatabase`.`user` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION
) Engine=InnoDB;

CREATE UNIQUE INDEX `unique_user_username` ON `mydatabase`.`user` (`username`);
CREATE UNIQUE INDEX `unique_user_email` ON `mydatabase`.`user` (`email`);

CREATE TRIGGER `user_before_insert` BEFORE INSERT ON `mydatabase`.`user`
FOR EACH ROW
    SET NEW.`create_by` = CURRENT_USER(),
        NEW.`update_by` = CURRENT_USER();

CREATE TRIGGER `user_before_update` BEFORE UPDATE ON `mydatabase`.`user`
FOR EACH ROW
    SET NEW.`update_by` = CURRENT_USER(),
        NEW.`update_time` = CURRENT_TIMESTAMP(3);

Auditing Special Feature

For some application, it is necessary to keep track of all changes on table, usually for auditing porposes. The audit flag creates a clone of the table with the prefix audit_ in its name and store all changes on the clonned table. If a row is updated N times, there will be N records of that specific row on the equivalent audit table.

{
    "name": "mydatabase",
    "table": {
        "name": "user",
        "field_list": [
            {
                "name": "username",
                "type": "VARCHAR(30)",
                "not_null": true,
                "comment": "Login username"
            },
            {
                "name": "email",
                "type": "VARCHAR(64)",
                "not_null": true,
                "comment": "User email"
            },
            {
                "name": "password",
                "type": "VARCHAR(128)",
                "not_null": true,
                "comment": "User password"
            },            
            {
                "name": "confirmed_at",
                "type": "DATETIME",
                "not_null": false,
                "comment": "User confirmation date"
            }
        ],
        "fk_list": [
            {
                "name": "inviter_id",
                "references": "user",
                "comment": "If user was invited by someone, contains the ID of that user account, NULL otherwise"
            }
        ],
        "unique_list": [
            ["username"],
            ["email"]
        ],
        "audit": true
    }
}

Consider the JSON above. From this model, the sql-ddl-generator will produce SQL below. Mind how tedious it would be to write that that SQL by hand. Now imagine you have many tables that require that auditing feature.

-- Generated by VBL - sql-ddl-generator
-- -----------------------------------------------------
-- Database mydatabase
-- -----------------------------------------------------

CREATE SCHEMA IF NOT EXISTS `mydatabase` DEFAULT CHARACTER SET utf8 ;
USE `mydatabase`;

-- -----------------------------------------------------
-- Table `mydatabase`.`user`
-- -----------------------------------------------------

CREATE TABLE IF NOT EXISTS `mydatabase`.`user` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
    `username` VARCHAR(30) NOT NULL COMMENT 'Login username',
    `email` VARCHAR(64) NOT NULL COMMENT 'User email',
    `password` VARCHAR(128) NOT NULL COMMENT 'User password',
    `confirmed_at` DATETIME COMMENT 'User confirmation date',
    `active` BOOLEAN NOT NULL DEFAULT 1,
    `create_by` VARCHAR(32) NOT NULL,
    `create_time` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `update_by` VARCHAR(32) NOT NULL,
    `update_time` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `who_id` INT UNSIGNED NOT NULL,
    `inviter_id` INT UNSIGNED COMMENT 'If user was invited by someone, contains the ID of that user account, NULL otherwise',
    PRIMARY KEY (`id`),
    CONSTRAINT `fk_user_who_id`
        FOREIGN KEY(`who_id`)
        REFERENCES `mydatabase`.`user` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
    CONSTRAINT `fk_user_inviter_id`
        FOREIGN KEY(`inviter_id`)
        REFERENCES `mydatabase`.`user` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION
) Engine=InnoDB;

CREATE UNIQUE INDEX `unique_user_username` ON `mydatabase`.`user` (`username`);
CREATE UNIQUE INDEX `unique_user_email` ON `mydatabase`.`user` (`email`);

CREATE TRIGGER `user_before_insert` BEFORE INSERT ON `mydatabase`.`user`
FOR EACH ROW
    SET NEW.`create_by` = CURRENT_USER(),
        NEW.`update_by` = CURRENT_USER();

CREATE TRIGGER `user_before_update` BEFORE UPDATE ON `mydatabase`.`user`
FOR EACH ROW
    SET NEW.`update_by` = CURRENT_USER(),
        NEW.`update_time` = CURRENT_TIMESTAMP(3);

-- -----------------------------------------------------
-- Audit Table for user
-- -----------------------------------------------------

CREATE TABLE IF NOT EXISTS `mydatabase`.`audit_user` LIKE `mydatabase`.`user`;
ALTER TABLE `mydatabase`.`audit_user` ADD COLUMN `user_id` INT UNSIGNED NOT NULL AFTER `id`;
ALTER TABLE `mydatabase`.`audit_user` ADD     CONSTRAINT `fk_audit_user_user_id`
        FOREIGN KEY(`user_id`)
        REFERENCES `mydatabase`.`user` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION;

DROP INDEX `unique_user_username` ON `mydatabase`.`audit_user`;
DROP INDEX `unique_user_email` ON `mydatabase`.`audit_user`;

ALTER TABLE `mydatabase`.`audit_user` ADD     CONSTRAINT `fk_audit_user_who_id`
        FOREIGN KEY(`who_id`)
        REFERENCES `mydatabase`.`user` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION;
ALTER TABLE `mydatabase`.`audit_user` ADD     CONSTRAINT `fk_audit_user_inviter_id`
        FOREIGN KEY(`inviter_id`)
        REFERENCES `mydatabase`.`user` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION;
delimiter //
CREATE TRIGGER `audit_user_insert_trigger`
AFTER INSERT ON `mydatabase`.`user`
FOR EACH ROW
BEGIN
    INSERT INTO `mydatabase`.`audit_user` (
        `user_id`,
        `username`,
        `email`,
        `password`,
        `confirmed_at`,
        `active`,
        `create_by`,
        `update_by`,
        `who_id`,
        `inviter_id`
    ) VALUES (
        NEW.`id`,
        NEW.`username`,
        NEW.`email`,
        NEW.`password`,
        NEW.`confirmed_at`,
        NEW.`active`,
        NEW.`create_by`,
        NEW.`update_by`,
        NEW.`who_id`,
        NEW.`inviter_id`
    );
END;//
DELIMITER ;

delimiter //
CREATE TRIGGER `audit_user_update_trigger`
AFTER UPDATE ON `mydatabase`.`user`
FOR EACH ROW
BEGIN
    INSERT INTO `mydatabase`.`audit_user` (
        `user_id`,
        `username`,
        `email`,
        `password`,
        `confirmed_at`,
        `active`,
        `create_by`,
        `update_by`,
        `who_id`,
        `inviter_id`
    ) VALUES (
        NEW.`id`,
        NEW.`username`,
        NEW.`email`,
        NEW.`password`,
        NEW.`confirmed_at`,
        NEW.`active`,
        NEW.`create_by`,
        NEW.`update_by`,
        NEW.`who_id`,
        NEW.`inviter_id`
    );
END;//
DELIMITER ;

vonbraunlabs/sql-ddl-generator 适用场景与选型建议

vonbraunlabs/sql-ddl-generator 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 743 次下载、GitHub Stars 达 8, 最近一次更新时间为 2018 年 01 月 16 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 vonbraunlabs/sql-ddl-generator 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 vonbraunlabs/sql-ddl-generator 我们能提供哪些服务?
定制开发 / 二次开发

基于 vonbraunlabs/sql-ddl-generator 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 743
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 8
  • 点击次数: 3
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 8
  • Watchers: 1
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: Unknown
  • 更新时间: 2018-01-16