我的SQL数据库不一致(基数与自动递增)。

问题描述 投票:1回答:1

我的SQL数据库在使用my SQL连接器的C程序填充时出现了问题。填充数据库的C代码的对应部分显示如下。

sprintf(query_table, "CREATE TABLE IF NOT EXISTS `%08X` (COUNTER INT NOT NULL AUTO_INCREMENT PRIMARY KEY, TIME TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP(6), DATA VARCHAR(16))", frame.can_id-0x80000000);

    if (mysql_query(conn, query_table) != 0)               
        {                                                                                                  
        fprintf(stderr, "Query Failure; create tables from can log!\n");                                                              
        return EXIT_FAILURE;                                                                             
        }              

sprintf(query, "INSERT INTO `%08X` (TIME, DATA) VALUES (FROM_UNIXTIME(%ld.%06ld), '%02X%02X%02X%02X%02X%02X%02X%02X')",frame.can_id-0x80000000,tv.tv_sec,tv.tv_usec,frame.data[0],frame.data[1],frame.data[2],frame.data[3],frame.data[4],frame.data[5],frame.data[6],frame.data[7]);
//printf("%s",query);

    if (mysql_query(conn, query) != 0)                                                                             
        {                                                                                                  
        fprintf(stderr, "Query Failure; insert into database!\n");                                                              
        return EXIT_FAILURE;                                                                             
        }

frame.data是一个子结构,它包括一个bytewise 8字节的十六进制值,由250kbit波特率的峰值CAN接口创建。如代码所示,任何新的CAN报文ID,数据库都会验证对应的DB表是否存在。在不存在的情况下,将创建该表。不幸的是,由于CAN软件的未知变化,不可能预先分配表。

经过两个月的测量期,DB被履行了不同的报文和数据集。起初,一切看起来都很好,但仔细观察,可以看出一些不一致的地方。附图 1 显示了3个不同的Cardinality-Auto-Increment-Issues案例来解释当前的情况。我的SQL和C语言编程能力不强,因此,我希望得到一些好的建议来解决这个问题。

非常感谢你,并祝你在德国一切顺利。

mysql c database auto-increment cardinality
1个回答
0
投票

索引的cardinality是估计的,而不是绝对的,所以不能保证索引统计中显示的cardinality会与 SELECT COUNT(*) FROM table_name; 应该是接近的,但不能保证一定会相等。

也不能保证下一个自动递增的值会等于 SELECT MAX(auto_increment_field)+1. 唯一能保证的是,它将大于或等于 SELECT MAX(auto_increment_field)+1. 我们可以分配但不使用自动递增值,例如,我们可以这样做。

START TRANSACTION;
    INSERT INTO table_name VALUES(...);
ROLLBACK;

这将会增加下一个自动递增的值,但是不会产生一条带有分配的自动递增值的记录。还有其他一些原因可以跳过这些值(例如 auto_increment_increment, auto_increment_offset, innodb_autoinc_lock_mode 的设置都会影响你的autoinc空间的稀疏程度)。)

如果你需要100%精确的COUNT()或MAX(),你将不得不使用这些,而且在一个大表上会很慢。索引的基数和 AUTO_INCREMENT= 值从 SHOW CREATE TABLE 只能作为近似值使用。

© www.soinside.com 2019 - 2024. All rights reserved.