“密钥主项的重复条目”在一台机器上,而不是在另一台机器上,具有相同的数据?

baubqpgj  于 2021-06-24  发布在  Mysql
关注(0)|答案(4)|浏览(394)

我的问题是:插入一组数据在我的本地机器/mysql数据库上工作,但在生产上它会导致 Duplicate entry for key 'PRIMARY' 错误。据我所知,这两种设置是等效的。
我的第一个想法是这是一个排序规则问题,但我检查了两个数据库中的表是否都在使用 utf8_bin .
table一开始是空的,我正在做 .Distinct() 所以不应该有任何重复的条目。
有关表格:

CREATE TABLE `mytable` (
  `name` varchar(100) CHARACTER SET utf8 NOT NULL,
  `appid` int(11) NOT NULL,
  -- A few other irrelevant fields
  PRIMARY KEY (`name`,`appid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
``` `Database.cs` :

[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
public class Database : DbContext
{
public DbSet MyTable { get; set; }
public static Database Get()
{
/* Not important */
}
//etc.
}
``` MyTable.cs :

[Table("mytable")]
public class MyTable : IEquatable<MyTable>, IComparable, IComparable<MyTable>
{
    [Column("name", Order = 0), Key, Required, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public string Name
    {
        get { return _name; }
        set { _name = value.Trim().ToLower(); }
    }

    private string _name;

    [Column("appid", Order = 1), Key, Required, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ApplicationId { get; set; }

    //Equals(), GetHashCode(), CompareTo(), ==() etc. all auto-generated by Resharper to use both Name and ApplicationId.
    //Have unit-tests to verify they work correctly.
}

然后使用它:

using(Database db = Database.Get())
using(DbContextTransaction transaction = db.Database.BeginTransaction(IsolationLevel.ReadUncommitted))
{
    IEnumerable<MyTable> newEntries = GetNewEntries();
    //Verify no existing entries already in the table; not necessary to show since table is empty anyways
    db.MyTable.AddRange(newEntries.Distinct());
}

我不知道在做了一个测试之后,数据库中怎么会有重复的条目 .Distinct() 在代码中,使用 utf8_bin 尤其是因为它在一台机器上工作,而不是在另一台机器上。有人有什么想法吗?

bt1cpqcv

bt1cpqcv1#

我将调查以下几点:
在两台机器上检查mysql的确切版本。您可以在mysql客户机中使用 SHOW VARIABLES LIKE "%version%"; 使用 SELECT HEX(name) 查看数据是如何编码的,对于重复行。
调查“utf8”数据是否存储在utf8mb3或utf8mb4中
https://dev.mysql.com/doc/refman/5.7/en/charset-unicode-utf8mb3.html
https://dev.mysql.com/doc/refman/5.7/en/charset-unicode-utf8mb4.html
假设在dev机器上,数据是从新安装插入的,而在生产机器上,数据可能是使用旧版本插入的,然后服务器升级的,我将特别检查是否需要(并且已经完成)操作来正确完成升级过程。
特别是,请参阅mysql参考手册中的以下部分(有关正确版本):
https://dev.mysql.com/doc/refman/5.7/en/checking-table-incompatibilities.html
如有必要,重新生成索引。
https://dev.mysql.com/doc/refman/5.7/en/rebuilding-tables.html
编辑(2016-10-12)
所有这些都集中在table和存储上。
要检查的另一部分是客户机和服务器之间的连接,包括 character_set_connection .
请检查所有字符集相关的系统变量,以进行比较。

mysql> show variables like "%character%";
+--------------------------+-------------------------------------------+
| Variable_name            | Value                                     |
+--------------------------+-------------------------------------------+
| character_set_client     | utf8                                      |
| character_set_connection | utf8                                      |
| character_set_database   | latin1                                    |
| character_set_filesystem | binary                                    |
| character_set_results    | utf8                                      |
| character_set_server     | latin1                                    |
| character_set_system     | utf8                                      |
| character_sets_dir       | /home/malff/GIT_TRUNK/sql/share/charsets/ |
+--------------------------+-------------------------------------------+
8 rows in set (0.02 sec)
w1e3prcc

w1e3prcc2#

我最终通过unicode转义非ascii字符来解决这个问题,类似于这个解决方案。
然而,我仍然不知道为什么会发生这种事。。。

nsc4cvqm

nsc4cvqm3#

两台机器是否使用相同的数据库驱动程序?当安装不同的驱动程序时,ef和oracle也有类似的问题。
编辑:
本文件
https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
在MySQL5.5.3Unicode之前,每个字符最多存储3个字节,而在MySQL5.5.3Unicode之后,每个字符最多存储4个字节。这可以解释一个键是否被确定为唯一的区别。当使用“补充字符”时,这种差异就会发挥作用,因为旧版本根本无法存储这些字符。
您的两个数据库是否处于不同的界限(mysql 5.5.3)?

2eafrhcq

2eafrhcq4#

我认为这可能是因为某些字符在不同的环境下有不同的含义,所以通常建议您在将字符串用作数据值之前转义这些特殊字符。
看看这个:http://dev.mysql.com/doc/refman/5.7/en/string-literals.html#character-转义序列

相关问题