我有一个复合主键,它们一起变得相当大(~2000字节)。我没有性能方面的考虑,我只想要一个主键来强制实现唯一性。
MySql doesn't like long primary keys。有没有解决的办法?也许只是为了强制执行唯一性而不构建索引?
我不想仅使用ASCII而不是UTF8来启用主键(UTF8字符占用3个字节)。
我的表定义如下:
CREATE TABLE `configuration` (
`Section` varchar(200) NOT NULL,
`StoredKey` VARCHAR(200) NOT NULL,
`ServiceName` VARCHAR(300) NOT NULL,
`ServiceMajorVersion` int unsigned NOT NULL,
`ServiceMinorVersion` int unsigned NOT NULL,
`ServiceInstanceID` VARCHAR(100) NOT NULL,
`StoredValue` VARCHAR(1024)
, PRIMARY KEY (`Section`, `StoredKey`, `ServiceName`, `ServiceMajorVersion`, `ServiceMinorVersion`, `ServiceID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
答案 0 :(得分:4)
你应该读一些关于数据库结构设计的书,然后你就不会有这样的主键表。或者雇用一些我为数据库结构创建(原型)的人。 这只是友好的建议。
答案 1 :(得分:4)
@poleneL 对此案例有正确的答案,但是, @Cade Roux 和 @noonex 也是正确的:数据库不是指像Excel一样使用。
您应该有辅助表格:
CREATE TABLE ServiceInstance (
ID int(11) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
Hash binary(16) NOT NULL,
ServiceInstanceID varchar(100) NOT NULL,
UNIQUE(Hash)
);
对于每个表,除了每个配置行唯一的数据。
插入时,请执行:
INSERT INTO ServiceInstance (Hash, ServiceInstanceID) VALUES (unhex(md5('whatever')), 'whatever');
然后,您的主表变为:
CREATE TABLE `configuration` (
`Section_ID` int unsigned NOT NULL,
`StoredKey_ID` int unsigned NOT NULL,
`ServiceName_ID` int unsigned NOT NULL,
`ServiceMajorVersion` int unsigned NOT NULL,
`ServiceMinorVersion` int unsigned NOT NULL,
`ServiceInstanceID` int unsigned NOT NULL,
`StoredValue` VARCHAR(1024),
UNIQUE (`Section_ID`, `StoredKey_ID`, `ServiceName_ID`, `ServiceMajorVersion`, `ServiceMinorVersion`, `ServiceInstanceID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
使用UNIQUE键,因为当您通过主键访问行时,通常会使用PRIMARY KEY。如果它只是一个约束,请使用UNIQUE。
答案 2 :(得分:3)
对主键使用自动增量整数并添加另一个唯一键。
或者,您可以尝试使用binary(16)
作为主键,并将unhex(md5(concat(
列 )))
作为值。
答案 3 :(得分:2)
如果不理解您的数据库,很难说,但可能需要一些规范化。您总是可以创建一个不是主键的UNIQUE INDEX
,如果已经有一个唯一的列,那么将其作为主键,如果没有,则可以创建一个代理主键( INTEGER AUTO_INCREMENT
)。
答案 4 :(得分:0)
同意@pornel和@CadeRoux已发布的内容;您最好将代理主键(ConfigurationId)创建为自动增量整数列,然后创建单独的唯一索引。