【问题标题】:How to ensure SQL database design will be cross platform如何确保 SQL 数据库设计将是跨平台的
【发布时间】:2019-12-16 04:59:10
【问题描述】:

我正在做一个项目,我当前的开发环境基于 MySQL,而生产环境可能是 MySQL 或 Microsoft SQL Server。我试图确保我为构建数据库表而编写的 SQL 将是跨平台的。

我已经发现 ZEROFILL 属性是非标准的,所以我假设它在 MySQL 之外不可用。

CREATE TABLE
 `scfe`.`tbl_UserRoles` ( 
 `UserRoleRecID` INT(7) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'User Role Rec ID' ,
 `UserADID` CHAR(50) NOT NULL COMMENT 'User ADID FK - tbl_Users.UserADID' ,
 `UserRole` CHAR(150) NOT NULL COMMENT 'User Role FK - systbl_SYS_Roles.UserRoleID' ,
 `Status` ENUM('A','I') NOT NULL DEFAULT 'I' COMMENT 'User Role Status - A = Active, I = Inactive // Default = I' ,
`RoleDateAdded` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP , 
`RoleDateModified` DATETIME on update CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , 
PRIMARY KEY (`UserRoleRecID`), 
INDEX `Index_UserADID` (`UserADID`), 
INDEX `Index_UserRole` (`UserRole`), 
INDEX `Index_RoleStatus` (`Status`))
 ENGINE = MyISAM;

由于我想确保代码能够在系统之间轻松转换,是否还有其他功能/选项不能跨平台(例如,基于上面的代码,是否有默认的CURRENT_TIMESTAMP?更新有没有应该使用的替代品?

我知道引擎行不需要在 MySQL 之外使用。

【问题讨论】:

  • @a_horse_with_no_name 你能推荐一个在两者之间转换的工具或参考。如前所述,由于我不知道最终的目标平台,我试图不使用平台相关的功能。

标签: sql standards ansi-sql


【解决方案1】:

您无法编写与 MySQL 和 SQL Server 相同的单个 CREATE TABLE 语句并产生您现在所拥有的结果,例如生成 ID 需要在 SQL Server 中使用 identity(...) 选项,您在 MySQL 中使用 auto_increment。这些选项都不是标准 SQL(即generated always as identity)。

数据类型是下一个问题。特别是 datetime/timestamp 类型有很大的不同,你不会有太多的运气。顺便说一句:停止使用char() - 这种类型只有缺点,绝对没有任何优点。

您无法在跨 DBMS 设计中使用 ENUM 之类的东西。请改用查找表。

约束和索引是下一个问题。列和表 cmets 也是如此(SQL Server 仅通过调用存储“扩展属性”的存储过程来“支持”它们)。

我建议使用例如Liquibase 采用 XML 格式,可轻松用于各种数据库产品。例如如果您使用 autoIncrement="true",Liquibase 知道如何创建“生成的 ID”列——它将使用 auto_increment 用于 MySQL,identity() 用于 SQL Server,serial 用于 Postgres。

如果您使用“标准 JDBC”数据类型,Liquibase 也知道如何翻译它们。例如timestamp 在 SQL Server 中将变为 datetime

您的陈述将导致以下内容:

<!-- lookup table for status -->
<createTable tableName="role_status"  schemaName="scfe" remarks="User Role Status - A = Active, I = Inactive // Default = I">
  <column name="status_id" type="integer">
    <constraints nullable="false" primaryKey="true" primaryKeyName="pk_role_status" />
  </column>
  <column name="status_code" type="varchar(1)" />
</createTable>

<createTable tableName="user_roles" schemaName="scfe">
  <column name="userrolerecid" type="integer" autoIncrement="true" remarks="User Role Rec ID">
    <constraints nullable="false" primaryKey="true" primaryKeyName="pk_user_roles" />
  </column>
  <column name="useradid" type="varchar(50)" remarks="User ADID FK - tbl_Users.UserADID">
    <constraints nullable="false"/>
  </column>
  <column name="user_role" type="varchar(150)" remarks="User Role FK - systbl_SYS_Roles.UserRoleID'">
    <constraints nullable="false"/>
  </column>
  <column name="status_id" type="varchar(1)">
    <constraints nullable="false"/>
  </column>
  <column name="role_date_added" type="timestamp">
    <constraints nullable="false"/>
  </column>
  <column name="role_date_modified" type="timestamp"/>
</createTable>

<addForeignKeyConstraint constraintName="fk_user_role2status" 
                         baseTableName="user_roles" 
                         baseColumnNames="status_id" 
                         referencedTableName="role_status" 
                         referencedColumnNames="status_id" />

<addForeignKeyConstraint constraintName="fk_user_role2role" 
                         baseTableName="user_roles" 
                         baseColumnNames="user_role" 
                         referencedTableName="roles" 
                         referencedColumnNames="user_role_id" />

<addForeignKeyConstraint constraintName="fk_user_role2adid" 
                         baseTableName="user_roles" 
                         baseColumnNames="useradid" 
                         referencedTableName="users" 
                         referencedColumnNames="useradid" />

<createIndex indexName="index_useradid" tableName="user_roles">
  <column name="useradid"/>
</createIndex>

<createIndex indexName="index_userrole" tableName="user_roles">
  <column name="user_role"/>
</createIndex>

<createIndex indexName="index_rolestatus" tableName="user_roles">
  <column name="status_id"/>
</createIndex>

这可以通过使用参数或仅针对特定 DBMS 产品运行某些事情(例如创建检查约束或特殊索引类型)

【讨论】:

    猜你喜欢
    • 2011-11-13
    • 1970-01-01
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    相关资源
    最近更新 更多