【问题标题】:MySQL if where not found then insertMySQL 如果找不到,则插入
【发布时间】:2014-02-06 09:12:47
【问题描述】:

因为这可能显示为经典的“ON DUPLICATE KEY UPDATE”问题 - 它不是。

我有一个包含一些元值的表格,如下所示:

meta_id   |   user_id   |   meta_type   |   meta_value

实际上可以有更多具有相同user_id&&meta_type 的条目,不能重复的是具有相同user_id&&meta_type&&meta_value 的条目。好吧,我可以为这些添加一个唯一索引,但我担心一件事 - meta_value 是一个 longtext,因此它可以包含更大的数据。
所以当我想创建唯一键时(这样我就可以使用 ON DUPLICATE KEY UPDATE),我得到一个错误:

#1170 - BLOB/TEXT column 'meta_hodnota' used in key specification without a key length

当我尝试添加一些限制时,它会弹出:

#1071 - Specified key was too long; max key length is 767 bytes

这对于可能的条目来说太低了。所以问题是这个键实际上是如何工作的:

  1. 它只是说 MySQL 将检查多长时间的列的重复性,并且不会修改具有最大值的可能性。列值大小 (max(longtext))
    注意:我只关心较小条目的这种三重重复性,我不关心大条目的重复性(不在这个地方)
  2. 它正在减少获得最大值的可能性。列值大小(max(longtext)) 并只留下 767 字节作为列的最大值,即使该列是长文本。 - 不可接受 => 这里是否真的需要额外的查询?还是有其他方法? (例如 sql 端搜索和变量保存 => 根据结果选择操作)

对此有任何帮助/提示吗?

【问题讨论】:

    标签: mysql sql phpmyadmin


    【解决方案1】:

    3072 字节是否足够?在这种情况下,您可以在 mysql 配置中使用 innodb_large_prefix 参数。

    如果 3072 字节还不够,我会添加一个固定长度的列(类似于 varchar(256))并使用该列来创建索引。插入/更新记录时,您可以使用 SUBSTR() 将长文本修剪为 256 个字符,并使用该值填充额外的列。

    这当然只有在您关心 meta_* 中较小的条目时才有效,就像您说的那样。根据行数,您的磁盘使用量会略有增加,但在大多数情况下这应该不是问题。

    【讨论】:

    • 或者将元值拆分到两个表更好?
    • 这将增加您的选择的复杂性,并且如果结果集很大,则会减慢您的查询速度。添加两个 varchar(256) 肯定比创建具有 1:1 关系的新表要快。
    • 试一试,你应该不会注意到任何性能差异。
    • 好吧,我只是拆分表,而不是为每个新条目创建一个新表 :) 你知道,一个是 meta_id | user_id | meta_type | meta_value(varchar(255)),另一个是 meta_id | user_id | meta_type | meta_value(longtext),两者都与用户表相关,并且将为每个表单独插入/更新新值 - 那么现在呢?
    • 我不认为这比简单地添加一列更好。同样在这种情况下,您如何使两个表保持同步?您只能在其中一个上使用 ON DUPLICATE KEY UPDATE...但您想在两者中都插入。
    猜你喜欢
    • 1970-01-01
    • 2010-10-20
    • 2014-04-14
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 1970-01-01
    相关资源
    最近更新 更多