从MySQL切换到SQLServer:困难程度?

从MySQL切换到SQLServer:困难程度?,mysql,sql,sql-server,Mysql,Sql,Sql Server,我已经将任何具有UI的构建切换到了C#。到目前为止,我一直是纯C++的。我只在数据库方面使用过MySQL和SQLite 当我想象C#+SQLServer更好地相处时,我很想切换到只使用微软的堆栈 因此,我设置了一个LocalDB实例,从MySQL切换一些表,以了解情况。显然,在使用SQLServer的15分钟内,我成功地获得了预期的WTF时刻: 如果不存在,则不存在。您需要将CREATE TABLE包装成一个疯狂的IF来复制功能。与约束相同 UNIQUE列考虑了NULL,因此只能有一个NULL。

我已经将任何具有UI的构建切换到了C#。到目前为止,我一直是纯C++的。我只在数据库方面使用过MySQL和SQLite

当我想象C#+SQLServer更好地相处时,我很想切换到只使用微软的堆栈

因此,我设置了一个LocalDB实例,从MySQL切换一些表,以了解情况。显然,在使用SQLServer的15分钟内,我成功地获得了预期的WTF时刻:

  • 如果不存在
    ,则不存在
    。您需要将
    CREATE TABLE
    包装成一个疯狂的
    IF
    来复制功能。与约束相同
  • UNIQUE
    列考虑了
    NULL
    ,因此只能有一个
    NULL
    。您需要使用
    WHERE
    设置一个特殊的
    非集群唯一
    ,以复制表示
    NULL
    不存在且无法比较的预期功能
  • 没有插入忽略之类的事情。在实际的
    唯一
    键上设置
    IGNORE\u DUP\u KEY=ON
    标志
  • 对于同一表中的
    主键
    外键,更新级联时没有
    ,删除级联时没有
    。我知道您不经常更新主键,但是没有
    删除级联
  • 样品

    CREATE TABLE t0 
    (
        id   INTEGER NOT NULL IDENTITY(1,1) PRIMARY KEY,
        parent_id INTEGER DEFAULT NULL
            references t0 (id) on delete cascade on update cascade
    );
    
  • 几年前我尝试使用SQLServer,但找不到如何对结果进行分页(除了
    TOP
    )。现在我看到他们添加了
    OFFSET
    +
    NEXT
    来实现这一点
  • 这只是15分钟的测试

    问题是:

    整个过程都是这样吗?微软真的在SQLServer上走自己的路吗?(他们已经用IE做了十多年了)并不是说我期望完全的查询级兼容性,而是说真的。。。如果不存在
    INSERT IGNORE
    CREATE TABLE
    或将
    NULL
    视为无效而不是实际值,有多困难


    是否有人可以分享一些关于更平稳过渡的提示,或者我应该坚持使用
    MySQL
    ,这是我已经有一段时间的朋友了。。。但是GPL呢?

    这并不难。 SQL server有很多MySQL没有的额外内容
    CTE、可写CTE、递归CTE等

    您可以使用nHibernate或entity framework之类的工具,首先使用数据库轻松地重新创建/迁移表
    当然,您需要手动修复的是数百万件小事(如唯一索引)。
    实际上,您可以创建一个经过筛选的唯一索引(
    ,其中您的_列不为null


    此外,SQL Server不会为您截断过长的字符串,这可能需要一些难看的应用程序代码管道
    如果使用自动增量ID,也需要手动管道。

    但主要问题是你的观点和程序
    这几乎是手工操作,因此耗时且容易出错。
    此外,在SQLServer中,您几乎可以忘记标量函数,因为它们在几乎所有方面都太慢了(它们在一些方面很有用)

    问题主要是在应用程序代码中使用
    System.Data.Common
    中的抽象类,而不是
    System.Data.SqlClient

    因此,当您有一个使用MySQL.Data.MySqlClient的应用程序,或一个使用System.Data.SqlClient的应用程序,并且您想要从SQL server或切换到SQL server时,您还必须重新编写应用程序代码,而不仅仅是SQL。
    这就是为什么您应该始终使用
    System.Data.Common
    ,而不是
    “当日名称空间”。SqlConnection

    对于分页,SQL Server 2012+支持ANSI-SQL分页方法:

    SELECT
         [TransactionID]
        ,[ProductID]
        ,[ReferenceOrderID]
        ,[ReferenceOrderLineID]
        ,[TransactionDate]
        ,[TransactionType]
        ,[Quantity]
        ,[ActualCost]
        ,[ModifiedDate]
    FROM [Production].[TransactionHistoryArchive]
    ORDER BY [TransactionID]
    OFFSET 5001 ROWS
    FETCH NEXT 100 ROWS ONLY 
    
    在SQL server 2012之前,您必须使用CTE:

    ;WITH CTE AS (
     SELECT
             [TransactionID]
            ,[ProductID]
            ,[ReferenceOrderID]
            ,[ReferenceOrderLineID]
            ,[TransactionDate]
            ,[TransactionType]
            ,[Quantity]
            ,[ActualCost]
            ,[ModifiedDate]
            ,ROW_NUMBER() OVER (ORDER BY ActualCost DESC) AS rn 
        FROM [Production].[TransactionHistoryArchive]
    )
    SELECT * FROM CTE WHERE rn BETWEEN @min_row AND @max_row
    
    要在表不存在时创建表,需要将表创建代码放入动态SQL中:

    IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[T_Verbs]') AND type in (N'U'))
    BEGIN
    
    CREATE TABLE [dbo].[T_Verbs](
        [Id] [int] NULL,
        [Infinitive] [nvarchar](500) NULL,
        [FirstPerson] [nvarchar](500) NULL,
        [SecondPerson] [nvarchar](500) NULL,
        [ThirdPerson] [nvarchar](500) NULL,
        [Singular] [bit] NULL,
        [Plural] [bit] NULL
    ) ON [PRIMARY]
    END
    
    
    
    IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[T_Verbs]') AND type in (N'U'))
    BEGIN
    EXEC('
    CREATE TABLE [dbo].[T_Verbs](
        [Id] [int] NULL,
        [Infinitive] [nvarchar](500) NULL,
        [FirstPerson] [nvarchar](500) NULL,
        [SecondPerson] [nvarchar](500) NULL,
        [ThirdPerson] [nvarchar](500) NULL,
        [Singular] [bit] NULL,
        [Plural] [bit] NULL
    ) ON [PRIMARY]
    ');
    END
    
    
    GO
    
    至于切换到SQL Server:为什么
    这只是一个过于昂贵的授权噩梦。
    您使用MySQL的能力要好得多。
    但是,如果您需要数据完整性、MySQL和ANSI兼容的分页以及CTE、数组、关联数组、JSON等,我会转而使用PostgreSQL


    在我看来,只有当您需要SQL server提供的商业智能功能时,SQL server才是真正优秀的(顺便说一句,不要期望BI web版与InternetExplorer[QuirksMode]以外的任何东西真正兼容),或者,当您有很多客户端使用SQL server而不需要其他东西时。

    在我使用过的所有DBMS中,MySQL肯定有更多的WTF时刻,尤其是它关于数据完整性的所有“功能”——我相信您会被它宠坏。在任何情况下,尽管我理解你的悲痛,但恐怕这个问题太大,太主观了,以至于不能在堆栈溢出时做得很好。“没有更新级联”——SQL Server肯定支持:BTW:如果你正在寻找一个开源的替代MySQL,而不是GPL,你应该认真考虑PASGRESNR 2)对我来说似乎很好。nr 5)几年前你也可以这样做。现在你有了一个更简单的语法,你也许可以在MySQL中声明这样一个外键,但由于MySQL的约束处理(在我看来是错误的),你不能真正从表中删除:。我非常习惯手工编写查询。看过一些EF基准测试,但看起来不太好。我想我确实会研究一下PostgreSQL。他们的数组数据类型看起来不错。粗体您是最后一段,它总结了所有内容。@CodeAngry:只是澄清一下:我没有说您应该使用EF或nhibernate。事实上,恰恰相反,如果说表现糟糕,那对那些人来说就是奉承。我的意思是,您可以使用这些工具将表架构迁移到SQL Server。然后您可以使用SSMS让它创建表创建脚本。当然,您需要手动检查结果(一刻也不要相信他们会做每一件事)