lss/schema

简单的PHP/MySQL架构同步/迁移工具。在PHP中指定您的架构,它将生成DDL和修改表语句以同步数据库。

dev-master 2017-04-17 22:27 UTC

This package is auto-updated.

Last update: 2024-09-22 09:03:15 UTC


README

简单的PHP和MySQL架构同步/迁移工具。

这是基于我在2007年编写的一个古老库,允许在PHP中定义数据库架构,并且(点击一下按钮)可以生成修改表语句以同步MySQL服务器和PHP。这对于拥有非常有限用户数量的一些网站来说很有用。它允许

  • 构建过程按需更新架构。
  • 自定义报告,以检查架构并生成对表和字段的有一定丰富度的描述。用户可以选择从哪个表开始,报告编写者知道由于外键关系,哪些表可以与其连接。
  • 使用graphviz生成数据库图
  • 以及自动化的架构文档,这些都支持报告生成器。
  • 交叉检查外键关系,以便我们可以执行不同类型的数据完整性检查(而不依赖于DBMS维护引用完整性,这在所有情况下都不合理)
  • 检查依赖模型是否正确连接以处理父模型数据更改时的onChange和onDelete事件。(这是在预发布构建步骤中完成的)。

是的,现在有更好的方法来做这件事,使用完整的ORM和其他优点。但是这个很简单,经过多年的战斗测试,快速/轻量,我仍然在一些地方使用它。

所以,这是我为通过composer引入而准备的,也许你会想使用它。最近更新为

  • 使用PHP 7特性
  • PSR-4自动加载
  • 高度单元测试覆盖率
  • 更好的关注点分离(尽管我需要保持与我旧代码的某些兼容性,所以我不必重写所有使用它的东西)。

以程序方式声明架构

$schema = new LSS\Schema();
$userTable = new LSS\Schema\Table('user', 'users who can log in');
$userTable->addColumn(new Column\PrimaryKey('id', 'unique user id'));
$userTable->addColumn(new Column\String('first_name', 'user first name', false, 40));
$userTable->addColumn(new Column\String('family_name', 'user family name', false, 40));
$userTable->addColumn(new Column\String('email', 'email address', false, 200));
$userTable->addColumn(new Column\String('password', 'bcrypt encoded password', false, 60));
$schema->add($userTable);

$groupTable = new LSS\Schema\Table('group', 'groups of users');
$groupTable->addColumn(new Column\PrimaryKey('id', 'unique group id'));
$groupTable->addColumn(new Column\String('name', 'name of the group', false, 40));
$groupTable->addColumn(new Column\Text('name', 'description of the group'));
$schema->add($groupTable);

$userGroupTable->addColumn(new Column\ForeignKey($userTable->getName(), 'which user'));
$userGroupTable->addColumn(new Column\ForeignKey($groupTable->getName(), 'which group'));
$schema->add($userGroupTable);

// get the DDL for the database (if needed)
$ddlGenerator = new LSS\Schema\Renderer\AlterTableSQL();
$ddl = $ddlGenerator->render($schema);

解析mysqldump

$sql = 'create table....'; // mysql ddl from mysqldump
$parsedSchema = new LSS\Schema();
$parser = new LSS\Schema\Parser();
$parser->parse($parsedSchema,$sql);

比较两者

$comparator = new LSS\Schema\Renderer\AlterTableSQL();
$alterTableSQL = $comparator->render($schema, $parsedSchema);
// contains the alter table statements to update the mysql server and make it look like $schema

已知限制

  • 不允许在表或字段注释中有分号
  • 不处理表末尾的元数据等
  • 与表中首先具有单个整数主键索引字段的情况配合得更好
  • 同步/比较器可以处理一列或多列的添加/删除/重命名,但如果一次进行大量大改动,它就会很容易混淆。为每个字段设置唯一注释有助于其重新同步。您可以为要修改的字段更改(列名、数据类型、注释)之一。更改两个,它将认为这是一个新字段,删除旧的一个并添加一个新的。

便利方法

请参阅示例目录,其中包含一个实现许多便利方法的类,以使构建数据库变得非常容易。

class Builder
{
    /**
     * return a Schema that contains the full database description
     * @return Schema
     */
    public function build()
    {
        $schema = new Schema();
        $this->addTable($schema, 'person', 'Data about one human being' )
            ->addPrimaryKeyColumn   ()
            ->addForeignKeyColumn   ( 'family' ) // the family that this person belongs to
            ->addStringColumn       ( 'title'           , 15                           , 'Mr Mrs Miss Prof Rev etc' )
            ->addStringColumn       ( 'first_name'      , FieldLength::PERSON_PART_NAME, 'Personal first name' )
            ->addStringColumn       ( 'middle_name'     , FieldLength::PERSON_PART_NAME, 'Middle name' )
            ->addStringColumn       ( 'family_name'     , FieldLength::PERSON_PART_NAME, 'Personal surname' )
            ->addEnumerationColumn  ( 'gender'          , array( 'Male', 'Female' ) )
            ->addDateColumn         ( 'birth_date'                                     , 'When the person was born' )
            ->addStringColumn       ( 'email'           , FieldLength::EMAIL           , 'Verified email address' )
            ->addStringColumn       ( 'user_name'       , FieldLength::USER_NAME       , 'Username to log in' )
            ->addDateTimeColumn     ( 'last_login'                                     , 'Date and time this user last logged in' )
            ->addTextColumn         ( 'biography'                                      , 'Brief one paragraph bio in plain text' )
            ->addTextColumn         ( 'preferences'                                    , 'Serialized array of user preference settings' )
            ->addStringColumn       ( 'facebook_link'   , FieldLength::WEBSITE         , 'Link to your facebook page' )
            ->addStringColumn       ( 'linkedin_profile', FieldLength::WEBSITE         , 'URL to www.linkedin.com for professional profile' )
            ->addDateCreatedColumn ()
            ->addLastModifiedColumn()
            ->addStandardIndex( 'user_name' );

        // $this->addTable($schema, $family, ... etc

        $this->addTable($schema, 'config', 'Collection of user adjustable system settings and parameters' )
            ->addPrimaryKeyColumn   ( 'id' )
            ->addStringColumn       ( 'name'       ,100, 'Name of the setting' )
            ->addTextColumn         ( 'value'          , 'Value of the setting' )
            ->addTextColumn         ( 'description'    , 'Help text about the setting' )
            ->addEnumerationColumn  ( 'page'           , array( 'Hidden', 'System', 'Finance', 'Person', 'Placement', 'JobOpenings' ), 'A useful subgrouping of items to help you find them' )
            ->addEnumerationColumn  ( 'field_type'     , array( 'Boolean', 'Integer', 'Decimal', 'Select', 'Currency', 'FreeText', 'HTML' ), 'What type of data entry field should be used' )
            ->addLastModifiedColumn ();

        return $schema;
    }

    /**
     * wrapper method so we can have a fluent syntax above.
     *
     * @param Schema $schema
     * @param string $name
     * @param string $description
     * @return AugmentedTable
     */
    private function addTable(Schema $schema, $name, $description = '')
    {
        $schema->add( $table = new AugmentedTable($name, $description) );
        return $table;
    }
}