MySql主键> 900/1000字节?

时间:2009-06-07 13:20:15

标签: mysql primary-key composite

我有一个复合主键,它们一起变得相当大(~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;

5 个答案:

答案 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)创建为自动增量整数列,然后创建单独的唯一索引。