我有一个.csv
包含一堆数据的文件,我用它来将所有数据加载到数据库表中。该文件缺少 ID 列(因为这是一个通过我们的软件管理的内部列,他们不关心它)。
为避免数据出现问题,我的“解决方案”是将列移动id
到不干扰文件中数据的位置,该位置就在ActiveFlag
列之后或末尾。
目前这id
是我的第一篇专栏,我没有任何问题,但我正试图走到最后,因为我遇到了数据问题,但我收到以下错误:
Operation failed:
Executing:
ALTER TABLE `sedb`.`volume_pricing_agreement`
CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT AFTER `ActiveFlag`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`AgreementNumber`,`CustomerSiteID`, `CFProgramLevelID`, `Source`, `AgreementTypeID`, `id`);
ERROR 1075: Incorrect table definition; there can be only one auto column and it must be defined as a key
我不知道该列是否必须是表定义中的第一个列,以及是否有任何办法让它出现在我想要的任何地方,或者解决方案可能是通过跳过该id
列来导入数据(假设它是第一个).
我正在检查这里的语法,但我不知道如何在加载期间跳过列:
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
[REPLACE | IGNORE]
INTO TABLE tbl_name
[PARTITION (partition_name,...)]
[CHARACTER SET charset_name]
[{FIELDS | COLUMNS}
[TERMINATED BY 'string']
[[OPTIONALLY] ENCLOSED BY 'char']
[ESCAPED BY 'char']
]
[LINES
[STARTING BY 'string']
[TERMINATED BY 'string']
]
[IGNORE number {LINES | ROWS}]
[(col_name_or_user_var,...)]
[SET col_name = expr,...]
这是命令的输出SHOW CREATE TABLE sedb.volume_pricing_agreement;
:
volume_pricing_agreement, CREATE TABLE `volume_pricing_agreement` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`AgreementNumber` int(11) DEFAULT NULL,
`AgreementName` varchar(60) CHARACTER SET utf8 DEFAULT NULL,
`CustomerSiteID` int(11) NOT NULL,
`CFProgramLevelID` int(11) DEFAULT NULL,
`Discount` decimal(5,4) NOT NULL DEFAULT '0.0000',
`Source` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
`ActiveFlag` int(1) NOT NULL,
`AgreementTypeID` int(1) NOT NULL DEFAULT '0',
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `AgreementNumber` (`AgreementNumber`),
KEY `CustomerSiteID` (`CustomerSiteID`),
KEY `ActiveFlag` (`ActiveFlag`)
) ENGINE=InnoDB AUTO_INCREMENT=2763 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
有什么帮助吗?我该如何处理?
不。表定义中列的顺序无关紧要,除了一个旧的例外。在旧版本中,“第一”
TIMESTAMP
列有一个特殊的默认DEFAULT
值。不需要有
AUTO_INCREMENT
. 然而,(本质上)要求您有一个PRIMARY KEY
. 闻起来像AgreementNumber
会这样?请记住,PK 必须是UNIQUE
(MySQL 要求)。作为旁注,A_I 不一定是 PK。唯一的要求是它是某个索引中的第一列。请记住,PK 是一个唯一的密钥,是一个密钥。
但是,那不是您的“真正”问题。也就是说,您需要在
LOAD DATA
没有id
被提供的情况下进行。计划 A:加载到另一个表中,然后将其复制过来。复制过来的时候,指定除id以外的所有列;A_我会处理剩下的事情。
B 计划:使用,但指定除 之外
LOAD DATA
的所有列。再次将注意正确默认它。id
A_I
其他提示,当你在线时:
int(1)
是一个 4 字节的数字;这(1)
意味着什么。也许你想要一个 1 字节的TINYINT
?INT UNSIGNED
在适当的地方使用INT
;查找,如果合适MEDIUMINT
再做一次。MEDIUMINT UNSIGNED
NOT NULL
。更多的
如果您选择拥有一个 6 列
UNIQUE
密钥,其中包含一些VARCHARs
,那么拥有 A_I 可能比将其作为 PK 更好。A
UNIQUE KEY
是两件事:索引和唯一性约束。您可以将它用于其中一个或两个。PK 是
UNIQUE KEY
标识行的。它还与数据“聚集”在一起,使查找比使用“辅助键”(任何非 PK)更有效。当索引列的“基数”非常低时,例如标志,优化器将动态查看您提供的值,并查看表中是否只有不到 20% 的部分具有该值。在这种情况下,它将使用索引;否则它不会。“20%”随月相变化。避开索引的原因是使用索引涉及通过 PK 在索引的 BTree 和数据的 BTree 之间来回跳动。这可能比简单地扫描数据、丢掉 80% 的行要慢。辅助键是包含索引列和 PK 副本的 BTree。