【问题标题】:dbWriteTable removes primary keys and indexes in MySQLdbWriteTable 删除 MySQL 中的主键和索引
【发布时间】:2019-05-14 14:36:10
【问题描述】:

我创建一个 MySQL 表如下:

create table schema_name.test (
col1 varchar(10),
col2 varchar(10),
primary key (col1),
index col1_index (col1)
)

然后我使用dbWriteTabledata.frame 写入表格,如下所示:

> test <- data.frame(col1 = c("a","b"),col2 = c("apple","banana"))
> types <- c("varchar(10)","varchar(10)")
> names(types) <- names(test)
> dbWriteTable(conn = con, overwrite = TRUE, value = test, name = "test",field.types = types)

执行此操作并在 MySQL 环境中检查表后,我看到主键和索引已被删除(con 这里是使用dbConnect( odbc::odbc(),"my_dsn_name") 创建的连接对象)。这是不希望的。

我试图实现的行为是覆盖表中的数据,同时保持表的元数据/结构不变。

我知道我可以创建另一个具有相同结构的表,使用dbWriteTable 将数据写入该表,然后使用插入语句将数据从另一个表复制到目标表中,但这相当有点开销,感觉应该是不必要的。顺序执行所有数据的删除和追加同样有问题。

对于这个问题有更优雅的解决方案吗?键和索引的破坏是预期的行为吗?文档非常稀少,似乎没有提供解决此问题的方法。

【问题讨论】:

    标签: mysql r odbc primary-key table-index


    【解决方案1】:

    首先我想指出您当前的表定义有冗余:

    CREATE TABLE schema_name.test (
        col1 VARCHAR(10),
        col2 VARCHAR(10),
        PRIMARY KEY (col1),
        INDEX col1_index (col1)
    );
    

    MySQL 会自动在主键上创建索引,所以你的索引定义是不必要的。

    关于您实际的 R 问题,如果您不希望 R 覆盖表,请尝试使用 overwrite=FALSE 调用 dbWriteTable。从here 周围探查,似乎dbWriteTableoverwrite=TRUE 可能会删除您的MySQL 表,然后重新创建它。

    根据您下面的 cmets,如果您想删除表中的所有数据然后插入新数据,您可以先截断表,然后致电 dbWriteTable

    dbGetQuery(con, "TRUNCATE TABLE schema_name.test")
    dbWriteTable(conn=con, overwrite=FALSE, append=TRUE, value=test, name="test", field.types=types)
    

    【讨论】:

    • 感谢@Tim Biegeleisen;我知道 MySQL 在主键上创建索引;我只是想证明 both 被丢弃;关于使用overwrite = FALSE 这给出了“错误:数据库中存在表测试,并且覆盖和附加都是错误的”;当然,如果我还设置了append = TRUE,那么我将无法获得所需的行为(即我想覆盖表中的所有数据,而不是追加)。 (我还添加了一些有关所需行为的细节)。有什么想法(再次感谢:))?
    • dbExecute(connection, " delete from table_name") 将删除数据而不删除表。
    • @Rookatu 尝试截断表格,然后用overwrite=FALSEappend=TRUE 调用dbWriteTable
    • @Tim Biegeleisen 我在原始帖子中将这种方法确定为一种可能的解决方案,但试图确定是否有比这更优雅的方法;这种方法似乎对用户的要求超出了必要的程度,我最终将编写一个结合这些步骤的包装函数,让我想知道为什么包的作者没有这样做,因为这是标准的数据库操作.我也想知道性能:这真的是替换表中所有数据的最佳方式吗?谢谢
    • 问题是您的用例非常不典型。每次写入数据库表时都需要完全擦除它是不寻常的。也许这就是为什么 RMySQL 包的创建者从未想过要创建一个 API 来实现这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-10
    • 2016-02-24
    • 2011-01-07
    • 2012-04-29
    • 1970-01-01
    • 2011-11-19
    相关资源
    最近更新 更多