我的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语言编程能力不强,因此,我希望得到一些好的建议来解决这个问题。
非常感谢你,并祝你在德国一切顺利。
索引的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
只能作为近似值使用。