如何处理mysql#1062 - 创建大表时重复输入错误

时间:2012-02-20 13:15:34

标签: mysql sql

我正在制作一张有大约500万条记录的桌子。我正在从csv文件中加载记录。

有一个唯一的专栏url

插入时,如果表格中已有url,我想对新的url值进行更改,然后进行插入。

示例:

  • 尝试插入url "book"的记录。如果"book"已存在,则新记录的url应为"book-1"(然后为"book-2",依此类推)

  • 结果:除了初始值url

  • 之外,表格中还有"book-1","book-2"...book

我已经发现有 2种方式这样做。

    插入每条记录之前
  1. :检查url值是否已存在;如果确实如此,则在新的url值中进行必要的更改并插入。我担心这会导致表现不佳。

  2. 插入记录而不检查url值是否已存在。如果url值已存在,则处理“mysql#1062 - 重复输入错误”并在url值中进行必要的更改;重试插入。

  3. 这可能吗?如果是这样,怎么样?

2 个答案:

答案 0 :(得分:1)

你有一个问题,一个简单的触发器在插入时会被证明是低效的,因为你说它们会从'book'转到'book-1''book-2'等等。这是最简单的方法这将是一个新列,其中包含一个默认为0的数值。这可以在存储过程中完成,即

CREATE PROCEDURE `insertURL`(inURL VARCHAR(255))

BEGIN
    DECLARE thisSuffix INT UNSIGNED DEFAULT 0;
    // We have to get this ID first, as MySQL won't let you select from the table you are inserting to
    SELECT COALESCE(MAX(url_suffix)+1,0) INTO thisSuffix FROM urls WHERE url_column = inURL;
    // Now the ID is retrieved, insert
    INSERT INTO urls (
        url_column,
        url_suffix
    ) VALUES (
        inURL,
        thisSuffix
    );
    // And then select the generated URL
    SELECT IF(thisSuffix>0,CONCAT(inURL,'-',thisSuffix),inURL) AS outURL;
END

然后使用

调用
CALL insertURL('book');

如果后缀= 0,则返回'book',如果后缀大于0,则返回'book-1'。

为了测试我的表设计是

CREATE TABLE `urls` (
`url_column`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`url_suffix`  tinyint(3) UNSIGNED NOT NULL ,
PRIMARY KEY (`url_column`, `url_suffix`)
);

答案 1 :(得分:1)

如果这是一次性问题,我想推荐一个特别的MySQL解决方案:

  1. 如果您的表格不是MyISAM,请转换为MyISAM。
  2. 暂时创建一个名为的auto_increment整数列 url_suffix
  3. 暂时删除url列上的唯一约束。
  4. 创建多列索引(urlurl_suffix)并确保没有其他索引使用url_suffix
  5. 插入所有行,允许重复的网址。您会注意到auto_increment url_suffix列现在已在网址上键入。因此,第一个特定urlurl_suffix 1和下一个2,依此类推。
  6. 执行如下更新,然后删除临时url_suffix列并重新放置您的唯一约束。
  7. 查询以更新所有行:

    UPDATE urls
    SET url = if (url_suffix = 1, url, CONCAT(url, '-', url_suffix - 1))
    

    事实上,您可以跳过第6步,保留auto_increment字段,这样您以后就可以轻松添加重复的网址,只需像这样获取您的网址:

    SELECT (if (url_suffix = 1, url, CONCAT(url, '-', url_suffix - 1))) AS url
    FROM urls
    

    您的数据看起来像这样:

    url     url_suffix
    ---------------------------
    that    1
    that    2
    this    1
    this    2
    this    3
    those   1